diff --git a/config.tests/arch/arch.cpp b/config.tests/arch/arch.cpp index 854228cc9c78d973aeae37547a38bdbca64c8fd6..7e481d4cf57fc4221901b6f55a653b9aa2bcfb8a 100644 --- a/config.tests/arch/arch.cpp +++ b/config.tests/arch/arch.cpp @@ -57,6 +57,10 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:" // Advanced Bit Manipulation, AMD Barcelona (family 10h) " abm" #endif +#ifdef __ADX__ +// Multi-Precision Add-Carry Instruction Extensions, Intel Core 5th generation ("Broadwell") +" adx" +#endif #ifdef __AES__ // AES New Instructions, Intel Core-i7 second generation ("Sandy Bridge") " aes" @@ -70,19 +74,19 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:" " avx2" #endif #ifdef __AVX512F__ -// AVX512 Foundation, Intel Xeon Phi codename "Knights Landing" +// AVX512 Foundation, Intel Xeon Phi codename "Knights Landing" and Intel Xeon codename "Skylake" " avx512f" #endif #ifdef __AVX512CD__ -// AVX512 Conflict Detection, Intel Xeon Phi codename "Knights Landing" +// AVX512 Conflict Detection, Intel Xeon Phi codename "Knights Landing" and Intel Xeon codename "Skylake" " avx512cd" #endif #ifdef __AVX512DQ__ -// AVX512 Double & Quadword, future Intel Xeon processor +// AVX512 Double & Quadword, Intel Xeon processor codename "Skylake" " avx512dq" #endif #ifdef __AVX512BW__ -// AVX512 Byte & Word, future Intel Xeon processor +// AVX512 Byte & Word, Intel Xeon processor codename "Skylake" " avx512bw" #endif #ifdef __AVX512ER__ @@ -94,9 +98,17 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:" " avx512pf" #endif #ifdef __AVX512VL__ -// AVX512 Vector Length, future Intel Xeon processor +// AVX512 Vector Length, Intel Xeon processor codename "Skylake" " avx512vl" #endif +#ifdef __AVX512IFMA__ +// AVX512 Integer Fused Multiply-Add, Intel processor codename "Cannonlake" +" avx512ifma" +#endif +#ifdef __AVX512VBMI__ +// AVX512 Vector Byte Manipulation Instructions, Intel processor codename "Cannonlake" +" avx512vbmi" +#endif #ifdef __BMI__ // Bit Manipulation Instructions 1, Intel Core 4th Generation ("Haswell"), AMD "Bulldozer 2" " bmi" @@ -143,6 +155,10 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:" // Move Big Endian, Intel Atom & "Haswell" " movbe" #endif +#ifdef __MPX__ +// Memory Protection Extensions, Intel Core processor codename "Skylake" +" mpx" +#endif #ifdef __NO_SAHF__ // missing SAHF instruction in 64-bit, up to Intel Pentium 4 64-bit ("Nocona"), AMD Athlon FX // Note: the macro is not defined, so this will never show up @@ -156,10 +172,26 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:" // Population Count (count of set bits), Intel Core-i7 second generation ("Sandy Bridge") " popcnt" #endif +#ifdef __PREFETCHWT1__ +// Prefetch data for writing with T1 hint, Intel processor TBA +" prefetchwt1" +#endif +#ifdef __PRFCHW__ +// Prefetch data for writing, Intel Core 5th Generation ("Broadwell") +" prfchw" +#endif #ifdef __RDRND__ // Random number generator, Intel Core 3rd Generation ("Ivy Bridge") " rdrnd" #endif +#ifdef __RDSEED__ +// Random number generator, Intel Core 5th Generation ("Broadwell") +" rdseed" +#endif +#ifdef __RTM__ +// Restricted Transactional Memory, Intel Core 4th Generation ("Haswell") +" rtm" +#endif #ifdef __SHA__ // SHA-1 and SHA-256 instructions, Intel processor TBA " sha" diff --git a/config.tests/common/c++11/c++11.cpp b/config.tests/common/c++11/c++11.cpp index 7e80723470e6ac883f04c039a83d3bf227b8d07d..30934951d7621f0bed37fee35e182b064df857b8 100644 --- a/config.tests/common/c++11/c++11.cpp +++ b/config.tests/common/c++11/c++11.cpp @@ -40,7 +40,7 @@ #include <utility> #if defined(__clang__) # if __has_feature(cxx_generalized_initializers) -// On Mac OS X, the libstdc++ headers don't include <initializer_list> +// On OS X, the libstdc++ headers don't include <initializer_list> // This #include here forces a failure unless we're using libc++ # include <initializer_list> # endif diff --git a/config.tests/unix/cloexec/cloexec.cpp b/config.tests/unix/cloexec/cloexec.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3f127d8d3fb6071663f467e62aabe36539a1d11d --- /dev/null +++ b/config.tests/unix/cloexec/cloexec.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Intel Corporation. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the configuration module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#define _GNU_SOURCE 1 + +#include <sys/types.h> +#include <sys/socket.h> +#include <fcntl.h> +#include <unistd.h> + +int main() +{ + int pipes[2]; + (void) pipe2(pipes, O_CLOEXEC | O_NONBLOCK); + (void) fcntl(0, F_DUPFD_CLOEXEC, 0); + (void) dup3(0, 3, O_CLOEXEC); + (void) accept4(0, 0, 0, SOCK_CLOEXEC | SOCK_NONBLOCK); + return 0; +} diff --git a/config.tests/unix/cloexec/cloexec.pro b/config.tests/unix/cloexec/cloexec.pro new file mode 100644 index 0000000000000000000000000000000000000000..bc735f9b1f5aff39a59f4103f2c83d9018220bd5 --- /dev/null +++ b/config.tests/unix/cloexec/cloexec.pro @@ -0,0 +1,3 @@ +SOURCES = cloexec.cpp +CONFIG -= qt +QT = diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h b/config.tests/win/directwrite/directwrite.cpp similarity index 52% rename from src/platformsupport/eglconvenience/qeglplatformwindow_p.h rename to config.tests/win/directwrite/directwrite.cpp index 852d690c92b28c516ffe57453fdeb64825b975cd..01bea19faff6e903ec4b846fb9fc756e059e1b43 100644 --- a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h +++ b/config.tests/win/directwrite/directwrite.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the config.tests of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL21$ ** Commercial License Usage @@ -31,55 +31,14 @@ ** ****************************************************************************/ -#ifndef QEGLPLATFORMWINDOW_H -#define QEGLPLATFORMWINDOW_H +#include <dwrite.h> +#include <d2d1.h> -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <qpa/qplatformwindow.h> -#include <QtPlatformSupport/private/qopenglcompositor_p.h> -#include <EGL/egl.h> - -QT_BEGIN_NAMESPACE - -class QOpenGLCompositorBackingStore; -class QPlatformTextureList; - -class QEGLPlatformWindow : public QPlatformWindow, public QOpenGLCompositorWindow +int main(int, char**) { -public: - QEGLPlatformWindow(QWindow *w); - - virtual void create(); - - QOpenGLCompositorBackingStore *backingStore() { return m_backingStore; } - void setBackingStore(QOpenGLCompositorBackingStore *backingStore) { m_backingStore = backingStore; } - bool isRaster() const; - - QWindow *sourceWindow() const Q_DECL_OVERRIDE; - const QPlatformTextureList *textures() const Q_DECL_OVERRIDE; - void endCompositing() Q_DECL_OVERRIDE; - - WId winId() const Q_DECL_OVERRIDE; - void setOpacity(qreal opacity) Q_DECL_OVERRIDE; - - virtual EGLNativeWindowType eglWindow() const = 0; - -private: - QOpenGLCompositorBackingStore *m_backingStore; - bool m_raster; - WId m_winId; -}; - -QT_END_NAMESPACE - -#endif // QEGLPLATFORMWINDOW_H + IDWriteFactory *factory = 0; + DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + reinterpret_cast<IUnknown **>(&factory)); + return 0; +} diff --git a/config.tests/win/directwrite/directwrite.pro b/config.tests/win/directwrite/directwrite.pro new file mode 100644 index 0000000000000000000000000000000000000000..9a4612ca119abf2d83bddd7210a49ee445797a42 --- /dev/null +++ b/config.tests/win/directwrite/directwrite.pro @@ -0,0 +1,4 @@ +SOURCES = directwrite.cpp +LIBS += -ldwrite +CONFIG -= qt +CONFIG += console diff --git a/configure b/configure index 47f6c60282929971bc92d5967539963750451bbd..28a0b370c0da1d912d89e42dfb6d85463f9e832e 100755 --- a/configure +++ b/configure @@ -683,6 +683,9 @@ CFG_XCB=auto CFG_XCB_XLIB=auto CFG_XCB_GLX=no CFG_EGLFS=auto +CFG_EGLFS_BRCM=no +CFG_EGLFS_MALI=no +CFG_EGLFS_VIV=no CFG_DIRECTFB=auto CFG_LINUXFB=auto CFG_KMS=auto @@ -726,6 +729,7 @@ CFG_IPV6IFNAME=auto CFG_GETIFADDRS=auto CFG_INOTIFY=auto CFG_EVENTFD=auto +CFG_CLOEXEC=no CFG_RPATH=yes CFG_FRAMEWORK=auto CFG_USE_GOLD_LINKER=auto @@ -1153,7 +1157,7 @@ while [ "$#" -gt 0 ]; do fi ;; force-pkg-config) - CFG_PKGCONFIG="force" + CFG_PKGCONFIG="yes" ;; docdir) QT_INSTALL_DOCS="$VAL" @@ -2708,6 +2712,8 @@ MacOS/iOS options: link tools against those frameworks. -no-framework ...... Do not build Qt as a series of frameworks. + -securetransport ... Use SecureTransport instead of OpenSSL (requires -no-openssl) + -sdk <sdk> ......... Build Qt using Apple provided SDK <sdk>. The argument should be one of the available SDKs as listed by 'xcodebuild -showsdks'. Note that the argument applies only to Qt libraries and applications built @@ -2851,7 +2857,7 @@ if [ -z "$PLATFORM" ]; then Linux:*) PLATFORM=linux-g++ PLATFORM_NOTES=" - - Also available for Linux: linux-kcc linux-icc linux-cxx + - Also available for Linux: linux-clang linux-kcc linux-icc linux-cxx " ;; SunOS:5*) @@ -2974,11 +2980,21 @@ if [ -f "$relpath"/LICENSE.PREVIEW.COMMERCIAL ] && [ $COMMERCIAL_USER = "yes" ]; EditionString="Technology Preview" elif [ $COMMERCIAL_USER = "yes" ]; then if [ $UNAME_SYSTEM = "Linux" ]; then - if file -L /bin/sh | grep -q "64-bit" ; then - Licheck=licheck64 - else + case "$PLATFORM" in + *-32) Licheck=licheck32 - fi + ;; + *-64) + Licheck=licheck64 + ;; + *) + if file -L /bin/sh | grep -q "64-bit" ; then + Licheck=licheck64 + else + Licheck=licheck32 + fi + ;; + esac elif [ $UNAME_SYSTEM = "Darwin" ]; then Licheck=licheck_mac else @@ -4135,11 +4151,6 @@ fi if [ "$CFG_PKGCONFIG" = "no" ]; then PKG_CONFIG= [ "$OPT_VERBOSE" = "yes" ] && echo "pkg-config support disabled." -elif [ "$CFG_PKGCONFIG" = "force" ]; then - echo >&2 "" - echo >&2 "You have asked to use pkg-config. Please make sure you have" - echo >&2 "a correctly setup pkg-config environment!" - echo >&2 "" elif [ -n "$PKG_CONFIG" ]; then # found a pkg-config if [ "$QT_CROSS_COMPILE" = "yes" ]; then @@ -4152,16 +4163,13 @@ elif [ -n "$PKG_CONFIG" ]; then fi export PKG_CONFIG_LIBDIR echo >&2 "Note: PKG_CONFIG_LIBDIR automatically set to $PKG_CONFIG_LIBDIR" - elif [ "$CFG_PKGCONFIG" = "yes" ]; then - echo >&2 "Error: PKG_CONFIG_LIBDIR has not been set. This could mean" - echo >&2 "the host's .pc files will be used (even if you set PKG_CONFIG_PATH)." + elif [ "$CFG_PKGCONFIG" = "auto" ]; then + PKG_CONFIG= + echo >&2 "Warning: Disabling pkg-config since PKG_CONFIG_LIBDIR is not set and" + echo >&2 "the host's .pc files would be used (even if you set PKG_CONFIG_PATH)." echo >&2 "Set this variable to the directory that contains target .pc files" echo >&2 "for pkg-config to function correctly when cross-compiling or" - echo >&2 "use -force-pkg-config to override this test." - exit 101 - else - PKG_CONFIG= - echo >&2 "Warning: Disabling pkg-config since PKG_CONFIG_LIBDIR is not set." + echo >&2 "use -pkg-config to override this test." fi fi if [ -z "$PKG_CONFIG_SYSROOT_DIR" ]; then @@ -4169,17 +4177,19 @@ elif [ -n "$PKG_CONFIG" ]; then PKG_CONFIG_SYSROOT_DIR=$CFG_SYSROOT export PKG_CONFIG_SYSROOT_DIR echo >&2 "Note: PKG_CONFIG_SYSROOT_DIR automatically set to $PKG_CONFIG_SYSROOT_DIR" - elif [ "$CFG_PKGCONFIG" = "yes" ]; then - echo >&2 "Error: PKG_CONFIG_SYSROOT_DIR has not been set. Set this variable" - echo >&2 "to your sysroot for pkg-config to function correctly when cross-compiling" - echo >&2 "or use -force-pkg-config to override this test." - exit 101 - else + elif [ "$CFG_PKGCONFIG" = "auto" ]; then PKG_CONFIG= echo >&2 "Warning: Disabling pkg-config since PKG_CONFIG_SYSROOT_DIR is not set." + echo >&2 "Set this variable to your sysroot for pkg-config to function correctly when" + echo >&2 "cross-compiling or use -pkg-config to override this test." fi fi fi + if [ -n "$PKG_CONFIG" ]; then + CFG_PKGCONFIG=yes + else + CFG_PKGCONFIG=no + fi elif [ "$CFG_PKGCONFIG" = "yes" ]; then echo >&2 "Could not detect pkg-config from mkspec or PATH." exit 101 @@ -4235,7 +4245,7 @@ compileTestWithPkgConfig() libdir_mod=`echo $libdir_raw | sed -e 's,^-L,,g' -e 's, -L, ,g'` has_used_pkg_config="yes" fi - if compileTest $configtest $configtest_name $libdir_raw $incdir_raw $libs $cflags "$@"; then + if compileTest $configtest "$configtest_name" $libdir_raw $incdir_raw $libs $cflags "$@"; then if [ "$has_used_pkg_config" = "yes" ] && [ -n "$qmake_postfix" ]; then QMakeVar set QMAKE_INCDIR_$qmake_postfix "`shellArgumentListToQMakeList $incdir_mod`" QMakeVar set QMAKE_LIBDIR_$qmake_postfix "`shellArgumentListToQMakeList $libdir_mod`" @@ -4951,7 +4961,7 @@ if [ "$CFG_DBUS" = "linked" ]; then else if [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then echo "The Qt D-Bus module cannot be enabled because libdbus-1 version $MIN_DBUS_1_VERSION was not found." - [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -force-pkg-config?" + [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -pkg-config?" echo " Turn on verbose messaging (-v) to $0 to see the final report." echo " If you believe this message is in error you may use the continue" echo " switch (-continue) to $0 to continue." @@ -4991,7 +5001,7 @@ if [ "$CFG_GLIB" != "no" ]; then else if [ "$CFG_GLIB" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then echo "Glib support cannot be enabled due to functionality tests!" - [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -force-pkg-config?" + [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -pkg-config?" echo " Turn on verbose messaging (-v) to $0 to see the final report." echo " If you believe this message is in error you may use the continue" echo " switch (-continue) to $0 to continue." @@ -5019,7 +5029,7 @@ if [ "$CFG_GLIB" = "yes" -a "$CFG_QGTKSTYLE" != "no" ]; then else if [ "$CFG_QGTKSTYLE" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then echo "GTK theme support cannot be enabled due to functionality tests!" - [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -force-pkg-config?" + [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -pkg-config?" echo " Turn on verbose messaging (-v) to $0 to see the fin al report." echo " If you believe this message is in error you may use the continue" echo " switch (-continue) to $0 to continue." @@ -5064,7 +5074,7 @@ if [ "$CFG_PULSEAUDIO" != "no" ]; then else if [ "$CFG_PULSEAUDIO" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then echo "PulseAudio support cannot be enabled due to functionality tests!" - [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -force-pkg-config?" + [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -pkg-config?" echo " Turn on verbose messaging (-v) to $0 to see the final report." echo " If you believe this message is in error you may use the continue" echo " switch (-continue) to $0 to continue." @@ -5182,7 +5192,7 @@ elif [ "$CFG_OPENGL" = "es2" ]; then compileTestWithPkgConfig glesv2 unix/opengles2 "OpenGL ES 2.0" OPENGL_ES2 if [ $? != "0" ]; then echo "The OpenGL ES 2.0 functionality test failed!" - [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -force-pkg-config?" + [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -pkg-config?" echo " You might need to modify the include and library search paths by editing" echo " QMAKE_INCDIR_OPENGL_ES2, QMAKE_LIBDIR_OPENGL_ES2 and QMAKE_LIBS_OPENGL_ES2 in" echo " ${XQMAKESPEC}." @@ -5256,7 +5266,7 @@ if [ "$CFG_LIBUDEV" != "no" ]; then QT_CONFIG="$QT_CONFIG libudev" elif [ "$CFG_LIBUDEV" = "yes" ]; then echo "The libudev functionality test failed!" - [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -force-pkg-config?" + [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -pkg-config?" exit 1 else CFG_LIBUDEV=no @@ -5468,7 +5478,7 @@ if [ "$CFG_XCB" != "no" ]; then else if [ "$CFG_XCB" != "auto" ]; then echo "The test for linking against libxcb failed!" - [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -force-pkg-config?" + [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -pkg-config?" echo " You might need to install dependency packages for libxcb." echo " See src/plugins/platforms/xcb/README." exit 1 @@ -5485,7 +5495,7 @@ if [ "$CFG_DIRECTFB" != "no" ]; then CFG_DIRECTFB=yes elif [ "$CFG_DIRECTFB" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then echo " DirectFB support cannot be enabled due to functionality tests!" - [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -force-pkg-config?" + [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -pkg-config?" echo " Turn on verbose messaging (-v) to $0 to see the final report." echo " If you believe this message is in error you may use the continue" echo " switch (-continue) to $0 to continue." @@ -5542,7 +5552,7 @@ if [ "$CFG_XCB" != "no" ]; then elif [ "$CFG_XKBCOMMON" = "system" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then echo " xkbcommon support cannot be enabled because either xkbcommon or " echo " xkbcommon-x11 >= $MIN_REQ_XKBCOMMON was not found via pkg-config!" - [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -force-pkg-config?" + [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -pkg-config?" echo " Turn on verbose messaging (-v) to $0 to see the final report." echo " If you believe this message is in error you may use the continue" echo " switch (-continue) to $0 to continue." @@ -5603,7 +5613,7 @@ if [ "$CFG_EGL" != "no" ]; then fi elif [ "$CFG_EGL" = "yes" ]; then echo " The EGL functionality test failed; EGL is required by some QPA plugins to manage contexts & surfaces." - [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -force-pkg-config?" + [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -pkg-config?" echo " You might need to modify the include and library search paths by editing" echo " QMAKE_INCDIR_EGL, QMAKE_LIBDIR_EGL and QMAKE_LIBS_EGL in ${XQMAKESPEC}." exit 1 @@ -5873,6 +5883,11 @@ if [ "$CFG_GETIFADDRS" != "no" ]; then fi fi +# find if the platform provides thread-safe CLOEXEC support +if compileTest unix/cloexec "cloexec"; then + CFG_CLOEXEC=yes +fi + # detect OpenSSL if [ "$CFG_OPENSSL" != "no" ]; then if compileTest unix/openssl "OpenSSL"; then @@ -6151,6 +6166,9 @@ fi if [ "$CFG_EVENTFD" = "yes" ]; then QT_CONFIG="$QT_CONFIG eventfd" fi +if [ "$CFG_CLOEXEC" = "yes" ]; then + QT_CONFIG="$QT_CONFIG threadsafe-cloexec" +fi if [ "$CFG_LIBJPEG" = "no" ]; then CFG_JPEG="no" elif [ "$CFG_LIBJPEG" = "system" ]; then @@ -6464,7 +6482,7 @@ fi # ### Vestige if [ "$CFG_QML_DEBUG" = "no" ]; then - QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_QML_DEBUGGER" + QT_CONFIG="$QT_CONFIG no-qml-debug" fi case "$QMAKE_CONF_COMPILER" in @@ -6631,6 +6649,7 @@ QMakeVar set sql-plugins "$SQL_PLUGINS" [ "$CFG_GETIFADDRS" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_GETIFADDRS" [ "$CFG_INOTIFY" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_INOTIFY" [ "$CFG_EVENTFD" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_EVENTFD" +[ "$CFG_CLOEXEC" = "yes" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_THREADSAFE_CLOEXEC=1" [ "$CFG_NIS" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_NIS" [ "$CFG_OPENSSL" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_OPENSSL" [ "$CFG_OPENSSL" = "linked" ]&& QCONFIG_FLAGS="$QCONFIG_FLAGS QT_LINKED_OPENSSL" diff --git a/configure.bat b/configure.bat index 0f0638b3db42c135f751e8b6a3da533794dd1843..8c0819aeb5c9041f582c16f68120144bed419f01 100644 --- a/configure.bat +++ b/configure.bat @@ -60,16 +60,16 @@ if errorlevel 1 goto exit echo #### Generated by configure.bat - DO NOT EDIT! ####> Makefile echo/>> Makefile for /f "tokens=3 usebackq" %%V in (`findstr QT_VERSION_STR %QTSRC%src\corelib\global\qglobal.h`) do @echo QTVERSION = %%~V>> Makefile -if not "%cl.exe%" == "" ( - echo CXX = cl>>Makefile - echo EXTRA_CXXFLAGS =>>Makefile +if not "%icl.exe%" == "" ( + echo CXX = icl>>Makefile + echo EXTRA_CXXFLAGS = /Zc:forScope>>Makefile rem This must have a trailing space. echo QTSRC = %QTSRC% >> Makefile set tmpl=win32 set make=nmake -) else if not "%icl.exe%" == "" ( - echo CXX = icl>>Makefile - echo EXTRA_CXXFLAGS = /Zc:forScope>>Makefile +) else if not "%cl.exe%" == "" ( + echo CXX = cl>>Makefile + echo EXTRA_CXXFLAGS =>>Makefile rem This must have a trailing space. echo QTSRC = %QTSRC% >> Makefile set tmpl=win32 diff --git a/dist/changes-5.5.0 b/dist/changes-5.5.0 new file mode 100644 index 0000000000000000000000000000000000000000..12240425337ef90bccadf0d4cddc6b28e06cc13c --- /dev/null +++ b/dist/changes-5.5.0 @@ -0,0 +1,619 @@ +Qt 5.5 introduces many new features and improvements as well as bugfixes +over the 5.4.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + + http://doc.qt.io/qt-5.5 + +The Qt version 5.5 series is binary compatible with the 5.4.x series. +Applications compiled for 5.4 will continue to run with 5.5. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Deprecation Notice * +**************************************************************************** + + - Support for the following platforms or toolchains is deprecated in Qt + 5.5 and will be removed as of Qt 5.6: + * Apple OS X builds using GNU libstdc++ + * BlackBerry 10 + * QNX 6.5 + + The following platforms or toolchains are deprecated and will be + removed as of Qt 5.7: + * Apple OS X 10.7 (Lion) + * GNU Compiler Collection (GCC) versions 4.6 and earlier + * Microsoft Visual Studio compiler versions 2008 and 2010 + * Microsoft Windows XP, Windows Vista + * Microsoft Windows Embedded Compact 7 + + Deprecated platforms and toolchains continue to work until removed. + + - The QtWebKit and QtQuick1 modules and support for the QML 1 language + are deprecated and Qt 5.5 will be the last release to include + them. Starting with Qt 5.6, the source code for those modules will + not be included in Qt's packaging. Compiling the 5.5 release of + QtWebKit modules along with Qt 5.6 or future versions should + work. QtQuick1 is not guaranteed to work in future versions after + Qt 5.6. + + - The QtScript module is deprecated and will be removed from Qt's + packaging starting with version 5.7. The 5.5 and 5.6 releases of + QtScript should continue to work along with Qt 5.7 and future + versions. + + - [QTBUG-25121] The usage of the QStyleOptionProgressBar::orientation + member has been deprecated. + + - QLibraryInfo::buildDate() was deprecated and will return a constant + date now. + +**************************************************************************** +* Future Direction Notice * +**************************************************************************** + + - In Qt 6, QCoreApplication::notify() will not be called for events being + delivered to objects outside the main thread. The reason for that is + that the main application object may begin destruction while those + threads are still delivering events, which is undefined behavior. + Applications that currently override notify() and use that function + outside the main thread are advised to find other solutions in the mean + time. + + - Qt 5.7 will begin requiring certain C++11 features in order to + compile. The minimum compiler versions for that release will be: + * Clang 3.2 (included in XCode 5.0) + * GCC 4.7 + * Intel C++ Composer XE 2013 SP1 (compiler version 14.0) + * Microsoft Visual Studio 2012 (compiler version 17.0) + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - Q_ASSERT will now expand the condition even in release mode when asserts + are disabled, albeit in an unreachable code path. This solves compiler + warnings about variables and functions that were unused in release mode + because they were only used in assertions. Unfortunately, codebases that + hid those functions and variables via #ifndef will need to remove the + conditionals to compile with Qt 5.5. + - QDBusConnection::sender() (deprecated since Qt 4.3) has changed to + always return an invalid QDBusConnection. To know what connection the + incoming call was received from, use QDBusContext. + - QHostAddress will no longer convert IPv6 addresses of type "v4-mapped" + to IPv4. To perform this conversion manually, construct another + QHostAddress with the result of toIPv4Address(). + - (DY)LD_LIBRARY_PATH will no longer "stick" in the process environment + when starting a QProcess. This means that if a QProcess is started with + a clear environment, it will not specially inherit (DY)LD_LIBRARY_PATH + from the parent process. This should not affect most applications, but + if the old behavior is desired, one can simply pass a clear + QProcessEnvironment with the (DY)LD_LIBRARY_PATH values added, to the + QProcess. + - QAbstractTableModel and QAbstractListModel now reimplement sibling() + to avoid calling parent() (which returns a constant). Subclasses of + these models that override parent(), will likely also need to + override sibling() now. +- Qt 5.5 received some header #include cleanups. Code that relied on indirect + includes from Qt headers may need to include some headers explicitly now. + For example, qstringlist.h no longer includes QDataStream and QObject. + + - QCoreApplication: + * [QTBUG-30330][QTSOLBUG-184] On Windows, QCoreApplication::arguments() + now returns a list built from argv on Windows as well if a modified + argv was passed to the class' constructor. + + - QIODevice: + * Opening Android assets with QIODevice::ReadWrite now returns false to + correctly indicate that the files are not writable. + + - QItemDelegate: + * [QTBUG-3305] QItemDelegate will now not close a + QTextEdit/QPlainTextEdit editor when the tab key is pressed; instead, + the key will reach the editor. + + - QProgressDialog: + * [QTBUG-17427][QTBUG-25316] The timer for estimating the duration of + the progress dialog is now started in the constructor and in + setValue(minimum()), as well as when calling setValue(0), as + previously documented. + + - QSaveFile: + * [QTBUG-44086] Files created by QSaveFile do now have the same + rights as files created by QFile. This also fixes a regression in + QSettings: In the Qt 5.4 series, new files created by QSettings + were only readable by the current user. + + - QVariant: + * [QTBUG-42722] QVariant now obeys the C++ type promotion rules when + comparing numeric types (integrals, float and double), including the + fact that unsigned comparisons are preferred for types of the same + rank (that is, now QVariant(-1) > QVariant(0U)). + + - QWindow: + * QWindows will no longer be re-shown automatically when moved from a + destroyed QScreen, unless that QScreen was a virtual sibling of the + primary screen. + + - qmake: + * For commercial builds, qmake now checks for a valid Qt license. This + requires setting up a Qt Account (or .qt-license file) on the + development machine. + * Qt configure and qmake used with a MinGW spec will no longer emulate + MSVC by picking up the INCLUDE and LIB environment variables. Use the + -I/-L configure options to pass additional paths, as you would under + Unix. + * A lot of quoting issues have been fixed. As a side effect, qmake + has become more sensitive to over-quoted file names in project + files. + * qmake is now stricter about syntax errors in project files. + +**************************************************************************** +* Library * +**************************************************************************** + +QtCore +------ + + - Added qEnvironmentVariableIntValue(). + - Added Q_DECL_RELAXED_CONSTEXPR for the corresponding C++14 feature + - Added qHashRange() and qHashRangeCommutative() functions to aid + implementing qHash() overloads for custom types. + - Q_ENUMS and Q_FLAGS have been deprecated, and replaced by Q_ENUM and + Q_FLAG macros. These two new macros automatically register the enum with + the Qt metatype system, allowing automatic conversion to or from string + in QVariant, or to show the strings by QDebug operators. They also + enable the new QMetaEnum::fromType function. + - QPersistentModel index becomes an built-in meta-type, including QVariant + support. + - Updated Unicode data to v.7.0 + - Updated QLocale data to CLDR v.27 + - Updated QTimeZone data to CLDR v.27 + + - Item Models: + * QItemSelectionModel can now be created without a model and have one + set later. + + - Logging: + * QtInfoMsg got added as a new QtMsgType. Use the new qInfo(), qCInfo() + macros to log to it. + + - Logging framework: + * %{threadid} now prints the real thread ID. On Linux, OS X, iOS, + FreeBSD and Windows, the value is unique system-wide. On other + systems, it will print something that may be process-specific (the + value of pthread_self(3)). To print the pointer to QThread::current(), + use %{qthreadptr}. + + - moc + * Classes annotated with Q_GADGET can now have Q_PROPERTY and Q_INVOKABLE + functions. QMetaProperty::{read,write}OnGadget and + QMetaMethod::invokeOnGadget can be used with those. + + - Objective-C: + * [QTBUG-37116] Added NSDate/CDateRef converters for QDateTime + + - QAssociativeIterable: + * Added find(). + + - QCommandLineParser: + * Message boxes are used to display errors and usage if no console + window can be obtained on Windows. + + - QDebug: + * Printing of QStrings and QStringRefs whenever "noquote" is not active + now prints the strings in a format that can be copied back to C++ + code. All characters that aren't printable in US-ASCII are escaped + (this includes printable Unicode characters outside of US-ASCII). + Pretty-printing will not respect QTextFormat padding or field widths. + * Similarly, printing of QByteArrays whenever "noquote" is not active now + prints the arrays in a format consumable in C++, with all non-printable + characters printed in hex escape sequences. + + - QJsonObject: + * Added conversion to and from QVariantHash + + - QLibrary: + * Added DeepBindHint which maps to RTLD_DEEPBIND on Linux making it + possible to load libraries with external symbols that clash with + already loaded ones, such as plugins linked to Qt4. + + - QLockFile: + * [QTBUG-45497] Detection of stale lock files got more robust and takes + the name of the process that belongs to the stored PID into account. + + - QRegularExpression: + * Support for matching using QStringRef as the subject's string type has + been added. + + - QSet: + * Can now be used as the key in QSet and QHash. + + - QSortFilterProxyModel: + * [QTBUG-35440] QSortFilterProxyModel now properly forwards the roles + that have been changed when the source model emits dataChanged(). + + - QStandardPaths: + * [QTBUG-38872][QTBUG-38845] Added QStandardPaths::AppConfigLocation, + for application-specific configuration directory. ConfigLocation was + inconsistent. + + - QString: + * Added support for retrieving the QRegularExpressionMatch to indexOf + and lastIndexOf. + * Added QT_RESTRICTED_CAST_FROM_ASCII macro as less intrusive + alternative to QT_NO_CAST_FROM_ASCII. + * Added methods for convenient conversion to and from std::u16string and + std::u32string. + * Added asprintf(), vasprintf(). + + - QThreadPool: + * Added QThreadPool::cancel() which allows removing from the job queue a + job that hasn't been started yet. + + - QTimeZone: + * Added methods systemTimeZone() and utc() that return QTimeZone objects + for the system time zone and for UTC, respectively. + + - QVector: + * Added QVector::append(const QVector &) overload + + - QVector3D: + * Added convenience project and unproject methods to use like gluProject + and gluUnproject + + - QtMath: + * qmath.h no longer includes math.h, so any sources depending on that + indirect inclusion may fail to build. + + - State Machine: + * Added support for internal transitions. + * [QTBUG-40293] Added an addTransition() overload that takes a + pointer-to-member for the signal triggering the transition. + * [QTBUG-44963] Fixed an issue where a history state restore would + activate too many states, possibly putting the state machine in an + invalid state. + * QTBUG-44783] Fixed an issue where the state machine could end up in + an invalid state when transitions from a parallel state were not + checked for conflicts. + * Fixed a case where a parallel state was not exited and re-entered + when one of its substates was exited and subsequently re-entered. + * Fixed the non-deterministic behavior of picking a transition from a + set of conflicting transitions. + +QtDBus +------ + + - Added annotation org.qtproject.QtDBus.MethodName to allow + autogenerating C++ methods with different names to the original DBus + method + +QtGui +----- + + - Added support for device-specific backend plugins in eglfs. + - eglfs is now using fullscreen mode also when running on X11. + - Added a plugin to get mouse, keyboard and touch events via libinput. + - The linuxfb platform plugin's input device handling is now compatible + with eglfs. The evdev keyboard, mouse and touch code is compiled in by + default. + - The mouse cursor on Embedded Linux is now handling hotplugging correctly + with eglfs and linuxfb regardless of how the input handling code is + loaded (via a generic plugin or built in to the platform plugin). + - QOffscreenSurface is now relying on EGL_KHR_surfaceless_context when + available, and avoids creating a pbuffer surface when the extension is + present. + - initializeOpenGLFunctions() no longer needs to be called when querying a + versioned function wrapper object via QOpenGLContext::versionFunctions(). + - Added version function classes for OpenGL 4.4 and 4.5 and deprecate some + erroneously classified functions. + - Exposed TabFocusBehavior in QStyleHints + - [QTBUG-42240][QTBUG-43263] Qt now contains a built-in GPU driver + blacklist for Windows that disables the usage of desktop OpenGL with + some older cards that are known to be unstable with opengl32.dll. + - [QTBUG-44937] Support for QScreen::grabWindow() is now available on + embedded platforms (eglfs, linuxfb). + - Added QStyleHints::singleClickActivation to access whether the platform + expects item activation to occur on single clicks rather than double + clicks. + - [QTBUG-40034] QOpenGLWidget and QQuickWidget are now supported on iOS. + + - Accessibility: + * [QTBUG-44479] Qt now reports text attributes correctly on Linux, so + ORCA+F now works properly in QTextEdit and other text controls. + + - Accessibility / OS X: + * QTextEdit now properly reports to accessibility visual lines + (softlines) as lines, instead of whole paragraphs. This allows better + VoiceOver user experience when reading text line by line using arrows + up/down. + * Visual bounds returned by QTextEdit were singificantly improved; this + enables VoiceOver to draw properly positioned VoiceOver cursor. + + - Image plugins: + * [QTBUG-37946][QTBUG-43563][QTBUG-45552][QTBUG-45865] An option has + been added to QImageReader to enable automatic application of EXIF + orientation. This behavior was default in Qt 5.4.1, but reverted in Qt + 5.4.2. + + - QFontDatabase: + * Added QFontDatabase::isPrivateFamily() + + - QImage: + * Added support for grayscale and alpha 8-bit formats which can also be + rendered to. + + - QPainter: + * [QTBUG-35830] QPainter will no longer try to replace IntersectClip + with ReplaceClip if the paint engine is a QPicture. + + - QPlatformSurfaceEvent: + * [QTBUG-42476][QTBUG-42483] Added event class QPlatformSurfaceEvent, + which is sent to QWindow and QOffscreenSurface when native surface is + created or about to be destroyed. + + - QQuaternion: + * Added methods to convert a quaternion to/from Euler angles and to/from + rotation matrix. + + - QScreen: + * Added devicePixelRatio property. + + - QTextDocument: + * Support for searching with a QRegularExpression in a document has been + added. + + - QWheelEvent: + * On OSX, trackpad wheel event phase transitions now occur in the order + ScrollBegin, ScrollUpdate, ..., ScrollEnd, ScrollUpdate, ..., + ScrollEnd, where the second batch of updates represents momentum + events (inertial scrolling). + + - QWindow: + * [QTBUG-32956] lastWindowClosed will now be emitted even if + quitOnLastWindowClosed is not set. + + - Windows: + * [QTBUG-43263] Introduced experimental feature allowing the user to + specify a GPU driver buglist with some additional keywords to chooose + the GL renderer backend depending on GPU. + + - i18n: + * [QTBUG-43447] Fixed bug where layout direction did not switch + according to the instruction in the translation file. + + - Text: + * [QTBUG-39286] Fixed position of underline on centered text when the + text layout's width is an even number. + +QtNetwork +--------- + + - [QTBUG-26295] Introduced libproxy backend for Unix platforms, enabled + automatically if the required dev package is present + - As some legacy ifdefs for OpenSSL 0.9.7 and 0.9.8f were removed, Qt + will no longer build with these versions. In addition, there is no + longer support for an OpenSSL library built with NO_TLSEXT. + - [QTBUG-26538] Fixed a bug that caused both QTcpSocket and QUdpSocket to + close the socket and lose any bound ports before connecting. Now + bind()/setSocketDescriptor() followed by connect() will retain the + original file descriptor. + + - QLocalSocket: + * [QTBUG-16688] On Windows, waitForReadyRead now always waits for more + data, even if bytes are still in the buffer. + + - QNetworkAccessManager: + * It is now possible to use TLS PSK ciphersuites when using HTTPS (or + similar protocols working over SSL). + + - QSslSocket: + * [QTBUG-39077] It is now possible to use TLS PSK ciphersuites in client + sockets. + * A new SSL backend for iOS and OS X, implemented with Apple's Secure + Transport (Security Framework). + + - SSL/TLS support: + * [QTBUG-18972] It is now possible to parse elliptic curve certificates. + * It is now possible to choose which elliptic curves should be used by + an elliptic curve cipher. + +QtTest +------ + + - QCOMPARE now pretty-prints QSizePolicy{,::Policy,::ControlType{,s}}. + - QtTest now prints an escaped version of QByteArrays that failed to + compare with QCOMPARE, instead of the hex dump. + - QTest::toString() can now be overloaded (instead of just specialized) + for custom types, and is now reliably found through argument-dependent + lookup (ADL). + +QtWidgets +--------- + + - Added QPlainTextEdit::createStandardContextMenu(QPoint) overload that + takes the position in document coordinates. This method enables the + actions that are sensitive to the given position eg. where the user + clicked. + + - Accessibility / OS X: + * VoiceOver users of QTextEdit can now use mouse and touch exploration + on trackpad to point at text to have spoken to them. + + - Layouts: + * [QTBUG-43099] Fixed a bug where spans sometimes didn't distribute + themselves to the last cells they covered. + + - QAbstractItemView: + * Added iconSizeChanged signal. + + - QAbstractScrollArea: + * [QTBUG-8315] A getter for the viewport margins has been added. + + - QComboBox: + * A QComboBox does not reset itself any more when setting the same model + more than once. + * [QTBUG-43350] QComboBox will now reset its root model index when a new + model is set on it. + + - QHeaderView: + * [QTBUG-21201] Auto-scroll the view when making extended row/column + selections. + * Default section size is now style-dependent by default. + * Added resetDefaultSectionSize(). + + - QMenu: + * [QTBUG-20094] QMenu now pick up how "sloppy" submenus behave from the + style. + + - QOpenGLWidget: + * [QTBUG-40717] Added an UpdateBehavior flag to QOpenGLWidget and + enabled support for NoParitalUpdate for QOpenGLWidget. NoPartialUpdate + is the default update behavior for QOpenGLWidget. + + - QSizePolicy: + * QSizePolicy::ControlTypes is now introspectable through QSizePolicy's + meta object. + + - QToolButton: + * [QTBUG-23396] Fixed the double removal of ampersands. + + - QTreeWidget: + * [QTBUG-40060] Restored Qt 5.1 behavior of QTreeWidgetItems with + ItemIsTristate to enable automatic management of the check state. + User-editable tristate checkboxes are now enabled by setting the new + flag ItemIsUserTristate. + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + + - Removed BlackBerry PlayBook support. + +Android +------- + + - [QTBUG-43705] Fixed canonical path for nonexistent paths on some + devices. + - [QTBUG-38700] On devices with translucent system UI, Qt's windows are now + positioned to avoid overlapping it. This behavior can be + overridden in the application's AndroidManifest.xml. + - [QTBUG-45430] Fixed a bug that caused applications not to be resumable + after user changed language in system settings. + + - QtCore / QTimeZone: + * [QTBUG-35908] Android timezones are now available in QTimeZone. + + - QtWidgets: + * Enable QDockWidget window decorations. + + - The QtDBus module is now disabled by default. + + - Added support for arm64-v8a, x86_64, and mips64 with gcc 4.9. + +OS X +---- + + - [QTBUG-43999] QApplication::setWindowIcon now changes the icon for the + application in the dock. + + - Text: + * [QTBUG-44708] Fixed appending text with a different writing system and + formatting to a latin ligature. + +Windows +------- + + - QMimeData: + * [QTBUG-17373] Added support for handling dropping of multiple mail + attachments, adding ;index=N to the mimetype string + application/x-qt-windows-mime;value="FileContents" + + - Text: + * [QTBUG-44501] Fixed design metrics for text + +X11/XCB +------- + + - GLX and EGL code paths are now dynamically resolved, making it possible + for one build of a plugin to use both code paths. The default is to use + the GLX code path if available. This can be overridden by specifying + QT_XCB_GL_INTEGRATION=xcb_egl as an environment variable. Enable the + logging category qt.xcb.glintegration.debug to get debug log output of + what integration is used. + - [QTBUG-31762] QSystemTrayIcon now uses StatusNotifier D-Bus protocol + when the desktop environment supports it + - [QTBUG-40174][QTBUG-42985] If all QScreens (xcb outputs) are + disconnected while an application is running, + QGuiApplication::primaryScreen() will now return null until a screen is + connected again. + +**************************************************************************** +* Compiler Specific Changes * +**************************************************************************** + + - Qt 5.5 now unconditionally uses the "using" keyword. Compilers that do + not support this keyword are deprecated and will not be able to build + Qt. Previous versions of Qt may or may not compile, as no testing was + done to ensure it worked. + - Visual Studio: -Zm200 (an option to specify the precompiled header + memory allocation limit) is not added anymore by qmake to the compiler + calls. If you encounter an C1076 compiler error you might need to re-add + it in your .pro file. + +**************************************************************************** +* Tools * +**************************************************************************** + +configure & build system +------------------------ + + - Added support for VS2015. + - [QTBUG-31814][OS X/iOS] Qt is now built with a relative RPATH. + - [VS2012+] Qt is now always built with C++11 with these compilers. + - [Windows] Added -static-runtime option. + - Added support for GCC/Clang -fsanitize= options. + - Enabled tslib autodetection by default. + - Added configure-time check for IPC support. + - [QTBUG-44690][QNX] Fixed NEON detection when cross-compiling on Windows. + - On-device compilation should work better on RaspPi and some other + devices now (use linux-g++ mkspec). + - configure -redo and config.status support spaces in arguments now. + - Qt can be now built in and installed to directories with spaces. + Note that source directories with spaces are still not supported. + +qmake +----- + + - [QTBUG-3069][Linux] Building with -rpath will now create DT_RUNPATH tags + instead of DT_RPATH, allowing LD_LIBRARY_PATH to override the rpath. + - [QTBUG-41917][VS] Fixed project generation when PRECOMPILED_SOURCE is + in a different directory than PRECOMPILED_HEADER. + - [QTBUG-42454][MinGW] Added handling of QMAKE_MANIFEST. + - [QTBUG-13496][MSVC] CONFIG+=no_batch is now automatically added when + multiple sources with the same base name exist. + - Added $$[QT_INSTALL_PREFIX/dev], etc. properties which reflect the + on-device locations of Qt (the -prefix, etc. passed to configure). + - Building under MSys is less problematic now. + - [QTBUG-37269] Fixed cross-compilation for Unix on Windows/MinGW. + - [QTBUG-8202][QTBUG-20566][QTBUG-44685] Fixed distclean targets. + - [QTBUG-43162][VS] Added DISTFILES support for Visual Studio projects. + - [QTBUG-41753][VS][WinPhone] Fixed MdilXapCompile deployment step. + - [QTBUG-44960][VS] Reworked .dll deployment. Added $$QMAKE_DLL_PATHS. + - [QTBUG-44823][MSVC] Fixed unreasonable values being passed in /VERSION. + Added $$VERSION_PE_HEADER to override the value. + - [WinRT] The icon handling was reworked/extended. + - [QTBUG-12711] Fixed infinite recursion on malformed .prl files. + +**************************************************************************** +* Third-party libraries * +**************************************************************************** + + - [QTBUG-44815][QTBUG-37660][QTBUG-44694][QTBUG-42443] ANGLE was updated + to Chromium branch 2356 (2.1~99f075dade7c). diff --git a/doc/global/html-footer-online.qdocconf b/doc/global/html-footer-online.qdocconf index 1937d97cbbc0307db840cabdc6a6accab093dad5..18022cabff72b6767afd6a433fccfd267849b55c 100644 --- a/doc/global/html-footer-online.qdocconf +++ b/doc/global/html-footer-online.qdocconf @@ -11,61 +11,61 @@ HTML.footer += \ " <div class=\"footer-main\">\n" \ " <div class=\"container clearfix\">\n" \ " <nav class=\"footer-nav clearfix\">\n" \ - " <div class=\"menu-footer-menu-container\"><ul id=\"menu-footer-menu\" class=\"menu\"><li id=\"menu-item-1350\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-1350\"><a href=\"http://qt.io/about-us/\">About us</a>\n" \ + " <div class=\"menu-footer-menu-container\"><ul id=\"menu-footer-menu\" class=\"menu\"><li id=\"menu-item-1403\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-1403\"><a href=\"http://qt.io/download/\">Download</a>\n" \ "<ul class=\"sub-menu\">\n" \ - " <li id=\"menu-item-1353\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1353\"><a href=\"http://qt.io/events/\">Training & Events</a></li>\n" \ - " <li id=\"menu-item-1596\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1596\"><a href=\"http://qt.io/news/\">News</a></li>\n" \ - " <li id=\"menu-item-1354\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1354\"><a href=\"http://qt.io/resource-center/\">Resource Center</a></li>\n" \ - " <li id=\"menu-item-1352\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1352\"><a href=\"http://qt.io/partners/\">Partners</a></li>\n" \ - " <li id=\"menu-item-1349\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1349\"><a href=\"http://qt.io/careers/\">Careers</a></li>\n" \ - " <li id=\"menu-item-11676\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-11676\"><a href=\"http://qt.io/locations/\">Locations</a></li>\n" \ + " <li id=\"menu-item-11677\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-11677\"><a href=\"http://qt.io/download/\">Start for Free</a></li>\n" \ + " <li id=\"menu-item-15840\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-15840\"><a href=\"http://qt.io/download-eval-for-applications-step-2/\">Qt for Application Development</a></li>\n" \ + " <li id=\"menu-item-15841\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-15841\"><a href=\"http://qt.io/request-eval-for-devices-step-2/\">Qt for Device Creation</a></li>\n" \ + " <li id=\"menu-item-15838\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-15838\"><a href=\"http://qt.io/download-open-source/\">Qt Open Source</a></li>\n" \ + " <li id=\"menu-item-1415\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1415\"><a href=\"http://qt.io/terms-conditions/\">Terms & Conditions</a></li>\n" \ + " <li id=\"menu-item-14184\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-14184\"><a href=\"http://qt.io/FAQ/\">Licensing FAQ</a></li>\n" \ "</ul>\n" \ "</li>\n" \ "<li id=\"menu-item-1355\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-1355\"><a href=\"http://qt.io/product/\">Product</a>\n" \ "<ul class=\"sub-menu\">\n" \ - " <li id=\"menu-item-1358\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1358\"><a href=\"http://qt.io/qt-framework/\">Qt Framework</a></li>\n" \ - " <li id=\"menu-item-1356\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1356\"><a href=\"http://qt.io/qt-features/\">Qt Features</a></li>\n" \ - " <li id=\"menu-item-1359\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1359\"><a href=\"http://qt.io/qt-quick/\">Qt Quick</a></li>\n" \ + " <li id=\"menu-item-12576\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-12576\"><a href=\"http://qt.io/product/\">Qt in Use</a></li>\n" \ + " <li id=\"menu-item-15848\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-15848\"><a href=\"http://qt.io/application-development/\">Qt for Application Development</a></li>\n" \ " <li id=\"menu-item-1357\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1357\"><a href=\"http://qt.io/qt-for-device-creation/\">Qt for Device Creation</a></li>\n" \ - " <li id=\"menu-item-10159\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-10159\"><a href=\"http://qt.io/mobile-app-development/\">Qt for Mobile Apps</a></li>\n" \ - " <li id=\"menu-item-12576\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-12576\"><a href=\"http://qt.io/qt-in-use/\">Qt in Use</a></li>\n" \ - "</ul>\n" \ - "</li>\n" \ - "<li id=\"menu-item-33\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-33\"><a href=\"http://qt.io/developers/\">Developers</a>\n" \ - "<ul class=\"sub-menu\">\n" \ - " <li id=\"menu-item-1365\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1365\"><a href=\"http://doc.qt.io/\">Documentation</a></li>\n" \ - " <li id=\"menu-item-1364\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1364\"><a href=\"http://doc.qt.io/qt-5/qtexamplesandtutorials.html\">Examples & Tutorials</a></li>\n" \ - " <li id=\"menu-item-1363\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1363\"><a href=\"http://doc.qt.io/qt-5/topics-app-development.html\">Tools</a></li>\n" \ - " <li id=\"menu-item-1361\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1361\"><a href=\"http://wiki.qt.io/\">Wiki</a></li>\n" \ - " <li id=\"menu-item-1360\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1360\"><a href=\"http://forum.qt.io/\">Forums</a></li>\n" \ - " <li id=\"menu-item-1362\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1362\"><a href=\"http://wiki.qt.io/Qt_Contribution_Guidelines\">Contribute to Qt</a></li>\n" \ + " <li id=\"menu-item-1356\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1356\"><a href=\"http://qt.io/qt-features/\">Commercial Features</a></li>\n" \ + " <li id=\"menu-item-15850\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-15850\"><a href=\"http://qt.io/ide/\">Qt Creator IDE</a></li>\n" \ + " <li id=\"menu-item-1359\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1359\"><a href=\"http://qt.io/qt-quick/\">Qt Quick</a></li>\n" \ "</ul>\n" \ "</li>\n" \ "<li id=\"menu-item-1347\" class=\"menu-item menu-item-type-post_type menu-item-object-page current-menu-ancestor current-menu-parent current_page_parent current_page_ancestor menu-item-has-children menu-item-1347\"><a href=\"http://qt.io/services/\">Services</a>\n" \ "<ul class=\"sub-menu\">\n" \ - " <li id=\"menu-item-32\" class=\"menu-item menu-item-type-post_type menu-item-object-page page_item page-item-14 menu-item-32\"><a href=\"http://qt.io/support/\">Support</a></li>\n" \ " <li id=\"menu-item-4028\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-4028\"><a href=\"http://qt.io/services-technology-evaluation/\">Technology Evaluation</a></li>\n" \ " <li id=\"menu-item-4027\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-4027\"><a href=\"http://qt.io/services-proof-of-concept/\">Proof of Concept</a></li>\n" \ " <li id=\"menu-item-4026\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-4026\"><a href=\"http://qt.io/services-design-implementation/\">Design & Implementation</a></li>\n" \ " <li id=\"menu-item-4025\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-4025\"><a href=\"http://qt.io/services-productization/\">Productization</a></li>\n" \ - " <li id=\"menu-item-5124\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-5124\"><a href=\"https://qtcloudservices.com/\">Qt Cloud Services</a></li>\n" \ + " <li id=\"menu-item-15863\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-15863\"><a href=\"http://qt.io/qt-training/\">Qt Training</a></li>\n" \ + " <li id=\"menu-item-4779\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4779\"><a href=\"https://qt.io/partners/\">Partner Network</a></li>\n" \ "</ul>\n" \ "</li>\n" \ - "<li id=\"menu-item-1403\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-1403\"><a href=\"http://qt.io/download/\">Download</a>\n" \ + "<li id=\"menu-item-33\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-33\"><a href=\"http://qt.io/developers/\">Developers</a>\n" \ "<ul class=\"sub-menu\">\n" \ - " <li id=\"menu-item-11677\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-11677\"><a href=\"http://qt.io/download/\">Free 30-Day Trial</a></li>\n" \ - " <li id=\"menu-item-1982\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1982\"><a href=\"http://qt.io/buy-enterprise-step-2/\">Enterprise</a></li>\n" \ - " <li id=\"menu-item-1985\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1985\"><a href=\"http://qt.io/buy-professional-step-2/\">Professional</a></li>\n" \ - " <li id=\"menu-item-3346\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-3346\"><a href=\"http://qt.io/buy-indiemobile-step-2/\">Indie Mobile</a></li>\n" \ - " <li id=\"menu-item-3343\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-3343\"><a href=\"http://qt.io/download-open-source/\">Community</a></li>\n" \ - " <li id=\"menu-item-1415\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1415\"><a href=\"http://qt.io/terms-conditions/\">Legal | Terms & Conditions</a></li>\n" \ + " <li id=\"menu-item-1365\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1365\"><a href=\"http://doc.qt.io/\">Documentation</a></li>\n" \ + " <li id=\"menu-item-1364\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1364\"><a href=\"http://doc.qt.io/qt-5/qtexamplesandtutorials.html\">Examples & Tutorials</a></li>\n" \ + " <li id=\"menu-item-1363\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1363\"><a href=\"http://doc.qt.io/qt-5/topics-app-development.html\">Development Tools</a></li>\n" \ + " <li id=\"menu-item-1361\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1361\"><a href=\"http://wiki.qt.io/\">Wiki</a></li>\n" \ + " <li id=\"menu-item-1360\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1360\"><a href=\"http://forum.qt.io/\">Forums</a></li>\n" \ + " <li id=\"menu-item-15922\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-15922\"><a href=\"http://wiki.qt.io/contribute\">Contribute to Qt</a></li>\n" \ + "</ul>\n" \ + "</li>\n" \ + "<li id=\"menu-item-1350\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-1350\"><a href=\"http://qt.io/about-us/\">About us</a>\n" \ + "<ul class=\"sub-menu\">\n" \ + " <li id=\"menu-item-1353\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1353\"><a href=\"http://qt.io/events/\">Training & Events</a></li>\n" \ + " <li id=\"menu-item-1354\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1354\"><a href=\"http://qt.io/resource-center/\">Resource Center</a></li>\n" \ + " <li id=\"menu-item-12285\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-12285\"><a href=\"http://qt.io/news/\">News</a></li>\n" \ + " <li id=\"menu-item-1349\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1349\"><a href=\"http://qt.io/careers/\">Careers</a></li>\n" \ + " <li id=\"menu-item-11676\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-11676\"><a href=\"http://qt.io/locations/\">Locations</a></li>\n" \ + " <li id=\"menu-item-15911\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-15911\"><a href=\"http://qt.io/contact-us\">Contact Us</a></li>\n" \ "</ul>\n" \ "</li>\n" \ "</ul></div></nav>\n" \ "<a href=\"http://qt.io/about-us/\" target=\"_blank\" class=\"theqtcompany\"></a>\n" \ " <div class=\"footer-social clearfix\">\n" \ " <div class=\"facebook\">\n" \ - " <iframe scrolling=\"no\" frameborder=\"0\" allowTransparency=\"true\" src=\"//www.facebook.com/plugins/like.php?href=https%3A%2F%2Fwww.facebook.com%2Fqt&width&layout=button_count&action=like&show_faces=true&share=false&height=21\" style=\"border:none;overflow:hidden;height:21px;\"></iframe>\n" \ + " <iframe scrolling=\"no\" frameborder=\"0\" allowTransparency=\"true\" src=\"http://www.facebook.com/plugins/like.php?href=https%3A%2F%2Fwww.facebook.com%2Fqt&width&layout=button_count&action=like&show_faces=true&share=false&height=21\" style=\"border:none;overflow:hidden;height:21px;\"></iframe>\n" \ " </div>\n" \ " <div class=\"twitter\">\n" \ " <iframe id=\"twitter-widget-0\" scrolling=\"no\" frameborder=\"0\" allowtransparency=\"true\" src=\"http://platform.twitter.com/widgets/follow_button.33b190ea0cba008796487b65df7f6d8e.en.html#_=1414403615717&id=twitter-widget-0&lang=en&screen_name=qtproject&show_count=true&show_screen_name=false&size=m\" class=\"twitter-follow-button twitter-follow-button\" title=\"Twitter Follow Button\" data-twttr-rendered=\"true\" style=\"width: 160px; height: 20px;\"></iframe>\n" \ diff --git a/doc/global/manifest-meta.qdocconf b/doc/global/manifest-meta.qdocconf index 01950e650cbe07d3002a65dfd4420d836e4244ac..e7f0464efde5d93ab31ab9125d3a7faf2656a006 100644 --- a/doc/global/manifest-meta.qdocconf +++ b/doc/global/manifest-meta.qdocconf @@ -42,15 +42,16 @@ manifestmeta.highlighted.names = "QtQuick/Qt Quick Demo - Same Game" \ "QtQuick/Qt Quick Demo - StocQt" \ "QtQuick/Qt Quick Demo - Clocks" \ "QtQuick/Qt Quick Examples - Shader Effects" \ - "QtQuick/Qt Quick Examples - Text" \ - "QtQuick/Qt Quick Examples - Window and Screen" \ + "QtQuickExtras/Qt Quick Extras - Dashboard" \ + "QtQuickExtras/Qt Quick Extras - Gallery" \ "QtQuickControls/Qt Quick Controls - Gallery" \ "QtQuickControls/Qt Quick Controls - Text Editor Example" \ "QtQuickControls/Qt Quick Controls - Table View Example" \ "QtQuickControls/Qt Quick Controls - Calendar Example" \ "QtQuickDialogs/Qt Quick System Dialog Examples" \ - "QtWidgets/Application Example" \ - "QtWinExtras/Quick Player" + "QtWinExtras/Quick Player" \ + "QtMultimedia/QML Video Shader Effects Example" \ + "QtCanvas3D/Planets Example" manifestmeta.highlighted.attributes = isHighlighted:true @@ -269,12 +270,9 @@ manifestmeta.thumbnail.names = "QtCore/Contiguous Cache Example" \ "QtWidgets/Event Transitions Example" \ "QtWidgets/Two-way Button Example" \ "QtWidgets/Validators Example" \ - "ActiveQt/*" \ "QtDbus/*" \ "QtHelp/*" \ "QtMultimedia/AudioEngine Example" \ - "QtMultimedia/Declarative Radio Example" \ - "QtMultimediaWidgets/Media Player Example" \ "QtQml/Extending QML*" \ "QtQuick/Qt Quick Examples - Accessibility" \ "QtSensors/Qt Sensors - SensorGesture QML Type example" \ diff --git a/doc/global/qt-cpp-defines.qdocconf b/doc/global/qt-cpp-defines.qdocconf index 5f309d2a6194a5901196f18aa7adc1181f3104fa..2d2fb9c357d8792fb9bf6d8146d839895f239d88 100644 --- a/doc/global/qt-cpp-defines.qdocconf +++ b/doc/global/qt-cpp-defines.qdocconf @@ -37,6 +37,8 @@ Cpp.ignoretokens += \ Q_DECL_NOTHROW \ Q_DECL_PURE_FUNCTION \ Q_DECL_UNUSED \ + Q_DECL_CF_RETURNS_RETAINED \ + Q_DECL_NS_RETURNS_AUTORELEASED \ Q_DECLARATIVE_EXPORT \ Q_EXPLICIT \ Q_EXPORT \ @@ -135,6 +137,7 @@ Cpp.ignoredirectives += \ Q_DECLARE_PRIVATE_D \ Q_DECLARE_PUBLIC \ Q_DECLARE_SHARED \ + Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6 \ Q_DECLARE_TR_FUNCTIONS \ Q_DECLARE_TYPEINFO \ Q_DECL_NOEXCEPT_EXPR \ @@ -153,4 +156,5 @@ Cpp.ignoredirectives += \ QT_WARNING_DISABLE_CLANG \ QT_WARNING_DISABLE_GCC \ QT_WARNING_DISABLE_INTEL \ - QT_WARNING_DISABLE_MSVC + QT_WARNING_DISABLE_MSVC \ + Q_ATTRIBUTE_FORMAT_PRINTF diff --git a/doc/global/template/style/online.css b/doc/global/template/style/online.css index 240a8187988ea3ca3fc36258bbf245c91222d607..8775719be6a57fed33f3b754f9644fb19198ebbe 100644 --- a/doc/global/template/style/online.css +++ b/doc/global/template/style/online.css @@ -770,7 +770,7 @@ body.qt-account #navbar .navbar-oneQt h2 { #footerbar .theqtcompany { background:url("theqtcompany.png") no-repeat; background-size:100%; - width:150px; + width:215px; height:68px; display:inline; float:right; diff --git a/doc/global/template/style/theqtcompany.png b/doc/global/template/style/theqtcompany.png index b9799f387c561a6b5b5b5e958db53e42721ff638..fee3d26f3d1230ff2e535ae4ec9e07debeb1b118 100644 Binary files a/doc/global/template/style/theqtcompany.png and b/doc/global/template/style/theqtcompany.png differ diff --git a/doc/src/images/recentfiles-example.png b/doc/src/images/recentfiles-example.png deleted file mode 100644 index 8a1f2e5509426ab96a3e3280225908f37b3ab14e..0000000000000000000000000000000000000000 Binary files a/doc/src/images/recentfiles-example.png and /dev/null differ diff --git a/examples/corelib/ipc/ipc.pro b/examples/corelib/ipc/ipc.pro index 5fc3c7457f92df2986d1d2b0fb75b97732232936..987df7afc7f7475f688dbc1bececc7e887fbb8a7 100644 --- a/examples/corelib/ipc/ipc.pro +++ b/examples/corelib/ipc/ipc.pro @@ -3,4 +3,4 @@ requires(qtHaveModule(widgets)) TEMPLATE = subdirs # no QSharedMemory !vxworks:SUBDIRS = sharedmemory -!wince*:qtHaveModule(network): SUBDIRS += localfortuneserver localfortuneclient +!wince:qtHaveModule(network): SUBDIRS += localfortuneserver localfortuneclient diff --git a/examples/network/bearermonitor/bearermonitor.pro b/examples/network/bearermonitor/bearermonitor.pro index 48358fc33c32fabd39401cc50230dc9dbdd0bf4a..f364fabf2d0ff9eff346f8de67d312905ced6c25 100644 --- a/examples/network/bearermonitor/bearermonitor.pro +++ b/examples/network/bearermonitor/bearermonitor.pro @@ -12,8 +12,8 @@ FORMS = bearermonitor_240_320.ui \ bearermonitor_640_480.ui \ sessionwidget.ui -win32:!wince*:LIBS += -lws2_32 -wince*:LIBS += -lws2 +win32:!wince: LIBS += -lws2_32 +wince: LIBS += -lws2 CONFIG += console diff --git a/examples/opengl/hellogl2/mainwindow.cpp b/examples/opengl/hellogl2/mainwindow.cpp index 104cf24b3799bb0d9068da194f287b18299f4c6f..b938300349b69dda8c04050d9c5d3856b7138551 100644 --- a/examples/opengl/hellogl2/mainwindow.cpp +++ b/examples/opengl/hellogl2/mainwindow.cpp @@ -51,7 +51,7 @@ MainWindow::MainWindow() QAction *addNew = new QAction(menuWindow); addNew->setText(tr("Add new")); menuWindow->addAction(addNew); - connect(addNew, SIGNAL(triggered()), this, SLOT(onAddNew())); + connect(addNew, &QAction::triggered, this, &MainWindow::onAddNew); setMenuBar(menuBar); onAddNew(); diff --git a/examples/opengl/hellogl2/window.cpp b/examples/opengl/hellogl2/window.cpp index e60de3b05b605862c05ba3ee7a44dac984db5df0..11a5ae68a90b1acb1125014cefd888c0847f1e2a 100644 --- a/examples/opengl/hellogl2/window.cpp +++ b/examples/opengl/hellogl2/window.cpp @@ -59,12 +59,12 @@ Window::Window(MainWindow *mw) ySlider = createSlider(); zSlider = createSlider(); - connect(xSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setXRotation(int))); - connect(glWidget, SIGNAL(xRotationChanged(int)), xSlider, SLOT(setValue(int))); - connect(ySlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setYRotation(int))); - connect(glWidget, SIGNAL(yRotationChanged(int)), ySlider, SLOT(setValue(int))); - connect(zSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setZRotation(int))); - connect(glWidget, SIGNAL(zRotationChanged(int)), zSlider, SLOT(setValue(int))); + connect(xSlider, &QSlider::valueChanged, glWidget, &GLWidget::setXRotation); + connect(glWidget, &GLWidget::xRotationChanged, xSlider, &QSlider::setValue); + connect(ySlider, &QSlider::valueChanged, glWidget, &GLWidget::setYRotation); + connect(glWidget, &GLWidget::yRotationChanged, ySlider, &QSlider::setValue); + connect(zSlider, &QSlider::valueChanged, glWidget, &GLWidget::setZRotation); + connect(glWidget, &GLWidget::zRotationChanged, zSlider, &QSlider::setValue); QVBoxLayout *mainLayout = new QVBoxLayout; QHBoxLayout *container = new QHBoxLayout; @@ -77,7 +77,7 @@ Window::Window(MainWindow *mw) w->setLayout(container); mainLayout->addWidget(w); dockBtn = new QPushButton(tr("Undock"), this); - connect(dockBtn, SIGNAL(clicked()), this, SLOT(dockUndock())); + connect(dockBtn, &QPushButton::clicked, this, &Window::dockUndock); mainLayout->addWidget(dockBtn); setLayout(mainLayout); diff --git a/examples/opengl/hellogles3/glwindow.cpp b/examples/opengl/hellogles3/glwindow.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ad654b854cef99cb2274684410d36467fd6e64db --- /dev/null +++ b/examples/opengl/hellogles3/glwindow.cpp @@ -0,0 +1,281 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "glwindow.h" +#include <QImage> +#include <QOpenGLTexture> +#include <QOpenGLShaderProgram> +#include <QOpenGLBuffer> +#include <QOpenGLContext> +#include <QOpenGLVertexArrayObject> +#include <QOpenGLExtraFunctions> +#include <QPropertyAnimation> +#include <QPauseAnimation> +#include <QSequentialAnimationGroup> +#include <QTimer> + +GLWindow::GLWindow() + : m_texture(0), + m_program(0), + m_vbo(0), + m_vao(0), + m_target(0, 0, -1), + m_uniformsDirty(true), + m_r(0), + m_r2(0) +{ + m_world.setToIdentity(); + m_world.translate(0, 0, -1); + m_world.rotate(180, 1, 0, 0); + + QSequentialAnimationGroup *animGroup = new QSequentialAnimationGroup(this); + animGroup->setLoopCount(-1); + QPropertyAnimation *zAnim0 = new QPropertyAnimation(this, QByteArrayLiteral("z")); + zAnim0->setStartValue(1.5f); + zAnim0->setEndValue(10.0f); + zAnim0->setDuration(2000); + animGroup->addAnimation(zAnim0); + QPropertyAnimation *zAnim1 = new QPropertyAnimation(this, QByteArrayLiteral("z")); + zAnim1->setStartValue(10.0f); + zAnim1->setEndValue(50.0f); + zAnim1->setDuration(4000); + zAnim1->setEasingCurve(QEasingCurve::OutElastic); + animGroup->addAnimation(zAnim1); + QPropertyAnimation *zAnim2 = new QPropertyAnimation(this, QByteArrayLiteral("z")); + zAnim2->setStartValue(50.0f); + zAnim2->setEndValue(1.5f); + zAnim2->setDuration(2000); + animGroup->addAnimation(zAnim2); + animGroup->start(); + + QPropertyAnimation* rAnim = new QPropertyAnimation(this, QByteArrayLiteral("r")); + rAnim->setStartValue(0.0f); + rAnim->setEndValue(360.0f); + rAnim->setDuration(2000); + rAnim->setLoopCount(-1); + rAnim->start(); + + QTimer::singleShot(4000, this, SLOT(startSecondStage())); +} + +GLWindow::~GLWindow() +{ + makeCurrent(); + delete m_texture; + delete m_program; + delete m_vbo; + delete m_vao; +} + +void GLWindow::startSecondStage() +{ + QPropertyAnimation* r2Anim = new QPropertyAnimation(this, QByteArrayLiteral("r2")); + r2Anim->setStartValue(0.0f); + r2Anim->setEndValue(360.0f); + r2Anim->setDuration(20000); + r2Anim->setLoopCount(-1); + r2Anim->start(); +} + +void GLWindow::setZ(float v) +{ + m_eye.setZ(v); + m_uniformsDirty = true; + update(); +} + +void GLWindow::setR(float v) +{ + m_r = v; + m_uniformsDirty = true; + update(); +} + +void GLWindow::setR2(float v) +{ + m_r2 = v; + m_uniformsDirty = true; + update(); +} + +static const char *vertexShaderSource = + "layout(location = 0) in vec4 vertex;\n" + "layout(location = 1) in vec3 normal;\n" + "out vec3 vert;\n" + "out vec3 vertNormal;\n" + "out vec3 color;\n" + "uniform mat4 projMatrix;\n" + "uniform mat4 camMatrix;\n" + "uniform mat4 worldMatrix;\n" + "uniform mat4 myMatrix;\n" + "uniform sampler2D sampler;\n" + "void main() {\n" + " ivec2 pos = ivec2(gl_InstanceID % 32, gl_InstanceID / 32);\n" + " vec2 t = vec2(float(-16 + pos.x) * 0.8, float(-18 + pos.y) * 0.6);\n" + " float val = 2.0 * length(texelFetch(sampler, pos, 0).rgb);\n" + " mat4 wm = myMatrix * mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, t.x, t.y, val, 1) * worldMatrix;\n" + " color = texelFetch(sampler, pos, 0).rgb * vec3(0.4, 1.0, 0.0);\n" + " vert = vec3(wm * vertex);\n" + " vertNormal = mat3(transpose(inverse(wm))) * normal;\n" + " gl_Position = projMatrix * camMatrix * wm * vertex;\n" + "}\n"; + +static const char *fragmentShaderSource = + "in highp vec3 vert;\n" + "in highp vec3 vertNormal;\n" + "in highp vec3 color;\n" + "out highp vec4 fragColor;\n" + "uniform highp vec3 lightPos;\n" + "void main() {\n" + " highp vec3 L = normalize(lightPos - vert);\n" + " highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n" + " highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n" + " fragColor = vec4(col, 1.0);\n" + "}\n"; + +QByteArray versionedShaderCode(const char *src) +{ + QByteArray versionedSrc; + + if (QOpenGLContext::currentContext()->isOpenGLES()) + versionedSrc.append(QByteArrayLiteral("#version 300 es\n")); + else + versionedSrc.append(QByteArrayLiteral("#version 330\n")); + + versionedSrc.append(src); + return versionedSrc; +} + +void GLWindow::initializeGL() +{ + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + + if (m_texture) { + delete m_texture; + m_texture = 0; + } + QImage img(":/qtlogo.png"); + Q_ASSERT(!img.isNull()); + m_texture = new QOpenGLTexture(img.scaled(32, 36).mirrored()); + + if (m_program) { + delete m_program; + m_program = 0; + } + m_program = new QOpenGLShaderProgram; + // Prepend the correct version directive to the sources. The rest is the + // same, thanks to the common GLSL syntax. + m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, versionedShaderCode(vertexShaderSource)); + m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, versionedShaderCode(fragmentShaderSource)); + m_program->link(); + + m_projMatrixLoc = m_program->uniformLocation("projMatrix"); + m_camMatrixLoc = m_program->uniformLocation("camMatrix"); + m_worldMatrixLoc = m_program->uniformLocation("worldMatrix"); + m_myMatrixLoc = m_program->uniformLocation("myMatrix"); + m_lightPosLoc = m_program->uniformLocation("lightPos"); + + // Create a VAO. Not strictly required for ES 3, but it is for plain OpenGL. + if (m_vao) { + delete m_vao; + m_vao = 0; + } + m_vao = new QOpenGLVertexArrayObject; + if (m_vao->create()) + m_vao->bind(); + + if (m_vbo) { + delete m_vbo; + m_vbo = 0; + } + m_program->bind(); + m_vbo = new QOpenGLBuffer; + m_vbo->create(); + m_vbo->bind(); + m_vbo->allocate(m_logo.constData(), m_logo.count() * sizeof(GLfloat)); + f->glEnableVertexAttribArray(0); + f->glEnableVertexAttribArray(1); + f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0); + f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat))); + m_vbo->release(); + + f->glEnable(GL_DEPTH_TEST); + f->glEnable(GL_CULL_FACE); +} + +void GLWindow::resizeGL(int w, int h) +{ + m_proj.setToIdentity(); + m_proj.perspective(45.0f, GLfloat(w) / h, 0.01f, 100.0f); + m_uniformsDirty = true; +} + +void GLWindow::paintGL() +{ + // Now use QOpenGLExtraFunctions instead of QOpenGLFunctions as we want to + // do more than what GL(ES) 2.0 offers. + QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions(); + + f->glClearColor(0, 0, 0, 1); + f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + m_program->bind(); + m_texture->bind(); + + if (m_uniformsDirty) { + m_uniformsDirty = false; + QMatrix4x4 camera; + camera.lookAt(m_eye, m_eye + m_target, QVector3D(0, 1, 0)); + m_program->setUniformValue(m_projMatrixLoc, m_proj); + m_program->setUniformValue(m_camMatrixLoc, camera); + QMatrix4x4 wm = m_world; + wm.rotate(m_r, 1, 1, 0); + m_program->setUniformValue(m_worldMatrixLoc, wm); + QMatrix4x4 mm; + mm.setToIdentity(); + mm.rotate(-m_r2, 1, 0, 0); + m_program->setUniformValue(m_myMatrixLoc, mm); + m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70)); + } + + // Now call a function introduced in OpenGL 3.1 / OpenGL ES 3.0. We + // requested a 3.3 or ES 3.0 context, so we know this will work. + f->glDrawArraysInstanced(GL_TRIANGLES, 0, m_logo.vertexCount(), 32 * 36); +} diff --git a/examples/widgets/mainwindows/recentfiles/mainwindow.h b/examples/opengl/hellogles3/glwindow.h similarity index 63% rename from examples/widgets/mainwindows/recentfiles/mainwindow.h rename to examples/opengl/hellogles3/glwindow.h index 95252ca52589bf9c553e673d9298a6ed31bb5578..fe5d5383e9847fc2d5d8a3d78475e11a89c93afa 100644 --- a/examples/widgets/mainwindows/recentfiles/mainwindow.h +++ b/examples/opengl/hellogles3/glwindow.h @@ -38,59 +38,61 @@ ** ****************************************************************************/ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H +#ifndef GLWIDGET_H +#define GLWIDGET_H -#include <QList> -#include <QMainWindow> +#include <QOpenGLWindow> +#include <QMatrix4x4> +#include <QVector3D> +#include "../hellogl2/logo.h" -QT_BEGIN_NAMESPACE -class QAction; -class QMenu; -class QTextEdit; -QT_END_NAMESPACE +class QOpenGLTexture; +class QOpenGLShaderProgram; +class QOpenGLBuffer; +class QOpenGLVertexArrayObject; -class MainWindow : public QMainWindow +class GLWindow : public QOpenGLWindow { Q_OBJECT + Q_PROPERTY(float z READ z WRITE setZ) + Q_PROPERTY(float r READ r WRITE setR) + Q_PROPERTY(float r2 READ r2 WRITE setR2) public: - MainWindow(); + GLWindow(); + ~GLWindow(); -private slots: - void newFile(); - void open(); - void save(); - void saveAs(); - void openRecentFile(); - void about(); - -private: - void createActions(); - void createMenus(); - void loadFile(const QString &fileName); - void saveFile(const QString &fileName); - void setCurrentFile(const QString &fileName); - void updateRecentFileActions(); - QString strippedName(const QString &fullFileName); + void initializeGL(); + void resizeGL(int w, int h); + void paintGL(); - QString curFile; + float z() const { return m_eye.z(); } + void setZ(float v); - QTextEdit *textEdit; - QMenu *fileMenu; - QMenu *recentFilesMenu; - QMenu *helpMenu; - QAction *newAct; - QAction *openAct; - QAction *saveAct; - QAction *saveAsAct; - QAction *exitAct; - QAction *aboutAct; - QAction *aboutQtAct; - QAction *separatorAct; - - enum { MaxRecentFiles = 5 }; - QAction *recentFileActs[MaxRecentFiles]; + float r() const { return m_r; } + void setR(float v); + float r2() const { return m_r2; } + void setR2(float v); +private slots: + void startSecondStage(); +private: + QOpenGLTexture *m_texture; + QOpenGLShaderProgram *m_program; + QOpenGLBuffer *m_vbo; + QOpenGLVertexArrayObject *m_vao; + Logo m_logo; + int m_projMatrixLoc; + int m_camMatrixLoc; + int m_worldMatrixLoc; + int m_myMatrixLoc; + int m_lightPosLoc; + QMatrix4x4 m_proj; + QMatrix4x4 m_world; + QVector3D m_eye; + QVector3D m_target; + bool m_uniformsDirty; + float m_r; + float m_r2; }; #endif diff --git a/examples/opengl/hellogles3/hellogles3.pro b/examples/opengl/hellogles3/hellogles3.pro new file mode 100644 index 0000000000000000000000000000000000000000..e0d4c25ca6dd45385b6f0a66cb0d9f3c1f06e6ce --- /dev/null +++ b/examples/opengl/hellogles3/hellogles3.pro @@ -0,0 +1,11 @@ +HEADERS = $$PWD/glwindow.h \ + $$PWD/../hellogl2/logo.h + +SOURCES = $$PWD/glwindow.cpp \ + $$PWD/main.cpp \ + $$PWD/../hellogl2/logo.cpp + +RESOURCES += hellogles3.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/hellogles3 +INSTALLS += target diff --git a/examples/opengl/hellogles3/hellogles3.qrc b/examples/opengl/hellogles3/hellogles3.qrc new file mode 100644 index 0000000000000000000000000000000000000000..f3a09780843359aad7acc9257cdd3875016f9b01 --- /dev/null +++ b/examples/opengl/hellogles3/hellogles3.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource> + <file>qtlogo.png</file> + </qresource> +</RCC> diff --git a/examples/widgets/mainwindows/recentfiles/main.cpp b/examples/opengl/hellogles3/main.cpp similarity index 63% rename from examples/widgets/mainwindows/recentfiles/main.cpp rename to examples/opengl/hellogles3/main.cpp index 23ff3eda160f96e02168006a20031b2f9e1dfbcd..f0de28bdc48018209f4209dbed47b1f91d1086f4 100644 --- a/examples/widgets/mainwindows/recentfiles/main.cpp +++ b/examples/opengl/hellogles3/main.cpp @@ -38,16 +38,41 @@ ** ****************************************************************************/ -#include <QApplication> +#include <QGuiApplication> +#include <QSurfaceFormat> +#include <QOpenGLContext> -#include "mainwindow.h" +#include "glwindow.h" + +// This example demonstrates easy, cross-platform usage of OpenGL ES 3.0 functions via +// QOpenGLExtraFunctions in an application that works identically on desktop platforms +// with OpenGL 3.3 and mobile/embedded devices with OpenGL ES 3.0. + +// The code is always the same, with the exception of two places: (1) the OpenGL context +// creation has to have a sufficiently high version number for the features that are in +// use, and (2) the shader code's version directive is different. int main(int argc, char *argv[]) { - QApplication app(argc, argv); - app.setOrganizationName("QtProject"); - app.setApplicationName("Recent Files Example"); - MainWindow *mainWin = new MainWindow; - mainWin->show(); + QSurfaceFormat fmt; + fmt.setDepthBufferSize(24); + + // Request OpenGL 3.3 compatibility or OpenGL ES 3.0. + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { + qDebug("Requesting 3.3 compatibility context"); + fmt.setVersion(3, 3); + fmt.setProfile(QSurfaceFormat::CompatibilityProfile); + } else { + qDebug("Requesting 3.0 context"); + fmt.setVersion(3, 0); + } + + QSurfaceFormat::setDefaultFormat(fmt); + + QGuiApplication app(argc, argv); + + GLWindow glWindow; + glWindow.showMaximized(); + return app.exec(); } diff --git a/examples/opengl/hellogles3/qtlogo.png b/examples/opengl/hellogles3/qtlogo.png new file mode 100644 index 0000000000000000000000000000000000000000..868fcea860b77bcdf5b22e59950dc3fbbc280492 Binary files /dev/null and b/examples/opengl/hellogles3/qtlogo.png differ diff --git a/examples/opengl/opengl.pro b/examples/opengl/opengl.pro index 7c055d2a8260ce27ea8be63e089c3c60a46cc1d0..ed8134743bcdbe113b7b59e317785ded9704557f 100644 --- a/examples/opengl/opengl.pro +++ b/examples/opengl/opengl.pro @@ -10,7 +10,9 @@ qtHaveModule(widgets) { 2dpainting \ hellogl2 - !wince*: SUBDIRS += qopenglwidget \ - cube \ - textures + !wince: SUBDIRS += \ + qopenglwidget \ + cube \ + textures \ + hellogles3 } diff --git a/examples/qtconcurrent/imagescaling/imagescaling.pro b/examples/qtconcurrent/imagescaling/imagescaling.pro index 52c7dd1b0bf569bcb65aa58580888356dbaed3aa..da237bd6afad3e16b3fe0514671e6d7fbfc3b0e3 100644 --- a/examples/qtconcurrent/imagescaling/imagescaling.pro +++ b/examples/qtconcurrent/imagescaling/imagescaling.pro @@ -6,4 +6,4 @@ HEADERS += imagescaling.h target.path = $$[QT_INSTALL_EXAMPLES]/qtconcurrent/imagescaling INSTALLS += target -wince*: DEPLOYMENT_PLUGIN += qgif qjpeg +wince: DEPLOYMENT_PLUGIN += qgif qjpeg diff --git a/examples/qtconcurrent/map/main.cpp b/examples/qtconcurrent/map/main.cpp index 75b1da4e6f6f54ededac4d27073d9131a1bc2542..eaa7c911cb4bc35ebe9743e7d33ecbb4026c8d15 100644 --- a/examples/qtconcurrent/map/main.cpp +++ b/examples/qtconcurrent/map/main.cpp @@ -64,7 +64,7 @@ int main(int argc, char *argv[]) // Use QtConcurrentBlocking::mapped to apply the scale function to all the // images in the list. - QList<QImage> thumbnails = QtConcurrent::blockingMapped<QList<QImage> >(images, scale); + QList<QImage> thumbnails = QtConcurrent::blockingMapped(images, scale); return 0; } diff --git a/examples/sql/books/books.pro b/examples/sql/books/books.pro index 1cdcaff8705d1b2c2950a5c26493c897e79edd09..c64766c29f3effc037e729a794bf61fdd452db88 100644 --- a/examples/sql/books/books.pro +++ b/examples/sql/books/books.pro @@ -12,7 +12,7 @@ target.path = $$[QT_INSTALL_EXAMPLES]/sql/books INSTALLS += target -wince*: { +wince { CONFIG(debug, debug|release):sqlPlugins.files = $$QT_BUILD_TREE/plugins/sqldrivers/*d4.dll CONFIG(release, debug|release):sqlPlugins.files = $$QT_BUILD_TREE/plugins/sqldrivers/*[^d]4.dll sqlPlugins.path = sqldrivers diff --git a/examples/sql/sql.pro b/examples/sql/sql.pro index eeed18379ec4e62b881323d4a0fc49dfbb502d40..e7bf3e76d935f14c58007d606bf8617e4f0eaadd 100644 --- a/examples/sql/sql.pro +++ b/examples/sql/sql.pro @@ -8,9 +8,9 @@ SUBDIRS = books \ relationaltablemodel \ sqlwidgetmapper -!wince*: SUBDIRS += masterdetail +!wince: SUBDIRS += masterdetail -!wince*: SUBDIRS += \ +!wince: SUBDIRS += \ querymodel \ tablemodel diff --git a/examples/sql/sqlbrowser/sqlbrowser.pro b/examples/sql/sqlbrowser/sqlbrowser.pro index 2983226b8b2afa90f28d90e4e44773f5fd21d52b..539796fe7143a960ff391eebc7454f4c444e0514 100644 --- a/examples/sql/sqlbrowser/sqlbrowser.pro +++ b/examples/sql/sqlbrowser/sqlbrowser.pro @@ -17,6 +17,6 @@ target.path = $$[QT_INSTALL_EXAMPLES]/sql/sqlbrowser INSTALLS += target -wince*: { +wince { DEPLOYMENT_PLUGIN += qsqlite } diff --git a/examples/sql/sqlwidgetmapper/sqlwidgetmapper.pro b/examples/sql/sqlwidgetmapper/sqlwidgetmapper.pro index ae0e59a12bf9efa851cd4a0facaba291c4346a5b..44815407d7594929f9512502b0533630192a8cd7 100644 --- a/examples/sql/sqlwidgetmapper/sqlwidgetmapper.pro +++ b/examples/sql/sqlwidgetmapper/sqlwidgetmapper.pro @@ -7,6 +7,6 @@ QT += sql widgets target.path = $$[QT_INSTALL_EXAMPLES]/sql/sqlwidgetmapper INSTALLS += target -wince*: DEPLOYMENT_PLUGIN += qsqlite +wince: DEPLOYMENT_PLUGIN += qsqlite diff --git a/examples/widgets/dialogs/classwizard/classwizard.cpp b/examples/widgets/dialogs/classwizard/classwizard.cpp index 0f1a2a08693198739df11beb71cef3b8e7a5cb47..c913d7b592256c3d2006fb3df062cd6fd9ffdff9 100644 --- a/examples/widgets/dialogs/classwizard/classwizard.cpp +++ b/examples/widgets/dialogs/classwizard/classwizard.cpp @@ -252,8 +252,8 @@ ClassInfoPage::ClassInfoPage(QWidget *parent) defaultCtorRadioButton->setChecked(true); - connect(defaultCtorRadioButton, SIGNAL(toggled(bool)), - copyCtorCheckBox, SLOT(setEnabled(bool))); + connect(defaultCtorRadioButton, &QAbstractButton::toggled, + copyCtorCheckBox, &QWidget::setEnabled); //! [11] //! [12] registerField("className*", classNameLineEdit); @@ -311,14 +311,14 @@ CodeStylePage::CodeStylePage(QWidget *parent) baseIncludeLineEdit = new QLineEdit; baseIncludeLabel->setBuddy(baseIncludeLineEdit); - connect(protectCheckBox, SIGNAL(toggled(bool)), - macroNameLabel, SLOT(setEnabled(bool))); - connect(protectCheckBox, SIGNAL(toggled(bool)), - macroNameLineEdit, SLOT(setEnabled(bool))); - connect(includeBaseCheckBox, SIGNAL(toggled(bool)), - baseIncludeLabel, SLOT(setEnabled(bool))); - connect(includeBaseCheckBox, SIGNAL(toggled(bool)), - baseIncludeLineEdit, SLOT(setEnabled(bool))); + connect(protectCheckBox, &QAbstractButton::toggled, + macroNameLabel, &QWidget::setEnabled); + connect(protectCheckBox, &QAbstractButton::toggled, + macroNameLineEdit, &QWidget::setEnabled); + connect(includeBaseCheckBox, &QAbstractButton::toggled, + baseIncludeLabel, &QWidget::setEnabled); + connect(includeBaseCheckBox, &QAbstractButton::toggled, + baseIncludeLineEdit, &QWidget::setEnabled); registerField("comment", commentCheckBox); registerField("protect", protectCheckBox); diff --git a/examples/widgets/dialogs/configdialog/configdialog.cpp b/examples/widgets/dialogs/configdialog/configdialog.cpp index 8e689402278bfaf09faa7dead304c8038a910a0d..c4565a64076e0bd337adeb8b5de6c69e6b07d2d0 100644 --- a/examples/widgets/dialogs/configdialog/configdialog.cpp +++ b/examples/widgets/dialogs/configdialog/configdialog.cpp @@ -62,7 +62,7 @@ ConfigDialog::ConfigDialog() createIcons(); contentsWidget->setCurrentRow(0); - connect(closeButton, SIGNAL(clicked()), this, SLOT(close())); + connect(closeButton, &QAbstractButton::clicked, this, &QWidget::close); QHBoxLayout *horizontalLayout = new QHBoxLayout; horizontalLayout->addWidget(contentsWidget); @@ -102,9 +102,7 @@ void ConfigDialog::createIcons() queryButton->setTextAlignment(Qt::AlignHCenter); queryButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - connect(contentsWidget, - SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), - this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*))); + connect(contentsWidget, &QListWidget::currentItemChanged, this, &ConfigDialog::changePage); } void ConfigDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) diff --git a/examples/widgets/dialogs/dialogs.pro b/examples/widgets/dialogs/dialogs.pro index d30c29778f02f38a17bebe16bac3a81068ac0189..7a01e818e0d105b196cd134b84c2925fa178a2f2 100644 --- a/examples/widgets/dialogs/dialogs.pro +++ b/examples/widgets/dialogs/dialogs.pro @@ -5,10 +5,13 @@ SUBDIRS = classwizard \ tabdialog \ trivialwizard -!wince*: SUBDIRS += licensewizard \ - extension \ - findfiles +!wince { + SUBDIRS += \ + licensewizard \ + extension \ + findfiles +} !qtHaveModule(printsupport): SUBDIRS -= licensewizard contains(DEFINES, QT_NO_WIZARD): SUBDIRS -= trivialwizard licensewizard classwizard -wince*: SUBDIRS += sipdialog +wince: SUBDIRS += sipdialog diff --git a/examples/widgets/dialogs/extension/finddialog.cpp b/examples/widgets/dialogs/extension/finddialog.cpp index 19eab195cbcfb38b8a5572937cf55f29fc7f0a84..895b0cf2cedb32d62bf87b4c8c48221da68b90f7 100644 --- a/examples/widgets/dialogs/extension/finddialog.cpp +++ b/examples/widgets/dialogs/extension/finddialog.cpp @@ -78,7 +78,7 @@ FindDialog::FindDialog(QWidget *parent) buttonBox->addButton(findButton, QDialogButtonBox::ActionRole); buttonBox->addButton(moreButton, QDialogButtonBox::ActionRole); - connect(moreButton, SIGNAL(toggled(bool)), extension, SLOT(setVisible(bool))); + connect(moreButton, &QAbstractButton::toggled, extension, &QWidget::setVisible); QVBoxLayout *extensionLayout = new QVBoxLayout; extensionLayout->setMargin(0); diff --git a/examples/widgets/dialogs/findfiles/window.cpp b/examples/widgets/dialogs/findfiles/window.cpp index 86c34a6352264486707edc4f75b8bbb2c5fc4cdb..780c398ad590cc9f0a9bc47d72cb6f7f1fd12cdb 100644 --- a/examples/widgets/dialogs/findfiles/window.cpp +++ b/examples/widgets/dialogs/findfiles/window.cpp @@ -46,8 +46,10 @@ Window::Window(QWidget *parent) : QWidget(parent) { - browseButton = createButton(tr("&Browse..."), SLOT(browse())); - findButton = createButton(tr("&Find"), SLOT(find())); + browseButton = new QPushButton(tr("&Browse..."), this); + connect(browseButton, &QAbstractButton::clicked, this, &Window::browse); + findButton = new QPushButton(tr("&Find"), this); + connect(findButton, &QAbstractButton::clicked, this, &Window::find); fileComboBox = createComboBox(tr("*")); textComboBox = createComboBox(); @@ -195,15 +197,6 @@ void Window::showFiles(const QStringList &files) } //! [8] -//! [9] -QPushButton *Window::createButton(const QString &text, const char *member) -{ - QPushButton *button = new QPushButton(text); - connect(button, SIGNAL(clicked()), this, member); - return button; -} -//! [9] - //! [10] QComboBox *Window::createComboBox(const QString &text) { @@ -228,8 +221,8 @@ void Window::createFilesTable() filesTable->verticalHeader()->hide(); filesTable->setShowGrid(false); - connect(filesTable, SIGNAL(cellActivated(int,int)), - this, SLOT(openFileOfItem(int,int))); + connect(filesTable, &QTableWidget::cellActivated, + this, &Window::openFileOfItem); } //! [11] diff --git a/examples/widgets/dialogs/findfiles/window.h b/examples/widgets/dialogs/findfiles/window.h index 281c932e2fe3edaa2c61413c29833cb93ef20c33..89dd87b83b0a2ccc68831f462994aa0cd8e8fd22 100644 --- a/examples/widgets/dialogs/findfiles/window.h +++ b/examples/widgets/dialogs/findfiles/window.h @@ -68,7 +68,6 @@ private slots: private: QStringList findFiles(const QStringList &files, const QString &text); void showFiles(const QStringList &files); - QPushButton *createButton(const QString &text, const char *member); QComboBox *createComboBox(const QString &text = QString()); void createFilesTable(); diff --git a/examples/widgets/dialogs/licensewizard/licensewizard.cpp b/examples/widgets/dialogs/licensewizard/licensewizard.cpp index ace2e1229a0a8ebb4d7367d33a68974f166f7b99..0f11f3ab7baef8e2873689f55005240c238ae81d 100644 --- a/examples/widgets/dialogs/licensewizard/licensewizard.cpp +++ b/examples/widgets/dialogs/licensewizard/licensewizard.cpp @@ -70,7 +70,7 @@ LicenseWizard::LicenseWizard(QWidget *parent) setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo.png")); //! [7] - connect(this, SIGNAL(helpRequested()), this, SLOT(showHelp())); + connect(this, &QWizard::helpRequested, this, &LicenseWizard::showHelp); //! [7] setWindowTitle(tr("License Wizard")); @@ -339,13 +339,13 @@ void ConclusionPage::setVisible(bool visible) //! [29] wizard()->setButtonText(QWizard::CustomButton1, tr("&Print")); wizard()->setOption(QWizard::HaveCustomButton1, true); - connect(wizard(), SIGNAL(customButtonClicked(int)), - this, SLOT(printButtonClicked())); + connect(wizard(), &QWizard::customButtonClicked, + this, &ConclusionPage::printButtonClicked); //! [29] } else { wizard()->setOption(QWizard::HaveCustomButton1, false); - disconnect(wizard(), SIGNAL(customButtonClicked(int)), - this, SLOT(printButtonClicked())); + disconnect(wizard(), &QWizard::customButtonClicked, + this, &ConclusionPage::printButtonClicked); } } //! [28] diff --git a/examples/widgets/dialogs/sipdialog/dialog.cpp b/examples/widgets/dialogs/sipdialog/dialog.cpp index f57cd094ae6bda86c7f2ecbbd0db5b5b532818e2..48859ec5ffee9e1c664ffb5a6794aab10489275f 100644 --- a/examples/widgets/dialogs/sipdialog/dialog.cpp +++ b/examples/widgets/dialogs/sipdialog/dialog.cpp @@ -89,10 +89,9 @@ Dialog::Dialog() //! [Dialog constructor part4] //! [Dialog constructor part5] - connect(button, SIGNAL(clicked()), - qApp, SLOT(closeAllWindows())); - connect(QApplication::desktop(), SIGNAL(workAreaResized(int)), - this, SLOT(desktopResized(int))); + connect(button, &QAbstractButton::clicked, qApp, &QApplication::closeAllWindows); + connect(QApplication::desktop(), &QDesktopWidget::workAreaResized, + this, &Dialog::desktopResized); } //! [Dialog constructor part5] diff --git a/examples/widgets/dialogs/standarddialogs/dialog.cpp b/examples/widgets/dialogs/standarddialogs/dialog.cpp index 0a1532616c3ea64f48fa5cbd42f8205745fbcca8..560ca77f31021f20709bd4bdbb8a06fffa473f1b 100644 --- a/examples/widgets/dialogs/standarddialogs/dialog.cpp +++ b/examples/widgets/dialogs/standarddialogs/dialog.cpp @@ -180,27 +180,27 @@ Dialog::Dialog(QWidget *parent) QPushButton *errorButton = new QPushButton(tr("QErrorMessage::showM&essage()")); - connect(integerButton, SIGNAL(clicked()), this, SLOT(setInteger())); - connect(doubleButton, SIGNAL(clicked()), this, SLOT(setDouble())); - connect(itemButton, SIGNAL(clicked()), this, SLOT(setItem())); - connect(textButton, SIGNAL(clicked()), this, SLOT(setText())); - connect(multiLineTextButton, SIGNAL(clicked()), this, SLOT(setMultiLineText())); - connect(colorButton, SIGNAL(clicked()), this, SLOT(setColor())); - connect(fontButton, SIGNAL(clicked()), this, SLOT(setFont())); - connect(directoryButton, SIGNAL(clicked()), - this, SLOT(setExistingDirectory())); - connect(openFileNameButton, SIGNAL(clicked()), - this, SLOT(setOpenFileName())); - connect(openFileNamesButton, SIGNAL(clicked()), - this, SLOT(setOpenFileNames())); - connect(saveFileNameButton, SIGNAL(clicked()), - this, SLOT(setSaveFileName())); - connect(criticalButton, SIGNAL(clicked()), this, SLOT(criticalMessage())); - connect(informationButton, SIGNAL(clicked()), - this, SLOT(informationMessage())); - connect(questionButton, SIGNAL(clicked()), this, SLOT(questionMessage())); - connect(warningButton, SIGNAL(clicked()), this, SLOT(warningMessage())); - connect(errorButton, SIGNAL(clicked()), this, SLOT(errorMessage())); + connect(integerButton, &QAbstractButton::clicked, this, &Dialog::setInteger); + connect(doubleButton, &QAbstractButton::clicked, this, &Dialog::setDouble); + connect(itemButton, &QAbstractButton::clicked, this, &Dialog::setItem); + connect(textButton, &QAbstractButton::clicked, this, &Dialog::setText); + connect(multiLineTextButton, &QAbstractButton::clicked, this, &Dialog::setMultiLineText); + connect(colorButton, &QAbstractButton::clicked, this, &Dialog::setColor); + connect(fontButton, &QAbstractButton::clicked, this, &Dialog::setFont); + connect(directoryButton, &QAbstractButton::clicked, + this, &Dialog::setExistingDirectory); + connect(openFileNameButton, &QAbstractButton::clicked, + this, &Dialog::setOpenFileName); + connect(openFileNamesButton, &QAbstractButton::clicked, + this, &Dialog::setOpenFileNames); + connect(saveFileNameButton, &QAbstractButton::clicked, + this, &Dialog::setSaveFileName); + connect(criticalButton, &QAbstractButton::clicked, this, &Dialog::criticalMessage); + connect(informationButton, &QAbstractButton::clicked, + this, &Dialog::informationMessage); + connect(questionButton, &QAbstractButton::clicked, this, &Dialog::questionMessage); + connect(warningButton, &QAbstractButton::clicked, this, &Dialog::warningMessage); + connect(errorButton, &QAbstractButton::clicked, this, &Dialog::errorMessage); QWidget *page = new QWidget; QGridLayout *layout = new QGridLayout(page); diff --git a/examples/widgets/dialogs/tabdialog/tabdialog.cpp b/examples/widgets/dialogs/tabdialog/tabdialog.cpp index ec1a6efbc846f10ed75e3bbbaeb70f6959044e91..75a7b85e3bb75888ac54532798e52ed0cee3f9f4 100644 --- a/examples/widgets/dialogs/tabdialog/tabdialog.cpp +++ b/examples/widgets/dialogs/tabdialog/tabdialog.cpp @@ -59,8 +59,8 @@ TabDialog::TabDialog(const QString &fileName, QWidget *parent) //! [1] //! [3] | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); //! [2] //! [3] //! [4] diff --git a/examples/widgets/doc/src/application.qdoc b/examples/widgets/doc/src/application.qdoc index e20480198a2fdf4c1807a72d39255ab563567cee..cd284ecba0bd569d328950cc0740e0f2e94ec0ad 100644 --- a/examples/widgets/doc/src/application.qdoc +++ b/examples/widgets/doc/src/application.qdoc @@ -50,11 +50,10 @@ To keep the example simple, recently opened files aren't shown in the \uicontrol{File} menu, even though this feature is desired in 90% - of applications. The \l{mainwindows/recentfiles}{Recent Files} - example shows how to implement this. Furthermore, this example - can only load one file at a time. The \l{mainwindows/sdi}{SDI} - and \l{mainwindows/mdi}{MDI} examples shows how to lift these - restrictions. + of applications. Furthermore, this example can only load one file at a + time. The \l{mainwindows/sdi}{SDI} and \l{mainwindows/mdi}{MDI} examples + show how to lift these restrictions and how to implement recently opened files + handling. \section1 MainWindow Class Definition @@ -96,8 +95,7 @@ the widget that occupies the central area of the main window, between the toolbars and the status bar. - Then we call \c createActions(), \c createMenus(), \c - createToolBars(), and \c createStatusBar(), four private + Then we call \c createActions() and \c createStatusBar(), two private functions that set up the user interface. After that, we call \c readSettings() to restore the user's preferences. @@ -184,7 +182,8 @@ \snippet mainwindows/application/mainwindow.cpp 22 The \c createActions() private function, which is called from the - \c MainWindow constructor, creates \l{QAction}s. The code is very + \c MainWindow constructor, creates \l{QAction}s and populates + the menus and two toolbars. The code is very repetitive, so we show only the actions corresponding to \uicontrol{File|New}, \uicontrol{File|Open}, and \uicontrol{Help|About Qt}. @@ -198,13 +197,27 @@ a "What's This?" text, and more. It emits a \l{QAction::triggered()}{triggered()} signal whenever the user invokes the action (e.g., by clicking the associated menu item or - toolbar button). We connect this signal to a slot that performs - the actual action. + toolbar button). + + Instances of QAction can be created by passing a parent QObject or + by using one of the convenience functions of QMenu, QMenuBar or QToolBar. + We create the actions that are in a menu as well as in a toolbar + parented on the window to prevent ownership issues. For actions + that are only in the menu, we use the convenience function + QMenu::addAction(), which allows us to pass text, icon and the + target object and its slot member function. + + Creating toolbars is very similar to creating menus. The same + actions that we put in the menus can be reused in the toolbars. + After creating the action, we add it to the toolbar using + QToolBar::addAction(). The code above contains one more idiom that must be explained. For some of the actions, we specify an icon as a QIcon to the - QAction constructor. The QIcon constructor takes the file name - of an image that it tries to load. Here, the file name starts + QAction constructor. We use QIcon::fromTheme() to obtain + the correct standard icon from the underlying window system. + If that fails due to the platform not supporting it, we + pass a file name as fallback. Here, the file name starts with \c{:}. Such file names aren't ordinary file names, but rather path in the executable's stored resources. We'll come back to this when we review the \c application.qrc file that's part of @@ -219,30 +232,12 @@ the QAction::setEnabled() slot, ensuring that the actions are disabled when the text editor has no selection. - \snippet mainwindows/application/mainwindow.cpp 25 - \snippet mainwindows/application/mainwindow.cpp 27 - - Creating actions isn't sufficient to make them available to the - user; we must also add them to the menu system. This is what \c - createMenus() does. We create a \uicontrol{File}, an \uicontrol{Edit}, and - a \uicontrol{Help} menu. QMainWindow::menuBar() lets us access the - window's menu bar widget. We don't have to worry about creating - the menu bar ourselves; the first time we call this function, the - QMenuBar is created. - Just before we create the \uicontrol{Help} menu, we call QMenuBar::addSeparator(). This has no effect for most widget - styles (e.g., Windows and Mac OS X styles), but for some + styles (e.g., Windows and OS X styles), but for some styles this makes sure that \uicontrol{Help} is pushed to the right side of the menu bar. - Let's now review the toolbars: - - \snippet mainwindows/application/mainwindow.cpp 30 - - Creating toolbars is very similar to creating menus. The same - actions that we put in the menus can be reused in the toolbars. - \snippet mainwindows/application/mainwindow.cpp 32 \snippet mainwindows/application/mainwindow.cpp 33 @@ -258,22 +253,22 @@ load the user's preferences and other application settings. The QSettings class provides a high-level interface for storing settings permanently on disk. On Windows, it uses the (in)famous - Windows registry; on Mac OS X, it uses the native XML-based + Windows registry; on OS X, it uses the native XML-based CFPreferences API; on Unix/X11, it uses text files. The QSettings constructor takes arguments that identify your company and the name of the product. This ensures that the settings for different applications are kept separately. - We use QSettings::value() to extract the value of the "pos" and - "size" settings. The second argument to QSettings::value() is + We use QSettings::value() to extract the value of the geometry setting. + The second argument to QSettings::value() is optional and specifies a default value for the setting if there exists none. This value is used the first time the application is run. - When restoring the position and size of a window, it's important - to call QWidget::resize() before QWidget::move(). The reason why - is given in the \l{Window Geometry} overview. + We use QWidget::saveGeometry() and Widget::restoreGeometry() to + save the position. They use an opaque QByteArray to store + screen number, geometry and window state. \snippet mainwindows/application/mainwindow.cpp 37 \snippet mainwindows/application/mainwindow.cpp 39 @@ -297,9 +292,9 @@ QMessageBox::Escape flag. The \c maybeSave() function returns \c true in all cases, except - when the user clicks \uicontrol{Cancel}. The caller must check the - return value and stop whatever it was doing if the return value - is \c false. + when the user clicks \uicontrol{Cancel} or saving the file fails. + The caller must check the return value and stop whatever it was + doing if the return value is \c false. \snippet mainwindows/application/mainwindow.cpp 42 \snippet mainwindows/application/mainwindow.cpp 43 @@ -310,7 +305,7 @@ We start by opening the file in read-only mode. The QFile::Text flag indicates that the file is a text file, not a binary file. - On Unix and Mac OS X, this makes no difference, but on Windows, + On Unix and OS X, this makes no difference, but on Windows, it ensures that the "\\r\\n" end-of-line sequence is converted to "\\n" when reading. @@ -361,6 +356,10 @@ \snippet mainwindows/application/main.cpp 0 + The main function uses QCommandLineParser to check whether some file + argument was passed to the application and loads it via + MainWindow::loadFile(). + \section1 The Resource File As you will probably recall, for some of the actions, we diff --git a/examples/widgets/doc/src/classwizard.qdoc b/examples/widgets/doc/src/classwizard.qdoc index 98a831da98dfab1d5ba0943e315b6950f571af93..579dcb205534e4d570fffad0414b03568606148b 100644 --- a/examples/widgets/doc/src/classwizard.qdoc +++ b/examples/widgets/doc/src/classwizard.qdoc @@ -76,7 +76,7 @@ \endlist Although the program is just an example, if you press \uicontrol Finish - (\uicontrol Done on Mac OS X), actual C++ source files will actually be + (\uicontrol Done on OS X), actual C++ source files will actually be generated. \section1 The ClassWizard Class @@ -158,7 +158,7 @@ layouts. The \c className field is created with an asterisk (\c *) next to its name. This makes it a \l{mandatory fields}{mandatory field}, that is, a field that must be filled before the user can press the - \uicontrol Next button (\uicontrol Continue on Mac OS X). The fields' values + \uicontrol Next button (\uicontrol Continue on OS X). The fields' values can be accessed from any other page using QWizardPage::field(), or from the wizard code using QWizard::field(). diff --git a/examples/widgets/doc/src/findfiles.qdoc b/examples/widgets/doc/src/findfiles.qdoc index 0a4fb8268dff35ffaee49169304437b2cd72df2f..dd06ed8bb4b30c45b20c97cceea3f0fa2704cf5f 100644 --- a/examples/widgets/doc/src/findfiles.qdoc +++ b/examples/widgets/doc/src/findfiles.qdoc @@ -200,13 +200,6 @@ We also update the total number of files found. - \snippet dialogs/findfiles/window.cpp 9 - - The private \c createButton() function is called from the - constructor. We create a QPushButton with the provided text, - connect it to the provided slot, and return a pointer to the - button. - \snippet dialogs/findfiles/window.cpp 10 The private \c createComboBox() function is also called from the diff --git a/examples/widgets/doc/src/imageviewer.qdoc b/examples/widgets/doc/src/imageviewer.qdoc index 901d6fe76e1925a03a38bb3bf4e2ced68e13e74c..91ae56b5d781840809205ce502f41e4690cfadae 100644 --- a/examples/widgets/doc/src/imageviewer.qdoc +++ b/examples/widgets/doc/src/imageviewer.qdoc @@ -124,10 +124,16 @@ \snippet widgets/imageviewer/imageviewer.cpp 2 - In the \c loadFile() function, we check if the file's - format is an image format by constructing a QImage which tries to - load the image from the file. If the constructor returns a null - image, we use a QMessageBox to alert the user. + In the \c loadFile() function, we instantiate a QImageReader + and enable automatic transformations by calling + QImageReader::setAutoTransform(). For files in JPEG format, + this ensures that portrait mode images of digital cameras are shown + correctly by applying the appropriate orientation read from the + EXIF meta data stored in the image file. + + We then load the image using QImageReader::read(). If this returns + a null image, indicating that the file is not an image file, + we use a QMessageBox to alert the user. The QMessageBox class provides a modal dialog with a short message, an icon, and some buttons. As with QFileDialog the diff --git a/examples/widgets/doc/src/licensewizard.qdoc b/examples/widgets/doc/src/licensewizard.qdoc index 37d67334a12ee7f19b0e29a6d2a8f42e0b3f0605..29e2f2779a1b0ecbd4a761b1a4915d3539fe7cd6 100644 --- a/examples/widgets/doc/src/licensewizard.qdoc +++ b/examples/widgets/doc/src/licensewizard.qdoc @@ -94,7 +94,7 @@ \snippet dialogs/licensewizard/licensewizard.cpp 4 We set the style to \l{QWizard::}{ModernStyle} on all platforms - except Mac OS X, + except OS X, \snippet dialogs/licensewizard/licensewizard.cpp 5 \snippet dialogs/licensewizard/licensewizard.cpp 6 @@ -160,7 +160,7 @@ layouts. The fields are created with an asterisk (\c *) next to their name. This makes them \l{mandatory fields}, that is, fields that must be filled before the user can press the - \uicontrol Next button (\uicontrol Continue on Mac OS X). The fields' values + \uicontrol Next button (\uicontrol Continue on OS X). The fields' values can be accessed from any other page using QWizardPage::field(). Resetting the page amounts to clearing the two text fields. diff --git a/examples/widgets/doc/src/plugandpaint.qdoc b/examples/widgets/doc/src/plugandpaint.qdoc index a1e26272bc9234268053c127e7071bcbb1167282..cf83ea35073954f9e052905bb85b0ef699b95806 100644 --- a/examples/widgets/doc/src/plugandpaint.qdoc +++ b/examples/widgets/doc/src/plugandpaint.qdoc @@ -162,7 +162,7 @@ subdirectory of the Plug & Paint example. On Unix, this is just a matter of initializing the QDir variable with QApplication::applicationDirPath(), the path of the executable - file, and to do a \l{QDir::cd()}{cd()}. On Windows and Mac OS X, + file, and to do a \l{QDir::cd()}{cd()}. On Windows and OS X, this file is usually located in a subdirectory, so we need to take this into account. diff --git a/examples/widgets/doc/src/tablet.qdoc b/examples/widgets/doc/src/tablet.qdoc index 1ab2917b7ec6b0a52fe29eee9a17cf0ea9ba80cd..bc03d46332075b3c8c7da7b98238da373ff629e5 100644 --- a/examples/widgets/doc/src/tablet.qdoc +++ b/examples/widgets/doc/src/tablet.qdoc @@ -259,24 +259,18 @@ \snippet widgets/tablet/tabletcanvas.cpp 5 - In this function we draw on the pixmap based on the movement of the - device. If the device used on the tablet is a stylus we want to draw a - line between the positions of the stylus recorded in \c polyLine. We - also assume that this is a reasonable handling of any unknown device, - but update the statusbar with a warning so that the user can see that - for his tablet he might have to implement special handling. - If it is an airbrush we want to draw a circle of points with a - point density based on the tangential pressure, which is the position - of the finger wheel on the airbrush. We use the Qt::BrushStyle to - draw the points as it has styles that draw points with different - density; we select the style based on the tangential pressure in - \c brushPattern(). + In this function we draw on the pixmap based on the movement of the device. + If the device used on the tablet is a stylus, we want to draw a line from + the last-known position to the current position. We also assume that this + is a reasonable handling of any unknown device, but update the status bar + with a warning. If it is an airbrush, we want to draw a circle filled with + a soft gradient, whose density can depend on various event parameters. + By default it depends on the tangential pressure, which is the position of + the finger wheel on the airbrush. If it is a rotation stylus, we simulate + a felt marker by drawing trapezoidal strokes. \snippet widgets/tablet/tabletcanvas.cpp 6 - We return a brush style with a point density that increases with - the tangential pressure. - In \c updateBrush() we set the pen and brush used for drawing to match \c alphaChannelType, \c lineWidthType, \c colorSaturationType, and \c myColor. We will examine the code to diff --git a/examples/widgets/draganddrop/draganddrop.pro b/examples/widgets/draganddrop/draganddrop.pro index 098651d2f611459f328468e0fb83193106e6eaeb..eb678eecd8750ad419b648ea8445a5dd6a2792a5 100644 --- a/examples/widgets/draganddrop/draganddrop.pro +++ b/examples/widgets/draganddrop/draganddrop.pro @@ -5,4 +5,4 @@ SUBDIRS = draggableicons \ fridgemagnets \ puzzle -wince*: SUBDIRS -= dropsite +wince: SUBDIRS -= dropsite diff --git a/examples/widgets/draganddrop/puzzle/puzzle.pro b/examples/widgets/draganddrop/puzzle/puzzle.pro index b310f1f776ff10b1e6cb64f2f46bdd0bd75ec323..404b75187d43726eff1410ad103e04a2ad1d625e 100644 --- a/examples/widgets/draganddrop/puzzle/puzzle.pro +++ b/examples/widgets/draganddrop/puzzle/puzzle.pro @@ -15,7 +15,7 @@ QMAKE_PROJECT_NAME = dndpuzzle target.path = $$[QT_INSTALL_EXAMPLES]/widgets/draganddrop/puzzle INSTALLS += target -wince*: { +wince { addFile.files = example.jpg addFile.path = . INSTALLS += addFile diff --git a/examples/widgets/gestures/imagegestures/imagewidget.cpp b/examples/widgets/gestures/imagegestures/imagewidget.cpp index 3d0d7e7a93abb62b3985d042eb433b83f17384a9..440eb783c1b9ba390314dde4f6a9bc7982c23cd0 100644 --- a/examples/widgets/gestures/imagegestures/imagewidget.cpp +++ b/examples/widgets/gestures/imagegestures/imagewidget.cpp @@ -202,6 +202,7 @@ QImage ImageWidget::loadImage(const QString &fileName) { qDebug() << position << files << fileName; QImageReader reader(fileName); + reader.setAutoTransform(true); qCDebug(lcExample) << "loading" << QDir::toNativeSeparators(fileName) << position << '/' << files.size(); if (!reader.canRead()) { qCWarning(lcExample) << QDir::toNativeSeparators(fileName) << ": can't load image"; diff --git a/examples/widgets/graphicsview/boxes/boxes.pro b/examples/widgets/graphicsview/boxes/boxes.pro index 15d26f02f07331126125d264379fc228502154c2..38aae1c2c4288857cdcbf44651772e916e62f75f 100644 --- a/examples/widgets/graphicsview/boxes/boxes.pro +++ b/examples/widgets/graphicsview/boxes/boxes.pro @@ -25,6 +25,6 @@ RESOURCES += boxes.qrc target.path = $$[QT_INSTALL_EXAMPLES]/widgets/graphicsview/boxes INSTALLS += target -wince*: { +wince { DEPLOYMENT_PLUGIN += qjpeg } diff --git a/examples/widgets/itemviews/addressbook/adddialog.cpp b/examples/widgets/itemviews/addressbook/adddialog.cpp index de5c7eaf876056ecbe6298fab24518d5e91a7bf0..d153381b56c12f762895b0eb5313620094c8e6f5 100644 --- a/examples/widgets/itemviews/addressbook/adddialog.cpp +++ b/examples/widgets/itemviews/addressbook/adddialog.cpp @@ -72,8 +72,8 @@ AddDialog::AddDialog(QWidget *parent) mainLayout->addLayout(gLayout); setLayout(mainLayout); - connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); + connect(okButton, &QAbstractButton::clicked, this, &QDialog::accept); + connect(cancelButton, &QAbstractButton::clicked, this, &QDialog::reject); setWindowTitle(tr("Add a Contact")); } diff --git a/examples/widgets/itemviews/addressbook/addresswidget.cpp b/examples/widgets/itemviews/addressbook/addresswidget.cpp index 20589a94173a958bb722b396c4ea60796475453d..792d626a4e5117688ab928bc3cb3f74d8928ad8d 100644 --- a/examples/widgets/itemviews/addressbook/addresswidget.cpp +++ b/examples/widgets/itemviews/addressbook/addresswidget.cpp @@ -49,8 +49,8 @@ AddressWidget::AddressWidget(QWidget *parent) { table = new TableModel(this); newAddressTab = new NewAddressTab(this); - connect(newAddressTab, SIGNAL(sendDetails(QString, QString)), - this, SLOT(addEntry(QString, QString))); + connect(newAddressTab, &NewAddressTab::sendDetails, + this, &AddressWidget::addEntry); addTab(newAddressTab, "Address Book"); @@ -59,7 +59,7 @@ AddressWidget::AddressWidget(QWidget *parent) //! [0] //! [2] -void AddressWidget::addEntry() +void AddressWidget::showAddEntryDialog() { AddDialog aDialog; @@ -182,8 +182,8 @@ void AddressWidget::setupTabs() tableView->setSortingEnabled(true); connect(tableView->selectionModel(), - SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - this, SIGNAL(selectionChanged(QItemSelection))); + &QItemSelectionModel::selectionChanged, + this, &AddressWidget::selectionChanged); addTab(tableView, str); } diff --git a/examples/widgets/itemviews/addressbook/addresswidget.h b/examples/widgets/itemviews/addressbook/addresswidget.h index b990c479110593c64441a32751e4c13eedc6aa90..a2fc4bc03bd386d5c7451a43f681bd6296d4eee3 100644 --- a/examples/widgets/itemviews/addressbook/addresswidget.h +++ b/examples/widgets/itemviews/addressbook/addresswidget.h @@ -63,7 +63,7 @@ public: void writeToFile(const QString &fileName); public slots: - void addEntry(); + void showAddEntryDialog(); void addEntry(QString name, QString address); void editEntry(); void removeEntry(); diff --git a/examples/widgets/itemviews/addressbook/mainwindow.cpp b/examples/widgets/itemviews/addressbook/mainwindow.cpp index f729f43604011d517b07100f4eadf23446bf157e..94b38ea2f6aa83480da08af74ac32565eb304603 100644 --- a/examples/widgets/itemviews/addressbook/mainwindow.cpp +++ b/examples/widgets/itemviews/addressbook/mainwindow.cpp @@ -61,40 +61,40 @@ void MainWindow::createMenus() openAct = new QAction(tr("&Open..."), this); fileMenu->addAction(openAct); - connect(openAct, SIGNAL(triggered()), this, SLOT(openFile())); + connect(openAct, &QAction::triggered, this, &MainWindow::openFile); //! [1a] saveAct = new QAction(tr("&Save As..."), this); fileMenu->addAction(saveAct); - connect(saveAct, SIGNAL(triggered()), this, SLOT(saveFile())); + connect(saveAct, &QAction::triggered, this, &MainWindow::saveFile); fileMenu->addSeparator(); exitAct = new QAction(tr("E&xit"), this); fileMenu->addAction(exitAct); - connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); + connect(exitAct, &QAction::triggered, this, &QWidget::close); toolMenu = menuBar()->addMenu(tr("&Tools")); addAct = new QAction(tr("&Add Entry..."), this); toolMenu->addAction(addAct); - connect(addAct, SIGNAL(triggered()), addressWidget, SLOT(addEntry())); + connect(addAct, &QAction::triggered, addressWidget, &AddressWidget::showAddEntryDialog); //! [1b] editAct = new QAction(tr("&Edit Entry..."), this); editAct->setEnabled(false); toolMenu->addAction(editAct); - connect(editAct, SIGNAL(triggered()), addressWidget, SLOT(editEntry())); + connect(editAct, &QAction::triggered, addressWidget, &AddressWidget::editEntry); toolMenu->addSeparator(); removeAct = new QAction(tr("&Remove Entry"), this); removeAct->setEnabled(false); toolMenu->addAction(removeAct); - connect(removeAct, SIGNAL(triggered()), addressWidget, SLOT(removeEntry())); + connect(removeAct, &QAction::triggered, addressWidget, &AddressWidget::removeEntry); - connect(addressWidget, SIGNAL(selectionChanged(QItemSelection)), - this, SLOT(updateActions(QItemSelection))); + connect(addressWidget, &AddressWidget::selectionChanged, + this, &MainWindow::updateActions); } //! [1b] diff --git a/examples/widgets/itemviews/addressbook/newaddresstab.cpp b/examples/widgets/itemviews/addressbook/newaddresstab.cpp index 012a19991c4f1d4f09e826990a5eb07e3fe69290..af66636995e68784cd8470dd599a033cf87d312f 100644 --- a/examples/widgets/itemviews/addressbook/newaddresstab.cpp +++ b/examples/widgets/itemviews/addressbook/newaddresstab.cpp @@ -53,7 +53,7 @@ NewAddressTab::NewAddressTab(QWidget *parent) addButton = new QPushButton(tr("Add")); - connect(addButton, SIGNAL(clicked()), this, SLOT(addEntry())); + connect(addButton, &QAbstractButton::clicked, this, &NewAddressTab::addEntry); mainLayout = new QVBoxLayout; mainLayout->addWidget(descriptionLabel); diff --git a/examples/widgets/itemviews/basicsortfiltermodel/window.cpp b/examples/widgets/itemviews/basicsortfiltermodel/window.cpp index b51846023097395c3f73e59c5f846d998a5fc697..0f5a434bccc13a4f58c5db909b81adee92c96991 100644 --- a/examples/widgets/itemviews/basicsortfiltermodel/window.cpp +++ b/examples/widgets/itemviews/basicsortfiltermodel/window.cpp @@ -77,16 +77,18 @@ Window::Window() filterColumnLabel = new QLabel(tr("Filter &column:")); filterColumnLabel->setBuddy(filterColumnComboBox); - connect(filterPatternLineEdit, SIGNAL(textChanged(QString)), - this, SLOT(filterRegExpChanged())); - connect(filterSyntaxComboBox, SIGNAL(currentIndexChanged(int)), - this, SLOT(filterRegExpChanged())); - connect(filterColumnComboBox, SIGNAL(currentIndexChanged(int)), - this, SLOT(filterColumnChanged())); - connect(filterCaseSensitivityCheckBox, SIGNAL(toggled(bool)), - this, SLOT(filterRegExpChanged())); - connect(sortCaseSensitivityCheckBox, SIGNAL(toggled(bool)), - this, SLOT(sortChanged())); + connect(filterPatternLineEdit, &QLineEdit::textChanged, + this, &Window::filterRegExpChanged); + + typedef void (QComboBox::*QComboIntSignal)(int); + connect(filterSyntaxComboBox, static_cast<QComboIntSignal>(&QComboBox::currentIndexChanged), + this, &Window::filterRegExpChanged); + connect(filterColumnComboBox, static_cast<QComboIntSignal>(&QComboBox::currentIndexChanged), + this, &Window::filterColumnChanged); + connect(filterCaseSensitivityCheckBox, &QAbstractButton::toggled, + this, &Window::filterRegExpChanged); + connect(sortCaseSensitivityCheckBox, &QAbstractButton::toggled, + this, &Window::sortChanged); sourceGroupBox = new QGroupBox(tr("Original Model")); proxyGroupBox = new QGroupBox(tr("Sorted/Filtered Model")); diff --git a/examples/widgets/itemviews/chart/mainwindow.cpp b/examples/widgets/itemviews/chart/mainwindow.cpp index 646b8a293a54e84e0c1292f54d0bf3dbaa66ad4a..9a3b372233e7cb62e6f03ef7e5de4bd059a37b9b 100644 --- a/examples/widgets/itemviews/chart/mainwindow.cpp +++ b/examples/widgets/itemviews/chart/mainwindow.cpp @@ -56,14 +56,14 @@ MainWindow::MainWindow() setupModel(); setupViews(); - connect(openAction, SIGNAL(triggered()), this, SLOT(openFile())); - connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile())); - connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(openAction, &QAction::triggered, this, &MainWindow::openFile); + connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile); + connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit); menuBar()->addMenu(fileMenu); statusBar(); - openFile(":/Charts/qtdata.cht"); + loadFile(":/Charts/qtdata.cht"); setWindowTitle(tr("Chart")); resize(870, 550); @@ -99,17 +99,16 @@ void MainWindow::setupViews() setCentralWidget(splitter); } -void MainWindow::openFile(const QString &path) +void MainWindow::openFile() { - QString fileName; - if (path.isNull()) - fileName = QFileDialog::getOpenFileName(this, tr("Choose a data file"), "", "*.cht"); - else - fileName = path; - - if (fileName.isEmpty()) - return; + const QString fileName = + QFileDialog::getOpenFileName(this, tr("Choose a data file"), "", "*.cht"); + if (!fileName.isEmpty()) + loadFile(fileName); +} +void MainWindow::loadFile(const QString &fileName) +{ QFile file(fileName); if (!file.open(QFile::ReadOnly | QFile::Text)) return; diff --git a/examples/widgets/itemviews/chart/mainwindow.h b/examples/widgets/itemviews/chart/mainwindow.h index 2fc47bb75b392fd5cbb06551f71380bbaeabfcfe..523ad704413d316c2d04986515c1571624ca5a69 100644 --- a/examples/widgets/itemviews/chart/mainwindow.h +++ b/examples/widgets/itemviews/chart/mainwindow.h @@ -57,12 +57,13 @@ public: MainWindow(); private slots: - void openFile(const QString &path = QString()); + void openFile(); void saveFile(); private: void setupModel(); void setupViews(); + void loadFile(const QString &path); QAbstractItemModel *model; QAbstractItemView *pieChart; diff --git a/examples/widgets/itemviews/combowidgetmapper/window.cpp b/examples/widgets/itemviews/combowidgetmapper/window.cpp index d135ffb33f23dca7560e20d13f3b9e9c6a229fd1..3a6f6498569927ce7bcf84e790451d9cca3dfabe 100644 --- a/examples/widgets/itemviews/combowidgetmapper/window.cpp +++ b/examples/widgets/itemviews/combowidgetmapper/window.cpp @@ -72,12 +72,12 @@ Window::Window(QWidget *parent) //! [Set up the mapper] //! [Set up connections and layouts] - connect(previousButton, SIGNAL(clicked()), - mapper, SLOT(toPrevious())); - connect(nextButton, SIGNAL(clicked()), - mapper, SLOT(toNext())); - connect(mapper, SIGNAL(currentIndexChanged(int)), - this, SLOT(updateButtons(int))); + connect(previousButton, &QAbstractButton::clicked, + mapper, &QDataWidgetMapper::toPrevious); + connect(nextButton, &QAbstractButton::clicked, + mapper, &QDataWidgetMapper::toNext); + connect(mapper, &QDataWidgetMapper::currentIndexChanged, + this, &Window::updateButtons); QGridLayout *layout = new QGridLayout(); layout->addWidget(nameLabel, 0, 0, 1, 1); diff --git a/examples/widgets/itemviews/customsortfiltermodel/filterwidget.cpp b/examples/widgets/itemviews/customsortfiltermodel/filterwidget.cpp index 6b5896f3c16de1d04cdb0c8b4dd031b364d1db73..12019e606a7a5e00e128b9787b781ef6fb9819e1 100644 --- a/examples/widgets/itemviews/customsortfiltermodel/filterwidget.cpp +++ b/examples/widgets/itemviews/customsortfiltermodel/filterwidget.cpp @@ -55,12 +55,12 @@ FilterWidget::FilterWidget(QWidget *parent) , m_patternGroup(new QActionGroup(this)) { setClearButtonEnabled(true); - connect(this, SIGNAL(textChanged(QString)), this, SIGNAL(filterChanged())); + connect(this, &QLineEdit::textChanged, this, &FilterWidget::filterChanged); QMenu *menu = new QMenu(this); m_caseSensitivityAction = menu->addAction(tr("Case Sensitive")); m_caseSensitivityAction->setCheckable(true); - connect(m_caseSensitivityAction, SIGNAL(toggled(bool)), this, SIGNAL(filterChanged())); + connect(m_caseSensitivityAction, &QAction::toggled, this, &FilterWidget::filterChanged); menu->addSeparator(); m_patternGroup->setExclusive(true); @@ -77,7 +77,7 @@ FilterWidget::FilterWidget(QWidget *parent) patternAction->setCheckable(true); patternAction->setData(QVariant(int(QRegExp::Wildcard))); m_patternGroup->addAction(patternAction); - connect(m_patternGroup, SIGNAL(triggered(QAction*)), this, SIGNAL(filterChanged())); + connect(m_patternGroup, &QActionGroup::triggered, this, &FilterWidget::filterChanged); const QIcon icon = QIcon(QPixmap(":/images/find.png")); QToolButton *optionsButton = new QToolButton; diff --git a/examples/widgets/itemviews/customsortfiltermodel/window.cpp b/examples/widgets/itemviews/customsortfiltermodel/window.cpp index 8653df2a61c727b3aaee773747e30d0df5b08c4f..ff07dfe79c185a7b4440282e0f8b33e261bd907f 100644 --- a/examples/widgets/itemviews/customsortfiltermodel/window.cpp +++ b/examples/widgets/itemviews/customsortfiltermodel/window.cpp @@ -66,7 +66,7 @@ Window::Window() //! [3] filterWidget = new FilterWidget; filterWidget->setText("Grace|Sports"); - connect(filterWidget, SIGNAL(filterChanged()), this, SLOT(textFilterChanged())); + connect(filterWidget, &FilterWidget::filterChanged, this, &Window::textFilterChanged); filterPatternLabel = new QLabel(tr("&Filter pattern:")); filterPatternLabel->setBuddy(filterWidget); @@ -81,13 +81,13 @@ Window::Window() toLabel = new QLabel(tr("&To:")); toLabel->setBuddy(toDateEdit); - connect(filterWidget, SIGNAL(textChanged(QString)), - this, SLOT(textFilterChanged())); - connect(fromDateEdit, SIGNAL(dateChanged(QDate)), - this, SLOT(dateFilterChanged())); - connect(toDateEdit, SIGNAL(dateChanged(QDate)), + connect(filterWidget, &QLineEdit::textChanged, + this, &Window::textFilterChanged); + connect(fromDateEdit, &QDateTimeEdit::dateChanged, + this, &Window::dateFilterChanged); + connect(toDateEdit, &QDateTimeEdit::dateChanged, //! [3] //! [4] - this, SLOT(dateFilterChanged())); + this, &Window::dateFilterChanged); //! [4] //! [5] diff --git a/examples/widgets/itemviews/editabletreemodel/mainwindow.cpp b/examples/widgets/itemviews/editabletreemodel/mainwindow.cpp index c7abe59c779349c783ce6f7b6ee19dae2253055f..f138e27095db33597902ff10e55997447e719321 100644 --- a/examples/widgets/itemviews/editabletreemodel/mainwindow.cpp +++ b/examples/widgets/itemviews/editabletreemodel/mainwindow.cpp @@ -60,19 +60,17 @@ MainWindow::MainWindow(QWidget *parent) for (int column = 0; column < model->columnCount(); ++column) view->resizeColumnToContents(column); - connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(exitAction, &QAction::triggered, qApp, &QCoreApplication::quit); - connect(view->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection &, - const QItemSelection &)), - this, SLOT(updateActions())); + connect(view->selectionModel(), &QItemSelectionModel::selectionChanged, + this, &MainWindow::updateActions); - connect(actionsMenu, SIGNAL(aboutToShow()), this, SLOT(updateActions())); - connect(insertRowAction, SIGNAL(triggered()), this, SLOT(insertRow())); - connect(insertColumnAction, SIGNAL(triggered()), this, SLOT(insertColumn())); - connect(removeRowAction, SIGNAL(triggered()), this, SLOT(removeRow())); - connect(removeColumnAction, SIGNAL(triggered()), this, SLOT(removeColumn())); - connect(insertChildAction, SIGNAL(triggered()), this, SLOT(insertChild())); + connect(actionsMenu, &QMenu::aboutToShow, this, &MainWindow::updateActions); + connect(insertRowAction, &QAction::triggered, this, &MainWindow::insertRow); + connect(insertColumnAction, &QAction::triggered, this, &MainWindow::insertColumn); + connect(removeRowAction, &QAction::triggered, this, &MainWindow::removeRow); + connect(removeColumnAction, &QAction::triggered, this, &MainWindow::removeColumn); + connect(insertChildAction, &QAction::triggered, this, &MainWindow::insertChild); updateActions(); } @@ -102,13 +100,13 @@ void MainWindow::insertChild() updateActions(); } -bool MainWindow::insertColumn(const QModelIndex &parent) +bool MainWindow::insertColumn() { QAbstractItemModel *model = view->model(); int column = view->selectionModel()->currentIndex().column(); // Insert a column in the parent item. - bool changed = model->insertColumn(column + 1, parent); + bool changed = model->insertColumn(column + 1); if (changed) model->setHeaderData(column + 1, Qt::Horizontal, QVariant("[No header]"), Qt::EditRole); @@ -133,15 +131,15 @@ void MainWindow::insertRow() } } -bool MainWindow::removeColumn(const QModelIndex &parent) +bool MainWindow::removeColumn() { QAbstractItemModel *model = view->model(); int column = view->selectionModel()->currentIndex().column(); // Insert columns in each child of the parent item. - bool changed = model->removeColumn(column, parent); + bool changed = model->removeColumn(column); - if (!parent.isValid() && changed) + if (changed) updateActions(); return changed; diff --git a/examples/widgets/itemviews/editabletreemodel/mainwindow.h b/examples/widgets/itemviews/editabletreemodel/mainwindow.h index 4626ecbc2a1119b492a36e6c42db1061f39c7b8f..4c164f88c1baed0f57f834d0267c43c7a70fa45e 100644 --- a/examples/widgets/itemviews/editabletreemodel/mainwindow.h +++ b/examples/widgets/itemviews/editabletreemodel/mainwindow.h @@ -58,9 +58,9 @@ public slots: private slots: void insertChild(); - bool insertColumn(const QModelIndex &parent = QModelIndex()); + bool insertColumn(); void insertRow(); - bool removeColumn(const QModelIndex &parent = QModelIndex()); + bool removeColumn(); void removeRow(); }; diff --git a/examples/widgets/itemviews/fetchmore/window.cpp b/examples/widgets/itemviews/fetchmore/window.cpp index eefa09622df8d4b05be0b040af7d059efbe34a9d..aa4e0adc90f512522b139072a919411cf7a2b396 100644 --- a/examples/widgets/itemviews/fetchmore/window.cpp +++ b/examples/widgets/itemviews/fetchmore/window.cpp @@ -59,12 +59,12 @@ Window::Window(QWidget *parent) logViewer = new QTextBrowser; logViewer->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); - connect(lineEdit, SIGNAL(textChanged(QString)), - model, SLOT(setDirPath(QString))); - connect(lineEdit, SIGNAL(textChanged(QString)), - logViewer, SLOT(clear())); - connect(model, SIGNAL(numberPopulated(int)), - this, SLOT(updateLog(int))); + connect(lineEdit, &QLineEdit::textChanged, + model, &FileListModel::setDirPath); + connect(lineEdit, &QLineEdit::textChanged, + logViewer, &QTextEdit::clear); + connect(model, &FileListModel::numberPopulated, + this, &Window::updateLog); QGridLayout *layout = new QGridLayout; layout->addWidget(label, 0, 0); diff --git a/examples/widgets/itemviews/frozencolumn/freezetablewidget.cpp b/examples/widgets/itemviews/frozencolumn/freezetablewidget.cpp index 254786b16e22b6bcd875f295d180edd70987bdcc..c2233abcc2147f5cae4bfe82471e5a8b9c81bb82 100644 --- a/examples/widgets/itemviews/frozencolumn/freezetablewidget.cpp +++ b/examples/widgets/itemviews/frozencolumn/freezetablewidget.cpp @@ -52,15 +52,15 @@ FreezeTableWidget::FreezeTableWidget(QAbstractItemModel * model) init(); //connect the headers and scrollbars of both tableviews together - connect(horizontalHeader(),SIGNAL(sectionResized(int,int,int)), this, - SLOT(updateSectionWidth(int,int,int))); - connect(verticalHeader(),SIGNAL(sectionResized(int,int,int)), this, - SLOT(updateSectionHeight(int,int,int))); - - connect(frozenTableView->verticalScrollBar(), SIGNAL(valueChanged(int)), - verticalScrollBar(), SLOT(setValue(int))); - connect(verticalScrollBar(), SIGNAL(valueChanged(int)), - frozenTableView->verticalScrollBar(), SLOT(setValue(int))); + connect(horizontalHeader(),&QHeaderView::sectionResized, this, + &FreezeTableWidget::updateSectionWidth); + connect(verticalHeader(),&QHeaderView::sectionResized, this, + &FreezeTableWidget::updateSectionHeight); + + connect(frozenTableView->verticalScrollBar(), &QAbstractSlider::valueChanged, + verticalScrollBar(), &QAbstractSlider::setValue); + connect(verticalScrollBar(), &QAbstractSlider::valueChanged, + frozenTableView->verticalScrollBar(), &QAbstractSlider::setValue); } diff --git a/examples/widgets/itemviews/pixelator/mainwindow.cpp b/examples/widgets/itemviews/pixelator/mainwindow.cpp index a05880225b2eb9c92aea0debcce2fc9c2571ad68..bab130a2b2452d927142f1d7a940f14a6650b5ad 100644 --- a/examples/widgets/itemviews/pixelator/mainwindow.cpp +++ b/examples/widgets/itemviews/pixelator/mainwindow.cpp @@ -98,15 +98,16 @@ MainWindow::MainWindow() menuBar()->addSeparator(); menuBar()->addMenu(helpMenu); - connect(openAction, SIGNAL(triggered()), this, SLOT(chooseImage())); - connect(printAction, SIGNAL(triggered()), this, SLOT(printImage())); - connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - connect(aboutAction, SIGNAL(triggered()), this, SLOT(showAboutBox())); + connect(openAction, &QAction::triggered, this, &MainWindow::chooseImage); + connect(printAction, &QAction::triggered, this, &MainWindow::printImage); + connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit); + connect(aboutAction, &QAction::triggered, this, &MainWindow::showAboutBox); //! [4] - connect(pixelSizeSpinBox, SIGNAL(valueChanged(int)), - delegate, SLOT(setPixelSize(int))); - connect(pixelSizeSpinBox, SIGNAL(valueChanged(int)), - this, SLOT(updateView())); + typedef void (QSpinBox::*QSpinBoxIntSignal)(int); + connect(pixelSizeSpinBox, static_cast<QSpinBoxIntSignal>(&QSpinBox::valueChanged), + delegate, &PixelDelegate::setPixelSize); + connect(pixelSizeSpinBox, static_cast<QSpinBoxIntSignal>(&QSpinBox::valueChanged), + this, &MainWindow::updateView); //! [4] QHBoxLayout *controlsLayout = new QHBoxLayout; diff --git a/examples/widgets/itemviews/puzzle/main.cpp b/examples/widgets/itemviews/puzzle/main.cpp index 866c6f0d8ba6ecadfecda5206ccabfa379a9db71..a7980489a81e50aa9064024e6306374aa2a2aeea 100644 --- a/examples/widgets/itemviews/puzzle/main.cpp +++ b/examples/widgets/itemviews/puzzle/main.cpp @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); MainWindow window; - window.openImage(":/images/example.jpg"); + window.loadImage(":/images/example.jpg"); window.show(); return app.exec(); } diff --git a/examples/widgets/itemviews/puzzle/mainwindow.cpp b/examples/widgets/itemviews/puzzle/mainwindow.cpp index 2e2a1d0ab5a2849c6f6176821a2371c37f7b4072..5cd9a7f0dfd7bbd35f1c6cb5e945fda859bca558 100644 --- a/examples/widgets/itemviews/puzzle/mainwindow.cpp +++ b/examples/widgets/itemviews/puzzle/mainwindow.cpp @@ -57,26 +57,27 @@ MainWindow::MainWindow(QWidget *parent) setWindowTitle(tr("Puzzle")); } -void MainWindow::openImage(const QString &path) +void MainWindow::openImage() { - QString fileName = path; - - if (fileName.isNull()) { - fileName = QFileDialog::getOpenFileName(this, - tr("Open Image"), "", tr("Image Files (*.png *.jpg *.bmp)")); - } + const QString fileName = + QFileDialog::getOpenFileName(this, + tr("Open Image"), QString(), + tr("Image Files (*.png *.jpg *.bmp)")); + if (!fileName.isEmpty()) + loadImage(fileName); +} - if (!fileName.isEmpty()) { - QPixmap newImage; - if (!newImage.load(fileName)) { - QMessageBox::warning(this, tr("Open Image"), - tr("The image file could not be loaded."), - QMessageBox::Cancel); - return; - } - puzzleImage = newImage; - setupPuzzle(); +void MainWindow::loadImage(const QString &fileName) +{ + QPixmap newImage; + if (!newImage.load(fileName)) { + QMessageBox::warning(this, tr("Open Image"), + tr("The image file could not be loaded."), + QMessageBox::Cancel); + return; } + puzzleImage = newImage; + setupPuzzle(); } void MainWindow::setCompleted() @@ -116,9 +117,9 @@ void MainWindow::setupMenus() QAction *restartAction = gameMenu->addAction(tr("&Restart")); - connect(openAction, SIGNAL(triggered()), this, SLOT(openImage())); - connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - connect(restartAction, SIGNAL(triggered()), this, SLOT(setupPuzzle())); + connect(openAction, &QAction::triggered, this, &MainWindow::openImage); + connect(exitAction, &QAction::triggered, qApp, &QCoreApplication::quit); + connect(restartAction, &QAction::triggered, this, &MainWindow::setupPuzzle); } void MainWindow::setupWidgets() @@ -141,8 +142,8 @@ void MainWindow::setupWidgets() PiecesModel *model = new PiecesModel(puzzleWidget->pieceSize(), this); piecesList->setModel(model); - connect(puzzleWidget, SIGNAL(puzzleCompleted()), - this, SLOT(setCompleted()), Qt::QueuedConnection); + connect(puzzleWidget, &PuzzleWidget::puzzleCompleted, + this, &MainWindow::setCompleted, Qt::QueuedConnection); frameLayout->addWidget(piecesList); frameLayout->addWidget(puzzleWidget); diff --git a/examples/widgets/itemviews/puzzle/mainwindow.h b/examples/widgets/itemviews/puzzle/mainwindow.h index 86daf0af2df9d9d67cf26a3783a067c69ea61914..440dd46377c1033af25dcf8ac638d82bef77d3b2 100644 --- a/examples/widgets/itemviews/puzzle/mainwindow.h +++ b/examples/widgets/itemviews/puzzle/mainwindow.h @@ -58,7 +58,8 @@ public: MainWindow(QWidget *parent = 0); public slots: - void openImage(const QString &path = QString()); + void openImage(); + void loadImage(const QString &path); void setupPuzzle(); private slots: diff --git a/examples/widgets/itemviews/simpledommodel/mainwindow.cpp b/examples/widgets/itemviews/simpledommodel/mainwindow.cpp index 4dc87dac1a1f58a7c4c765b110139b6561c95ee8..c11fb40a0e34853d7fc45da34b639d56cb0478e1 100644 --- a/examples/widgets/itemviews/simpledommodel/mainwindow.cpp +++ b/examples/widgets/itemviews/simpledommodel/mainwindow.cpp @@ -49,8 +49,8 @@ MainWindow::MainWindow() : QMainWindow(), model(0) { fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(tr("&Open..."), this, SLOT(openFile()), QKeySequence::Open); - fileMenu->addAction(tr("E&xit"), this, SLOT(close()), QKeySequence::Quit); + fileMenu->addAction(tr("&Open..."), this, &MainWindow::openFile, QKeySequence::Open); + fileMenu->addAction(tr("E&xit"), this, &QWidget::close, QKeySequence::Quit); model = new DomModel(QDomDocument(), this); view = new QTreeView(this); diff --git a/examples/widgets/itemviews/simplewidgetmapper/window.cpp b/examples/widgets/itemviews/simplewidgetmapper/window.cpp index 9df004430b2f3940e91aa685a99dd332e270d619..0d99acc603d4fdf3354004a565dab3e8c6c3f72e 100644 --- a/examples/widgets/itemviews/simplewidgetmapper/window.cpp +++ b/examples/widgets/itemviews/simplewidgetmapper/window.cpp @@ -69,9 +69,9 @@ Window::Window(QWidget *parent) mapper->addMapping(addressEdit, 1); mapper->addMapping(ageSpinBox, 2); - connect(previousButton, SIGNAL(clicked()), mapper, SLOT(toPrevious())); - connect(nextButton, SIGNAL(clicked()), mapper, SLOT(toNext())); - connect(mapper, SIGNAL(currentIndexChanged(int)), this, SLOT(updateButtons(int))); + connect(previousButton, &QAbstractButton::clicked, mapper, &QDataWidgetMapper::toPrevious); + connect(nextButton, &QAbstractButton::clicked, mapper, &QDataWidgetMapper::toNext); + connect(mapper, &QDataWidgetMapper::currentIndexChanged, this, &Window::updateButtons); //! [Set up the mapper] //! [Set up the layout] diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp b/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp index 02e635b87a7ca3954e65b2667f8b5f8947b4e1fa..41b51c10714c30d0050aa21fe3008a74c0e3ff64 100644 --- a/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp +++ b/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp @@ -73,17 +73,17 @@ SpreadSheet::SpreadSheet(int rows, int cols, QWidget *parent) setCentralWidget(table); statusBar(); - connect(table, SIGNAL(currentItemChanged(QTableWidgetItem*,QTableWidgetItem*)), - this, SLOT(updateStatus(QTableWidgetItem*))); - connect(table, SIGNAL(currentItemChanged(QTableWidgetItem*,QTableWidgetItem*)), - this, SLOT(updateColor(QTableWidgetItem*))); - connect(table, SIGNAL(currentItemChanged(QTableWidgetItem*,QTableWidgetItem*)), - this, SLOT(updateLineEdit(QTableWidgetItem*))); - connect(table, SIGNAL(itemChanged(QTableWidgetItem*)), - this, SLOT(updateStatus(QTableWidgetItem*))); - connect(formulaInput, SIGNAL(returnPressed()), this, SLOT(returnPressed())); - connect(table, SIGNAL(itemChanged(QTableWidgetItem*)), - this, SLOT(updateLineEdit(QTableWidgetItem*))); + connect(table, &QTableWidget::currentItemChanged, + this, &SpreadSheet::updateStatus); + connect(table, &QTableWidget::currentItemChanged, + this, &SpreadSheet::updateColor); + connect(table, &QTableWidget::currentItemChanged, + this, &SpreadSheet::updateLineEdit); + connect(table, &QTableWidget::itemChanged, + this, &SpreadSheet::updateStatus); + connect(formulaInput, &QLineEdit::returnPressed, this, &SpreadSheet::returnPressed); + connect(table, &QTableWidget::itemChanged, + this, &SpreadSheet::updateLineEdit); setWindowTitle(tr("Spreadsheet")); } @@ -91,43 +91,43 @@ SpreadSheet::SpreadSheet(int rows, int cols, QWidget *parent) void SpreadSheet::createActions() { cell_sumAction = new QAction(tr("Sum"), this); - connect(cell_sumAction, SIGNAL(triggered()), this, SLOT(actionSum())); + connect(cell_sumAction, &QAction::triggered, this, &SpreadSheet::actionSum); cell_addAction = new QAction(tr("&Add"), this); cell_addAction->setShortcut(Qt::CTRL | Qt::Key_Plus); - connect(cell_addAction, SIGNAL(triggered()), this, SLOT(actionAdd())); + connect(cell_addAction, &QAction::triggered, this, &SpreadSheet::actionAdd); cell_subAction = new QAction(tr("&Subtract"), this); cell_subAction->setShortcut(Qt::CTRL | Qt::Key_Minus); - connect(cell_subAction, SIGNAL(triggered()), this, SLOT(actionSubtract())); + connect(cell_subAction, &QAction::triggered, this, &SpreadSheet::actionSubtract); cell_mulAction = new QAction(tr("&Multiply"), this); cell_mulAction->setShortcut(Qt::CTRL | Qt::Key_multiply); - connect(cell_mulAction, SIGNAL(triggered()), this, SLOT(actionMultiply())); + connect(cell_mulAction, &QAction::triggered, this, &SpreadSheet::actionMultiply); cell_divAction = new QAction(tr("&Divide"), this); cell_divAction->setShortcut(Qt::CTRL | Qt::Key_division); - connect(cell_divAction, SIGNAL(triggered()), this, SLOT(actionDivide())); + connect(cell_divAction, &QAction::triggered, this, &SpreadSheet::actionDivide); fontAction = new QAction(tr("Font..."), this); fontAction->setShortcut(Qt::CTRL | Qt::Key_F); - connect(fontAction, SIGNAL(triggered()), this, SLOT(selectFont())); + connect(fontAction, &QAction::triggered, this, &SpreadSheet::selectFont); colorAction = new QAction(QPixmap(16, 16), tr("Background &Color..."), this); - connect(colorAction, SIGNAL(triggered()), this, SLOT(selectColor())); + connect(colorAction, &QAction::triggered, this, &SpreadSheet::selectColor); clearAction = new QAction(tr("Clear"), this); clearAction->setShortcut(Qt::Key_Delete); - connect(clearAction, SIGNAL(triggered()), this, SLOT(clear())); + connect(clearAction, &QAction::triggered, this, &SpreadSheet::clear); aboutSpreadSheet = new QAction(tr("About Spreadsheet"), this); - connect(aboutSpreadSheet, SIGNAL(triggered()), this, SLOT(showAbout())); + connect(aboutSpreadSheet, &QAction::triggered, this, &SpreadSheet::showAbout); exitAction = new QAction(tr("E&xit"), this); - connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(exitAction, &QAction::triggered, qApp, &QCoreApplication::quit); printAction = new QAction(tr("&Print"), this); - connect(printAction, SIGNAL(triggered()), this, SLOT(print())); + connect(printAction, &QAction::triggered, this, &SpreadSheet::print); firstSeparator = new QAction(this); firstSeparator->setSeparator(true); @@ -309,11 +309,11 @@ bool SpreadSheet::runInputDialog(const QString &title, outColInput.setCurrentIndex(outCol); QPushButton cancelButton(tr("Cancel"), &addDialog); - connect(&cancelButton, SIGNAL(clicked()), &addDialog, SLOT(reject())); + connect(&cancelButton, &QAbstractButton::clicked, &addDialog, &QDialog::reject); QPushButton okButton(tr("OK"), &addDialog); okButton.setDefault(true); - connect(&okButton, SIGNAL(clicked()), &addDialog, SLOT(accept())); + connect(&okButton, &QAbstractButton::clicked, &addDialog, &QDialog::accept); QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->addStretch(1); @@ -625,7 +625,7 @@ void SpreadSheet::print() QPrintPreviewDialog dlg(&printer); PrintView view; view.setModel(table->model()); - connect(&dlg, SIGNAL(paintRequested(QPrinter*)), &view, SLOT(print(QPrinter*))); + connect(&dlg, &QPrintPreviewDialog::paintRequested, &view, &PrintView::print); dlg.exec(); #endif } diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.cpp b/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.cpp index d056e3f8e41ffa3610e426ce04c889bb52127c52..a7404fe1594510cd4ef0fe820aba984d3e85cbd9 100644 --- a/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.cpp +++ b/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.cpp @@ -63,7 +63,7 @@ QWidget *SpreadSheetDelegate::createEditor(QWidget *parent, QCompleter *autoComplete = new QCompleter(allStrings); editor->setCompleter(autoComplete); - connect(editor, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor())); + connect(editor, &QLineEdit::editingFinished, this, &SpreadSheetDelegate::commitAndCloseEditor); return editor; } diff --git a/examples/widgets/itemviews/stardelegate/stardelegate.cpp b/examples/widgets/itemviews/stardelegate/stardelegate.cpp index 48f6eb543b687a1fd53154d00c73f62d9ec55290..a9e8f716990eb7c8a5afab3df4c8086a2e70582a 100644 --- a/examples/widgets/itemviews/stardelegate/stardelegate.cpp +++ b/examples/widgets/itemviews/stardelegate/stardelegate.cpp @@ -83,8 +83,8 @@ QWidget *StarDelegate::createEditor(QWidget *parent, { if (index.data().canConvert<StarRating>()) { StarEditor *editor = new StarEditor(parent); - connect(editor, SIGNAL(editingFinished()), - this, SLOT(commitAndCloseEditor())); + connect(editor, &StarEditor::editingFinished, + this, &StarDelegate::commitAndCloseEditor); return editor; } else { return QStyledItemDelegate::createEditor(parent, option, index); diff --git a/examples/widgets/mainwindows/application/main.cpp b/examples/widgets/mainwindows/application/main.cpp index 41913db07ebc06e025b62b57b9969b8b64887977..73c1cf57d38ba27bb52e6a92ecd1d72b5712d8ad 100644 --- a/examples/widgets/mainwindows/application/main.cpp +++ b/examples/widgets/mainwindows/application/main.cpp @@ -40,6 +40,8 @@ //! [0] #include <QApplication> +#include <QCommandLineParser> +#include <QCommandLineOption> #include "mainwindow.h" @@ -48,9 +50,19 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(application); QApplication app(argc, argv); - app.setOrganizationName("QtProject"); - app.setApplicationName("Application Example"); + QCoreApplication::setOrganizationName("QtProject"); + QCoreApplication::setApplicationName("Application Example"); + QCoreApplication::setApplicationVersion(QT_VERSION_STR); + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::applicationName()); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("file", "The file to open."); + parser.process(app); + MainWindow mainWin; + if (!parser.positionalArguments().isEmpty()) + mainWin.loadFile(parser.positionalArguments().first()); mainWin.show(); return app.exec(); } diff --git a/examples/widgets/mainwindows/application/mainwindow.cpp b/examples/widgets/mainwindows/application/mainwindow.cpp index d3f9c7645ed7efc206214f712b21ac9e606a9ae1..7a93a0cd22cff38b32afd5fd69d20240afb22c9b 100644 --- a/examples/widgets/mainwindows/application/mainwindow.cpp +++ b/examples/widgets/mainwindows/application/mainwindow.cpp @@ -46,22 +46,20 @@ //! [1] MainWindow::MainWindow() + : textEdit(new QPlainTextEdit) //! [1] //! [2] { - textEdit = new QPlainTextEdit; setCentralWidget(textEdit); createActions(); - createMenus(); - createToolBars(); createStatusBar(); readSettings(); - connect(textEdit->document(), SIGNAL(contentsChanged()), - this, SLOT(documentWasModified())); + connect(textEdit->document(), &QTextDocument::contentsChanged, + this, &MainWindow::documentWasModified); - setCurrentFile(""); + setCurrentFile(QString()); setUnifiedTitleAndToolBarOnMac(true); } //! [2] @@ -85,7 +83,7 @@ void MainWindow::newFile() { if (maybeSave()) { textEdit->clear(); - setCurrentFile(""); + setCurrentFile(QString()); } } //! [6] @@ -121,13 +119,9 @@ bool MainWindow::saveAs() QFileDialog dialog(this); dialog.setWindowModality(Qt::WindowModal); dialog.setAcceptMode(QFileDialog::AcceptSave); - QStringList files; - if (dialog.exec()) - files = dialog.selectedFiles(); - else + if (dialog.exec() != QDialog::Accepted) return false; - - return saveFile(files.at(0)); + return saveFile(dialog.selectedFiles().first()); } //! [12] @@ -154,121 +148,103 @@ void MainWindow::documentWasModified() void MainWindow::createActions() //! [17] //! [18] { - newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); + + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + QToolBar *fileToolBar = addToolBar(tr("File")); + const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png")); + QAction *newAct = new QAction(newIcon, tr("&New"), this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); + connect(newAct, &QAction::triggered, this, &MainWindow::newFile); + fileMenu->addAction(newAct); + fileToolBar->addAction(newAct); //! [19] - openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); + const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/images/open.png")); + QAction *openAct = new QAction(openIcon, tr("&Open..."), this); openAct->setShortcuts(QKeySequence::Open); openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(openAct, &QAction::triggered, this, &MainWindow::open); + fileMenu->addAction(openAct); + fileToolBar->addAction(openAct); //! [18] //! [19] - saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); + const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png")); + QAction *saveAct = new QAction(saveIcon, tr("&Save"), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); + fileMenu->addAction(saveAct); + fileToolBar->addAction(saveAct); - saveAsAct = new QAction(tr("Save &As..."), this); + const QIcon saveAsIcon = QIcon::fromTheme("document-save-as"); + QAction *saveAsAct = fileMenu->addAction(saveAsIcon, tr("Save &As..."), this, &MainWindow::saveAs); saveAsAct->setShortcuts(QKeySequence::SaveAs); saveAsAct->setStatusTip(tr("Save the document under a new name")); - connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); //! [20] - exitAct = new QAction(tr("E&xit"), this); + + fileMenu->addSeparator(); + + const QIcon exitIcon = QIcon::fromTheme("application-exit"); + QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), this, &QWidget::close); exitAct->setShortcuts(QKeySequence::Quit); //! [20] exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); //! [21] - cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this); + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + QToolBar *editToolBar = addToolBar(tr("Edit")); +//! + const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png")); + QAction *cutAct = new QAction(cutIcon, tr("Cu&t"), this); //! [21] cutAct->setShortcuts(QKeySequence::Cut); cutAct->setStatusTip(tr("Cut the current selection's contents to the " "clipboard")); - connect(cutAct, SIGNAL(triggered()), textEdit, SLOT(cut())); + connect(cutAct, &QAction::triggered, textEdit, &QPlainTextEdit::cut); + editMenu->addAction(cutAct); + editToolBar->addAction(cutAct); - copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this); + const QIcon copyIcon = QIcon::fromTheme("edit-copy", QIcon(":/images/copy.png")); + QAction *copyAct = new QAction(copyIcon, tr("&Copy"), this); copyAct->setShortcuts(QKeySequence::Copy); copyAct->setStatusTip(tr("Copy the current selection's contents to the " "clipboard")); - connect(copyAct, SIGNAL(triggered()), textEdit, SLOT(copy())); + connect(copyAct, &QAction::triggered, textEdit, &QPlainTextEdit::copy); + editMenu->addAction(copyAct); + editToolBar->addAction(copyAct); - pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this); + const QIcon pasteIcon = QIcon::fromTheme("edit-paste", QIcon(":/images/paste.png")); + QAction *pasteAct = new QAction(pasteIcon, tr("&Paste"), this); pasteAct->setShortcuts(QKeySequence::Paste); pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " "selection")); - connect(pasteAct, SIGNAL(triggered()), textEdit, SLOT(paste())); + connect(pasteAct, &QAction::triggered, textEdit, &QPlainTextEdit::paste); + editMenu->addAction(pasteAct); + editToolBar->addAction(pasteAct); + + menuBar()->addSeparator(); - aboutAct = new QAction(tr("&About"), this); + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); + QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about); aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); //! [22] - aboutQtAct = new QAction(tr("About &Qt"), this); + + QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); //! [22] //! [23] cutAct->setEnabled(false); //! [23] //! [24] copyAct->setEnabled(false); - connect(textEdit, SIGNAL(copyAvailable(bool)), - cutAct, SLOT(setEnabled(bool))); - connect(textEdit, SIGNAL(copyAvailable(bool)), - copyAct, SLOT(setEnabled(bool))); + connect(textEdit, &QPlainTextEdit::copyAvailable, cutAct, &QAction::setEnabled); + connect(textEdit, &QPlainTextEdit::copyAvailable, copyAct, &QAction::setEnabled); } //! [24] -//! [25] //! [26] -void MainWindow::createMenus() -//! [25] //! [27] -{ - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newAct); -//! [28] - fileMenu->addAction(openAct); -//! [28] - fileMenu->addAction(saveAct); -//! [26] - fileMenu->addAction(saveAsAct); - fileMenu->addSeparator(); - fileMenu->addAction(exitAct); - - editMenu = menuBar()->addMenu(tr("&Edit")); - editMenu->addAction(cutAct); - editMenu->addAction(copyAct); - editMenu->addAction(pasteAct); - - menuBar()->addSeparator(); - - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} -//! [27] - -//! [29] //! [30] -void MainWindow::createToolBars() -{ - fileToolBar = addToolBar(tr("File")); - fileToolBar->addAction(newAct); -//! [29] //! [31] - fileToolBar->addAction(openAct); -//! [31] - fileToolBar->addAction(saveAct); - - editToolBar = addToolBar(tr("Edit")); - editToolBar->addAction(cutAct); - editToolBar->addAction(copyAct); - editToolBar->addAction(pasteAct); -} -//! [30] - //! [32] void MainWindow::createStatusBar() //! [32] //! [33] @@ -281,11 +257,16 @@ void MainWindow::createStatusBar() void MainWindow::readSettings() //! [34] //! [36] { - QSettings settings("QtProject", "Application Example"); - QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); - QSize size = settings.value("size", QSize(400, 400)).toSize(); - resize(size); - move(pos); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray(); + if (geometry.isEmpty()) { + const QRect availableGeometry = QApplication::desktop()->availableGeometry(this); + resize(availableGeometry.width() / 3, availableGeometry.height() / 2); + move((availableGeometry.width() - width()) / 2, + (availableGeometry.height() - height()) / 2); + } else { + restoreGeometry(geometry); + } } //! [35] //! [36] @@ -293,9 +274,8 @@ void MainWindow::readSettings() void MainWindow::writeSettings() //! [37] //! [39] { - QSettings settings("QtProject", "Application Example"); - settings.setValue("pos", pos()); - settings.setValue("size", size()); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + settings.setValue("geometry", saveGeometry()); } //! [38] //! [39] @@ -303,16 +283,20 @@ void MainWindow::writeSettings() bool MainWindow::maybeSave() //! [40] //! [41] { - if (textEdit->document()->isModified()) { - QMessageBox::StandardButton ret; - ret = QMessageBox::warning(this, tr("Application"), - tr("The document has been modified.\n" - "Do you want to save your changes?"), - QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); - if (ret == QMessageBox::Save) - return save(); - else if (ret == QMessageBox::Cancel) - return false; + if (!textEdit->document()->isModified()) + return true; + const QMessageBox::StandardButton ret + = QMessageBox::warning(this, tr("Application"), + tr("The document has been modified.\n" + "Do you want to save your changes?"), + QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + switch (ret) { + case QMessageBox::Save: + return save(); + case QMessageBox::Cancel: + return false; + default: + break; } return true; } @@ -326,8 +310,7 @@ void MainWindow::loadFile(const QString &fileName) if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(this, tr("Application"), tr("Cannot read file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return; } @@ -353,8 +336,8 @@ bool MainWindow::saveFile(const QString &fileName) if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("Application"), tr("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), + file.errorString())); return false; } diff --git a/examples/widgets/mainwindows/application/mainwindow.h b/examples/widgets/mainwindows/application/mainwindow.h index cb791abf004577aa836c21b88fe567eacc447cad..08b4aa17f50a32f1e7fac89aaa077a011b87caf3 100644 --- a/examples/widgets/mainwindows/application/mainwindow.h +++ b/examples/widgets/mainwindows/application/mainwindow.h @@ -57,6 +57,8 @@ class MainWindow : public QMainWindow public: MainWindow(); + void loadFile(const QString &fileName); + protected: void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; @@ -70,35 +72,16 @@ private slots: private: void createActions(); - void createMenus(); - void createToolBars(); void createStatusBar(); void readSettings(); void writeSettings(); bool maybeSave(); - void loadFile(const QString &fileName); bool saveFile(const QString &fileName); void setCurrentFile(const QString &fileName); QString strippedName(const QString &fullFileName); QPlainTextEdit *textEdit; QString curFile; - - QMenu *fileMenu; - QMenu *editMenu; - QMenu *helpMenu; - QToolBar *fileToolBar; - QToolBar *editToolBar; - QAction *newAct; - QAction *openAct; - QAction *saveAct; - QAction *saveAsAct; - QAction *exitAct; - QAction *cutAct; - QAction *copyAct; - QAction *pasteAct; - QAction *aboutAct; - QAction *aboutQtAct; }; //! [0] diff --git a/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp b/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp index 20c2bd1c700ef760cc5a5efb873a63832d2816c2..c0472b537cf3f9f55f6d576f140b8094308a8b74 100644 --- a/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp +++ b/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp @@ -49,13 +49,11 @@ //! [1] MainWindow::MainWindow() + : textEdit(new QTextEdit) { - textEdit = new QTextEdit; setCentralWidget(textEdit); createActions(); - createMenus(); - createToolBars(); createStatusBar(); createDockWindows(); @@ -135,17 +133,17 @@ void MainWindow::print() //! [4] void MainWindow::save() { + QMimeDatabase mimeDatabase; QString fileName = QFileDialog::getSaveFileName(this, tr("Choose a file name"), ".", - tr("HTML (*.html *.htm)")); + mimeDatabase.mimeTypeForName("text/html").filterString()); if (fileName.isEmpty()) return; QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("Dock Widgets"), tr("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return; } @@ -222,71 +220,60 @@ void MainWindow::about() void MainWindow::createActions() { - newLetterAct = new QAction(QIcon(":/images/new.png"), tr("&New Letter"), - this); + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + QToolBar *fileToolBar = addToolBar(tr("File")); + + const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png")); + QAction *newLetterAct = new QAction(newIcon, tr("&New Letter"), this); newLetterAct->setShortcuts(QKeySequence::New); newLetterAct->setStatusTip(tr("Create a new form letter")); - connect(newLetterAct, SIGNAL(triggered()), this, SLOT(newLetter())); + connect(newLetterAct, &QAction::triggered, this, &MainWindow::newLetter); + fileMenu->addAction(newLetterAct); + fileToolBar->addAction(newLetterAct); - saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save..."), this); + const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png")); + QAction *saveAct = new QAction(saveIcon, tr("&Save..."), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the current form letter")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); + fileMenu->addAction(saveAct); + fileToolBar->addAction(saveAct); - printAct = new QAction(QIcon(":/images/print.png"), tr("&Print..."), this); + const QIcon printIcon = QIcon::fromTheme("document-print", QIcon(":/images/print.png")); + QAction *printAct = new QAction(printIcon, tr("&Print..."), this); printAct->setShortcuts(QKeySequence::Print); printAct->setStatusTip(tr("Print the current form letter")); - connect(printAct, SIGNAL(triggered()), this, SLOT(print())); + connect(printAct, &QAction::triggered, this, &MainWindow::print); + fileMenu->addAction(printAct); + fileToolBar->addAction(printAct); - undoAct = new QAction(QIcon(":/images/undo.png"), tr("&Undo"), this); - undoAct->setShortcuts(QKeySequence::Undo); - undoAct->setStatusTip(tr("Undo the last editing action")); - connect(undoAct, SIGNAL(triggered()), this, SLOT(undo())); + fileMenu->addSeparator(); - quitAct = new QAction(tr("&Quit"), this); + QAction *quitAct = fileMenu->addAction(tr("&Quit"), this, &QWidget::close); quitAct->setShortcuts(QKeySequence::Quit); quitAct->setStatusTip(tr("Quit the application")); - connect(quitAct, SIGNAL(triggered()), this, SLOT(close())); - - aboutAct = new QAction(tr("&About"), this); - aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - - aboutQtAct = new QAction(tr("About &Qt"), this); - aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); -} - -void MainWindow::createMenus() -{ - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newLetterAct); - fileMenu->addAction(saveAct); - fileMenu->addAction(printAct); - fileMenu->addSeparator(); - fileMenu->addAction(quitAct); - editMenu = menuBar()->addMenu(tr("&Edit")); + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + QToolBar *editToolBar = addToolBar(tr("Edit")); + const QIcon undoIcon = QIcon::fromTheme("edit-undo", QIcon(":/images/undo.png")); + QAction *undoAct = new QAction(undoIcon, tr("&Undo"), this); + undoAct->setShortcuts(QKeySequence::Undo); + undoAct->setStatusTip(tr("Undo the last editing action")); + connect(undoAct, &QAction::triggered, this, &MainWindow::undo); editMenu->addAction(undoAct); + editToolBar->addAction(undoAct); viewMenu = menuBar()->addMenu(tr("&View")); menuBar()->addSeparator(); - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); -void MainWindow::createToolBars() -{ - fileToolBar = addToolBar(tr("File")); - fileToolBar->addAction(newLetterAct); - fileToolBar->addAction(saveAct); - fileToolBar->addAction(printAct); + QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about); + aboutAct->setStatusTip(tr("Show the application's About box")); - editToolBar = addToolBar(tr("Edit")); - editToolBar->addAction(undoAct); + QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); + aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); } //! [8] @@ -337,9 +324,9 @@ void MainWindow::createDockWindows() addDockWidget(Qt::RightDockWidgetArea, dock); viewMenu->addAction(dock->toggleViewAction()); - connect(customerList, SIGNAL(currentTextChanged(QString)), - this, SLOT(insertCustomer(QString))); - connect(paragraphsList, SIGNAL(currentTextChanged(QString)), - this, SLOT(addParagraph(QString))); + connect(customerList, &QListWidget::currentTextChanged, + this, &MainWindow::insertCustomer); + connect(paragraphsList, &QListWidget::currentTextChanged, + this, &MainWindow::addParagraph); } //! [9] diff --git a/examples/widgets/mainwindows/dockwidgets/mainwindow.h b/examples/widgets/mainwindows/dockwidgets/mainwindow.h index 2fb161a20bf98caee52031f66ce34f9f85453539..c244febf9a976c12cf28509cc319b4c257eba849 100644 --- a/examples/widgets/mainwindows/dockwidgets/mainwindow.h +++ b/examples/widgets/mainwindows/dockwidgets/mainwindow.h @@ -69,8 +69,6 @@ private slots: private: void createActions(); - void createMenus(); - void createToolBars(); void createStatusBar(); void createDockWindows(); @@ -78,19 +76,7 @@ private: QListWidget *customerList; QListWidget *paragraphsList; - QMenu *fileMenu; - QMenu *editMenu; QMenu *viewMenu; - QMenu *helpMenu; - QToolBar *fileToolBar; - QToolBar *editToolBar; - QAction *newLetterAct; - QAction *saveAct; - QAction *printAct; - QAction *undoAct; - QAction *aboutAct; - QAction *aboutQtAct; - QAction *quitAct; }; //! [0] diff --git a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp index 7499389dc30e68a25cfea37278c1a1f4571f2dc4..d746bbe8d3517a6ad6b395226861355c96617068 100644 --- a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp +++ b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp @@ -42,6 +42,7 @@ #include <QImage> #include <QColor> #include <QDialog> +#include <QDialogButtonBox> #include <QGridLayout> #include <QSpinBox> #include <QLabel> @@ -57,15 +58,15 @@ QColor bgColorForName(const QString &name) { if (name == "Black") return QColor("#D8D8D8"); - else if (name == "White") + if (name == "White") return QColor("#F1F1F1"); - else if (name == "Red") + if (name == "Red") return QColor("#F1D8D8"); - else if (name == "Green") + if (name == "Green") return QColor("#D8E4D8"); - else if (name == "Blue") + if (name == "Blue") return QColor("#D8D8F1"); - else if (name == "Yellow") + if (name == "Yellow") return QColor("#F1F0D8"); return QColor(name).light(110); } @@ -74,15 +75,15 @@ QColor fgColorForName(const QString &name) { if (name == "Black") return QColor("#6C6C6C"); - else if (name == "White") + if (name == "White") return QColor("#F8F8F8"); - else if (name == "Red") + if (name == "Red") return QColor("#F86C6C"); - else if (name == "Green") + if (name == "Green") return QColor("#6CB26C"); - else if (name == "Blue") + if (name == "Blue") return QColor("#6C6CF8"); - else if (name == "Yellow") + if (name == "Yellow") return QColor("#F8F76C"); return QColor(name); } @@ -91,10 +92,10 @@ class ColorDock : public QFrame { Q_OBJECT public: - ColorDock(const QString &c, QWidget *parent); + explicit ColorDock(const QString &c, QWidget *parent); - virtual QSize sizeHint() const Q_DECL_OVERRIDE; - virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; + QSize sizeHint() const Q_DECL_OVERRIDE { return szHint; } + QSize minimumSizeHint() const Q_DECL_OVERRIDE { return minSzHint; } void setCustomSizeHint(const QSize &size); @@ -103,28 +104,22 @@ public slots: protected: void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; - QString color; - QSize szHint, minSzHint; + +private: + const QString color; + QSize szHint; + QSize minSzHint; }; ColorDock::ColorDock(const QString &c, QWidget *parent) - : QFrame(parent) , color(c) + : QFrame(parent) + , color(c) + , szHint(-1, -1) + , minSzHint(125, 75) { QFont font = this->font(); font.setPointSize(8); setFont(font); - szHint = QSize(-1, -1); - minSzHint = QSize(125, 75); -} - -QSize ColorDock::sizeHint() const -{ - return szHint; -} - -QSize ColorDock::minimumSizeHint() const -{ - return minSzHint; } void ColorDock::paintEvent(QPaintEvent *) @@ -178,6 +173,7 @@ static QSpinBox *createSpinBox(int value, QWidget *parent, int max = 1000) void ColorDock::changeSizeHints() { QDialog dialog(this); + dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint); dialog.setWindowTitle(color); QVBoxLayout *topLayout = new QVBoxLayout(&dialog); @@ -188,7 +184,7 @@ void ColorDock::changeSizeHints() inputLayout->addWidget(new QLabel(tr("Size Hint:"), &dialog), 0, 0); inputLayout->addWidget(new QLabel(tr("Min Size Hint:"), &dialog), 1, 0); inputLayout->addWidget(new QLabel(tr("Max Size:"), &dialog), 2, 0); - inputLayout->addWidget(new QLabel(tr("Dockwgt Max Size:"), &dialog), 3, 0); + inputLayout->addWidget(new QLabel(tr("Dock Widget Max Size:"), &dialog), 3, 0); QSpinBox *szHintW = createSpinBox(szHint.width(), &dialog); inputLayout->addWidget(szHintW, 0, 1); @@ -217,19 +213,13 @@ void ColorDock::changeSizeHints() topLayout->addStretch(); - QHBoxLayout *buttonBox = new QHBoxLayout(); - topLayout->addLayout(buttonBox); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); + connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::reject); - QPushButton *okButton = new QPushButton(tr("Ok"), &dialog); - QPushButton *cancelButton = new QPushButton(tr("Cancel"), &dialog); - connect(okButton, SIGNAL(clicked()), &dialog, SLOT(accept())); - connect(cancelButton, SIGNAL(clicked()), &dialog, SLOT(reject())); - buttonBox->addStretch(); - buttonBox->addWidget(cancelButton); - buttonBox->addWidget(okButton); + topLayout->addWidget(buttonBox); - - if (!dialog.exec()) + if (dialog.exec() != QDialog::Accepted) return; szHint = QSize(szHintW->value(), szHintH->value()); @@ -244,8 +234,10 @@ void ColorDock::changeSizeHints() void ColorDock::setCustomSizeHint(const QSize &size) { - szHint = size; - updateGeometry(); + if (szHint != size) { + szHint = size; + updateGeometry(); + } } ColorSwatch::ColorSwatch(const QString &colorName, QMainWindow *parent, Qt::WindowFlags flags) @@ -254,53 +246,50 @@ ColorSwatch::ColorSwatch(const QString &colorName, QMainWindow *parent, Qt::Wind setObjectName(colorName + QLatin1String(" Dock Widget")); setWindowTitle(objectName() + QLatin1String(" [*]")); - QFrame *swatch = new ColorDock(colorName, this); + ColorDock *swatch = new ColorDock(colorName, this); swatch->setFrameStyle(QFrame::Box | QFrame::Sunken); setWidget(swatch); - changeSizeHintsAction = new QAction(tr("Change Size Hints"), this); - connect(changeSizeHintsAction, SIGNAL(triggered()), swatch, SLOT(changeSizeHints())); - closableAction = new QAction(tr("Closable"), this); closableAction->setCheckable(true); - connect(closableAction, SIGNAL(triggered(bool)), SLOT(changeClosable(bool))); + connect(closableAction, &QAction::triggered, this, &ColorSwatch::changeClosable); movableAction = new QAction(tr("Movable"), this); movableAction->setCheckable(true); - connect(movableAction, SIGNAL(triggered(bool)), SLOT(changeMovable(bool))); + connect(movableAction, &QAction::triggered, this, &ColorSwatch::changeMovable); floatableAction = new QAction(tr("Floatable"), this); floatableAction->setCheckable(true); - connect(floatableAction, SIGNAL(triggered(bool)), SLOT(changeFloatable(bool))); + connect(floatableAction, &QAction::triggered, this, &ColorSwatch::changeFloatable); verticalTitleBarAction = new QAction(tr("Vertical title bar"), this); verticalTitleBarAction->setCheckable(true); - connect(verticalTitleBarAction, SIGNAL(triggered(bool)), - SLOT(changeVerticalTitleBar(bool))); + connect(verticalTitleBarAction, &QAction::triggered, + this, &ColorSwatch::changeVerticalTitleBar); floatingAction = new QAction(tr("Floating"), this); floatingAction->setCheckable(true); - connect(floatingAction, SIGNAL(triggered(bool)), SLOT(changeFloating(bool))); + connect(floatingAction, &QAction::triggered, this, &ColorSwatch::changeFloating); allowedAreasActions = new QActionGroup(this); allowedAreasActions->setExclusive(false); allowLeftAction = new QAction(tr("Allow on Left"), this); allowLeftAction->setCheckable(true); - connect(allowLeftAction, SIGNAL(triggered(bool)), SLOT(allowLeft(bool))); + connect(allowLeftAction, &QAction::triggered, this, &ColorSwatch::allowLeft); allowRightAction = new QAction(tr("Allow on Right"), this); allowRightAction->setCheckable(true); - connect(allowRightAction, SIGNAL(triggered(bool)), SLOT(allowRight(bool))); + connect(allowRightAction, &QAction::triggered, this, &ColorSwatch::allowRight); allowTopAction = new QAction(tr("Allow on Top"), this); allowTopAction->setCheckable(true); - connect(allowTopAction, SIGNAL(triggered(bool)), SLOT(allowTop(bool))); + connect(allowTopAction, &QAction::triggered, this, &ColorSwatch::allowTop); allowBottomAction = new QAction(tr("Allow on Bottom"), this); allowBottomAction->setCheckable(true); - connect(allowBottomAction, SIGNAL(triggered(bool)), SLOT(allowBottom(bool))); + connect(allowBottomAction, &QAction::triggered, this, &ColorSwatch::allowBottom); allowedAreasActions->addAction(allowLeftAction); allowedAreasActions->addAction(allowRightAction); @@ -312,56 +301,56 @@ ColorSwatch::ColorSwatch(const QString &colorName, QMainWindow *parent, Qt::Wind leftAction = new QAction(tr("Place on Left") , this); leftAction->setCheckable(true); - connect(leftAction, SIGNAL(triggered(bool)), SLOT(placeLeft(bool))); + connect(leftAction, &QAction::triggered, this, &ColorSwatch::placeLeft); rightAction = new QAction(tr("Place on Right") , this); rightAction->setCheckable(true); - connect(rightAction, SIGNAL(triggered(bool)), SLOT(placeRight(bool))); + connect(rightAction, &QAction::triggered, this, &ColorSwatch::placeRight); topAction = new QAction(tr("Place on Top") , this); topAction->setCheckable(true); - connect(topAction, SIGNAL(triggered(bool)), SLOT(placeTop(bool))); + connect(topAction, &QAction::triggered, this, &ColorSwatch::placeTop); bottomAction = new QAction(tr("Place on Bottom") , this); bottomAction->setCheckable(true); - connect(bottomAction, SIGNAL(triggered(bool)), SLOT(placeBottom(bool))); + connect(bottomAction, &QAction::triggered, this, &ColorSwatch::placeBottom); areaActions->addAction(leftAction); areaActions->addAction(rightAction); areaActions->addAction(topAction); areaActions->addAction(bottomAction); - connect(movableAction, SIGNAL(triggered(bool)), areaActions, SLOT(setEnabled(bool))); + connect(movableAction, &QAction::triggered, areaActions, &QActionGroup::setEnabled); - connect(movableAction, SIGNAL(triggered(bool)), allowedAreasActions, SLOT(setEnabled(bool))); + connect(movableAction, &QAction::triggered, allowedAreasActions, &QActionGroup::setEnabled); - connect(floatableAction, SIGNAL(triggered(bool)), floatingAction, SLOT(setEnabled(bool))); + connect(floatableAction, &QAction::triggered, floatingAction, &QAction::setEnabled); - connect(floatingAction, SIGNAL(triggered(bool)), floatableAction, SLOT(setDisabled(bool))); - connect(movableAction, SIGNAL(triggered(bool)), floatableAction, SLOT(setEnabled(bool))); + connect(floatingAction, &QAction::triggered, floatableAction, &QAction::setDisabled); + connect(movableAction, &QAction::triggered, floatableAction, &QAction::setEnabled); tabMenu = new QMenu(this); tabMenu->setTitle(tr("Tab into")); - connect(tabMenu, SIGNAL(triggered(QAction*)), this, SLOT(tabInto(QAction*))); + connect(tabMenu, &QMenu::triggered, this, &ColorSwatch::tabInto); splitHMenu = new QMenu(this); splitHMenu->setTitle(tr("Split horizontally into")); - connect(splitHMenu, SIGNAL(triggered(QAction*)), this, SLOT(splitInto(QAction*))); + connect(splitHMenu, &QMenu::triggered, this, &ColorSwatch::splitInto); splitVMenu = new QMenu(this); splitVMenu->setTitle(tr("Split vertically into")); - connect(splitVMenu, SIGNAL(triggered(QAction*)), this, SLOT(splitInto(QAction*))); + connect(splitVMenu, &QMenu::triggered, this, &ColorSwatch::splitInto); - windowModifiedAction = new QAction(tr("Modified"), this); + QAction *windowModifiedAction = new QAction(tr("Modified"), this); windowModifiedAction->setCheckable(true); windowModifiedAction->setChecked(false); - connect(windowModifiedAction, SIGNAL(toggled(bool)), this, SLOT(setWindowModified(bool))); + connect(windowModifiedAction, &QAction::toggled, this, &QWidget::setWindowModified); menu = new QMenu(colorName, this); menu->addAction(toggleViewAction()); - QAction *action = menu->addAction(tr("Raise")); - connect(action, SIGNAL(triggered()), this, SLOT(raise())); - menu->addAction(changeSizeHintsAction); + menu->addAction(tr("Raise"), this, &QWidget::raise); + menu->addAction(tr("Change Size Hints..."), swatch, &ColorDock::changeSizeHints); + menu->addSeparator(); menu->addAction(closableAction); menu->addAction(movableAction); @@ -379,12 +368,12 @@ ColorSwatch::ColorSwatch(const QString &colorName, QMainWindow *parent, Qt::Wind menu->addSeparator(); menu->addAction(windowModifiedAction); - connect(menu, SIGNAL(aboutToShow()), this, SLOT(updateContextMenu())); + connect(menu, &QMenu::aboutToShow, this, &ColorSwatch::updateContextMenu); - if(colorName == "Black") { - leftAction->setShortcut(Qt::CTRL|Qt::Key_W); - rightAction->setShortcut(Qt::CTRL|Qt::Key_E); - toggleViewAction()->setShortcut(Qt::CTRL|Qt::Key_R); + if (colorName == QLatin1String("Black")) { + leftAction->setShortcut(Qt::CTRL | Qt::Key_W); + rightAction->setShortcut(Qt::CTRL | Qt::Key_E); + toggleViewAction()->setShortcut(Qt::CTRL | Qt::Key_R); } } @@ -447,46 +436,36 @@ void ColorSwatch::updateContextMenu() splitVMenu->clear(); QList<ColorSwatch*> dock_list = mainWindow->findChildren<ColorSwatch*>(); foreach (ColorSwatch *dock, dock_list) { -// if (!dock->isVisible() || dock->isFloating()) -// continue; tabMenu->addAction(dock->objectName()); splitHMenu->addAction(dock->objectName()); splitVMenu->addAction(dock->objectName()); } } -void ColorSwatch::splitInto(QAction *action) +static ColorSwatch *findByName(const QMainWindow *mainWindow, const QString &name) { - QList<ColorSwatch*> dock_list = mainWindow->findChildren<ColorSwatch*>(); - ColorSwatch *target = 0; - foreach (ColorSwatch *dock, dock_list) { - if (action->text() == dock->objectName()) { - target = dock; - break; - } + foreach (ColorSwatch *dock, mainWindow->findChildren<ColorSwatch*>()) { + if (name == dock->objectName()) + return dock; } - if (target == 0) + return Q_NULLPTR; +} + +void ColorSwatch::splitInto(QAction *action) +{ + ColorSwatch *target = findByName(mainWindow, action->text()); + if (!target) return; - Qt::Orientation o = action->parent() == splitHMenu - ? Qt::Horizontal : Qt::Vertical; + const Qt::Orientation o = action->parent() == splitHMenu + ? Qt::Horizontal : Qt::Vertical; mainWindow->splitDockWidget(target, this, o); } void ColorSwatch::tabInto(QAction *action) { - QList<ColorSwatch*> dock_list = mainWindow->findChildren<ColorSwatch*>(); - ColorSwatch *target = 0; - foreach (ColorSwatch *dock, dock_list) { - if (action->text() == dock->objectName()) { - target = dock; - break; - } - } - if (target == 0) - return; - - mainWindow->tabifyDockWidget(target, this); + if (ColorSwatch *target = findByName(mainWindow, action->text())) + mainWindow->tabifyDockWidget(target, this); } void ColorSwatch::contextMenuEvent(QContextMenuEvent *event) @@ -503,7 +482,6 @@ void ColorSwatch::resizeEvent(QResizeEvent *e) QDockWidget::resizeEvent(e); } - void ColorSwatch::allow(Qt::DockWidgetArea area, bool a) { Qt::DockWidgetAreas areas = allowedAreas(); @@ -520,7 +498,8 @@ void ColorSwatch::allow(Qt::DockWidgetArea area, bool a) void ColorSwatch::place(Qt::DockWidgetArea area, bool p) { - if (!p) return; + if (!p) + return; mainWindow->addDockWidget(area, this); @@ -592,10 +571,10 @@ QSize BlueTitleBar::minimumSizeHint() const BlueTitleBar::BlueTitleBar(QWidget *parent) : QWidget(parent) + , leftPm(QPixmap(":/res/titlebarLeft.png")) + , centerPm(QPixmap(":/res/titlebarCenter.png")) + , rightPm(QPixmap(":/res/titlebarRight.png")) { - leftPm = QPixmap(":/res/titlebarLeft.png"); - centerPm = QPixmap(":/res/titlebarCenter.png"); - rightPm = QPixmap(":/res/titlebarRight.png"); } void BlueTitleBar::paintEvent(QPaintEvent*) @@ -683,7 +662,7 @@ void BlueTitleBar::updateMask() { QPainter painter(&bitmap); - ///initialize to transparent + // initialize to transparent painter.fillRect(rect, Qt::color0); QRect contents = rect; @@ -692,10 +671,7 @@ void BlueTitleBar::updateMask() contents.setBottom(contents.bottom()-y()); painter.fillRect(contents, Qt::color1); - - - //let's pait the titlebar - + // let's paint the titlebar QRect titleRect = this->geometry(); if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) { @@ -718,7 +694,6 @@ void BlueTitleBar::updateMask() QRect rect = titleRect; - painter.drawPixmap(rect.topLeft(), leftPm.mask()); painter.fillRect(rect.left() + leftPm.width(), rect.top(), rect.width() - leftPm.width() - rightPm.width(), diff --git a/examples/widgets/mainwindows/mainwindow/colorswatch.h b/examples/widgets/mainwindows/mainwindow/colorswatch.h index 78f267c3202c6b606268c1953105e4c7bd1fbe27..8827a7dca7dbf9daa03d9d703233cb5915b15a19 100644 --- a/examples/widgets/mainwindows/mainwindow/colorswatch.h +++ b/examples/widgets/mainwindows/mainwindow/colorswatch.h @@ -44,47 +44,15 @@ class ColorSwatch : public QDockWidget { Q_OBJECT - QAction *closableAction; - QAction *movableAction; - QAction *floatableAction; - QAction *floatingAction; - QAction *verticalTitleBarAction; - - QActionGroup *allowedAreasActions; - QAction *allowLeftAction; - QAction *allowRightAction; - QAction *allowTopAction; - QAction *allowBottomAction; - - QActionGroup *areaActions; - QAction *leftAction; - QAction *rightAction; - QAction *topAction; - QAction *bottomAction; - - QAction *changeSizeHintsAction; - - QMenu *tabMenu; - QMenu *splitHMenu; - QMenu *splitVMenu; - - QAction *windowModifiedAction; - - QMainWindow *mainWindow; - public: - explicit ColorSwatch(const QString &colorName, QMainWindow *parent = 0, Qt::WindowFlags flags = 0); + explicit ColorSwatch(const QString &colorName, QMainWindow *parent = Q_NULLPTR, Qt::WindowFlags flags = 0); - QMenu *menu; void setCustomSizeHint(const QSize &size); + QMenu *colorSwatchMenu() const { return menu; } protected: - virtual void contextMenuEvent(QContextMenuEvent *event) Q_DECL_OVERRIDE; - virtual void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE; - -private: - void allow(Qt::DockWidgetArea area, bool allow); - void place(Qt::DockWidgetArea area, bool place); + void contextMenuEvent(QContextMenuEvent *event) Q_DECL_OVERRIDE; + void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE; private slots: void changeClosable(bool on); @@ -106,25 +74,57 @@ private slots: void splitInto(QAction *action); void tabInto(QAction *action); + +private: + void allow(Qt::DockWidgetArea area, bool allow); + void place(Qt::DockWidgetArea area, bool place); + + QAction *closableAction; + QAction *movableAction; + QAction *floatableAction; + QAction *floatingAction; + QAction *verticalTitleBarAction; + + QActionGroup *allowedAreasActions; + QAction *allowLeftAction; + QAction *allowRightAction; + QAction *allowTopAction; + QAction *allowBottomAction; + + QActionGroup *areaActions; + QAction *leftAction; + QAction *rightAction; + QAction *topAction; + QAction *bottomAction; + + QMenu *tabMenu; + QMenu *splitHMenu; + QMenu *splitVMenu; + QMenu *menu; + + QMainWindow *mainWindow; }; class BlueTitleBar : public QWidget { Q_OBJECT public: - BlueTitleBar(QWidget *parent = 0); + explicit BlueTitleBar(QWidget *parent = Q_NULLPTR); QSize sizeHint() const Q_DECL_OVERRIDE { return minimumSizeHint(); } QSize minimumSizeHint() const Q_DECL_OVERRIDE; + protected: void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + public slots: void updateMask(); private: - QPixmap leftPm, centerPm, rightPm; + const QPixmap leftPm; + const QPixmap centerPm; + const QPixmap rightPm; }; - -#endif +#endif // COLORSWATCH_H diff --git a/examples/widgets/mainwindows/mainwindow/main.cpp b/examples/widgets/mainwindows/mainwindow/main.cpp index 2192074791058dbca9d4903db8e987db28dca36e..b32b595a2d077b1960bb6e29a3e62c0af6213a22 100644 --- a/examples/widgets/mainwindows/mainwindow/main.cpp +++ b/examples/widgets/mainwindows/mainwindow/main.cpp @@ -37,9 +37,10 @@ #include <QPainterPath> #include <QPainter> #include <QMap> -#include <qdebug.h> +#include <QDebug> -void render_qt_text(QPainter *painter, int w, int h, const QColor &color) { +void render_qt_text(QPainter *painter, int w, int h, const QColor &color) +{ QPainterPath path; path.moveTo(-0.083695, 0.283849); path.cubicTo(-0.049581, 0.349613, -0.012720, 0.397969, 0.026886, 0.428917); @@ -108,47 +109,67 @@ void render_qt_text(QPainter *painter, int w, int h, const QColor &color) { painter->drawPath(path); } -void usage() +static void usage() { qWarning() << "Usage: mainwindow [-SizeHint<color> <width>x<height>] ..."; exit(1); } -QMap<QString, QSize> parseCustomSizeHints(int argc, char **argv) -{ - QMap<QString, QSize> result; - - for (int i = 1; i < argc; ++i) { - QString arg = QString::fromLocal8Bit(argv[i]); +enum ParseCommandLineArgumentsResult { + CommandLineArgumentsOk, + CommandLineArgumentsError, + HelpRequested +}; +static ParseCommandLineArgumentsResult + parseCustomSizeHints(const QStringList &arguments, MainWindow::CustomSizeHintMap *result) +{ + result->clear(); + const int argumentCount = arguments.size(); + for (int i = 1; i < argumentCount; ++i) { + const QString &arg = arguments.at(i); if (arg.startsWith(QLatin1String("-SizeHint"))) { - QString name = arg.mid(9); + const QString name = arg.mid(9); if (name.isEmpty()) - usage(); - if (++i == argc) - usage(); - QString sizeStr = QString::fromLocal8Bit(argv[i]); - int idx = sizeStr.indexOf(QLatin1Char('x')); + return CommandLineArgumentsError; + if (++i == argumentCount) + return CommandLineArgumentsError; + const QString sizeStr = arguments.at(i); + const int idx = sizeStr.indexOf(QLatin1Char('x')); if (idx == -1) - usage(); + return CommandLineArgumentsError; bool ok; - int w = sizeStr.left(idx).toInt(&ok); + const int w = sizeStr.leftRef(idx).toInt(&ok); if (!ok) - usage(); - int h = sizeStr.mid(idx + 1).toInt(&ok); + return CommandLineArgumentsError; + const int h = sizeStr.midRef(idx + 1).toInt(&ok); if (!ok) - usage(); - result[name] = QSize(w, h); + return CommandLineArgumentsError; + result->insert(name, QSize(w, h)); + } else if (arg == QLatin1String("-h") || arg == QLatin1String("--help")) { + return HelpRequested; + } else { + return CommandLineArgumentsError; } } - return result; + return CommandLineArgumentsOk; } int main(int argc, char **argv) { QApplication app(argc, argv); - QMap<QString, QSize> customSizeHints = parseCustomSizeHints(argc, argv); + MainWindow::CustomSizeHintMap customSizeHints; + switch (parseCustomSizeHints(QCoreApplication::arguments(), &customSizeHints)) { + case CommandLineArgumentsOk: + break; + case CommandLineArgumentsError: + usage(); + return -1; + case HelpRequested: + usage(); + return 0; + } MainWindow mainWin(customSizeHints); mainWin.resize(800, 600); mainWin.show(); diff --git a/examples/widgets/mainwindows/mainwindow/mainwindow.cpp b/examples/widgets/mainwindows/mainwindow/mainwindow.cpp index ea557c7aa97e45b9c4f86d84fbf6cf243ba87e5c..91579ae611666dd9fa8aae1aade5f5dd8372b6bf 100644 --- a/examples/widgets/mainwindows/mainwindow/mainwindow.cpp +++ b/examples/widgets/mainwindows/mainwindow/mainwindow.cpp @@ -44,6 +44,7 @@ #include <QFile> #include <QDataStream> #include <QFileDialog> +#include <QDialogButtonBox> #include <QMessageBox> #include <QSignalMapper> #include <QApplication> @@ -53,9 +54,10 @@ #include <QComboBox> #include <QLabel> #include <QPushButton> -#include <qdebug.h> +#include <QTextEdit> +#include <QDebug> -static const char * const message = +static const char message[] = "<p><b>Qt Main Window Example</b></p>" "<p>This is a demonstration of the QMainWindow, QToolBar and " @@ -68,21 +70,21 @@ static const char * const message = "(right-click) menu.</p>" #ifdef Q_OS_MAC - "<p>On Mac OS X, the \"Black\" dock widget has been created as a " + "<p>On OS X, the \"Black\" dock widget has been created as a " "<em>Drawer</em>, which is a special kind of QDockWidget.</p>" #endif ; Q_DECLARE_METATYPE(QDockWidget::DockWidgetFeatures) -MainWindow::MainWindow(const QMap<QString, QSize> &customSizeHints, - QWidget *parent, Qt::WindowFlags flags) +MainWindow::MainWindow(const CustomSizeHintMap &customSizeHints, + QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags) { setObjectName("MainWindow"); setWindowTitle("Qt Main Window Example"); - center = new QTextEdit(this); + QTextEdit *center = new QTextEdit(this); center->setReadOnly(true); center->setMinimumSize(400, 205); setCentralWidget(center); @@ -116,54 +118,48 @@ void MainWindow::setupMenuBar() { QMenu *menu = menuBar()->addMenu(tr("&File")); - QAction *action = menu->addAction(tr("Save layout...")); - connect(action, SIGNAL(triggered()), this, SLOT(saveLayout())); - - action = menu->addAction(tr("Load layout...")); - connect(action, SIGNAL(triggered()), this, SLOT(loadLayout())); - - action = menu->addAction(tr("Switch layout direction")); - connect(action, SIGNAL(triggered()), this, SLOT(switchLayoutDirection())); + menu->addAction(tr("Save layout..."), this, &MainWindow::saveLayout); + menu->addAction(tr("Load layout..."), this, &MainWindow::loadLayout); + menu->addAction(tr("Switch layout direction"),this, &MainWindow::switchLayoutDirection); menu->addSeparator(); - - menu->addAction(tr("&Quit"), this, SLOT(close())); + menu->addAction(tr("&Quit"), this, &QWidget::close); mainWindowMenu = menuBar()->addMenu(tr("Main window")); - action = mainWindowMenu->addAction(tr("Animated docks")); + QAction *action = mainWindowMenu->addAction(tr("Animated docks")); action->setCheckable(true); action->setChecked(dockOptions() & AnimatedDocks); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); action = mainWindowMenu->addAction(tr("Allow nested docks")); action->setCheckable(true); action->setChecked(dockOptions() & AllowNestedDocks); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); action = mainWindowMenu->addAction(tr("Allow tabbed docks")); action->setCheckable(true); action->setChecked(dockOptions() & AllowTabbedDocks); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); action = mainWindowMenu->addAction(tr("Force tabbed docks")); action->setCheckable(true); action->setChecked(dockOptions() & ForceTabbedDocks); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); action = mainWindowMenu->addAction(tr("Vertical tabs")); action->setCheckable(true); action->setChecked(dockOptions() & VerticalTabs); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); action = mainWindowMenu->addAction(tr("Grouped dragging")); action->setCheckable(true); action->setChecked(dockOptions() & GroupedDragging); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); QMenu *toolBarMenu = menuBar()->addMenu(tr("Tool bars")); for (int i = 0; i < toolBars.count(); ++i) - toolBarMenu->addMenu(toolBars.at(i)->menu); + toolBarMenu->addMenu(toolBars.at(i)->toolbarMenu()); #ifdef Q_OS_OSX toolBarMenu->addSeparator(); @@ -171,7 +167,7 @@ void MainWindow::setupMenuBar() action = toolBarMenu->addAction(tr("Unified")); action->setCheckable(true); action->setChecked(unifiedTitleAndToolBarOnMac()); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setUnifiedTitleAndToolBarOnMac(bool))); + connect(action, &QAction::toggled, this, &QMainWindow::setUnifiedTitleAndToolBarOnMac); #endif dockWidgetMenu = menuBar()->addMenu(tr("&Dock Widgets")); @@ -207,8 +203,7 @@ void MainWindow::saveLayout() QFile file(fileName); if (!file.open(QFile::WriteOnly)) { QString msg = tr("Failed to open %1\n%2") - .arg(fileName) - .arg(file.errorString()); + .arg(QDir::toNativeSeparators(fileName), file.errorString()); QMessageBox::warning(this, tr("Error"), msg); return; } @@ -224,8 +219,7 @@ void MainWindow::saveLayout() if (!ok) { QString msg = tr("Error writing to %1\n%2") - .arg(fileName) - .arg(file.errorString()); + .arg(QDir::toNativeSeparators(fileName), file.errorString()); QMessageBox::warning(this, tr("Error"), msg); return; } @@ -240,8 +234,7 @@ void MainWindow::loadLayout() QFile file(fileName); if (!file.open(QFile::ReadOnly)) { QString msg = tr("Failed to open %1\n%2") - .arg(fileName) - .arg(file.errorString()); + .arg(QDir::toNativeSeparators(fileName), file.errorString()); QMessageBox::warning(this, tr("Error"), msg); return; } @@ -266,56 +259,65 @@ void MainWindow::loadLayout() ok = restoreState(layout_data); if (!ok) { - QString msg = tr("Error reading %1") - .arg(fileName); + QString msg = tr("Error reading %1").arg(QDir::toNativeSeparators(fileName)); QMessageBox::warning(this, tr("Error"), msg); return; } } -QAction *addAction(QMenu *menu, const QString &text, QActionGroup *group, QSignalMapper *mapper, - int id) +class DockWidgetAreaCornerFunctor { +public: + explicit DockWidgetAreaCornerFunctor(QMainWindow *mw, Qt::Corner c, Qt::DockWidgetArea a) + : m_mainWindow(mw), m_area(a), m_corner(c) {} + + void operator()() const { m_mainWindow->setCorner(m_corner, m_area); } + +private: + QMainWindow *m_mainWindow; + Qt::DockWidgetArea m_area; + Qt::Corner m_corner; +}; + +static QAction *addCornerAction(const QString &text, QMainWindow *mw, QMenu *menu, QActionGroup *group, + Qt::Corner c, Qt::DockWidgetArea a) { - bool first = group->actions().isEmpty(); - QAction *result = menu->addAction(text); + QAction *result = menu->addAction(text, mw, DockWidgetAreaCornerFunctor(mw, c, a)); result->setCheckable(true); - result->setChecked(first); group->addAction(result); - QObject::connect(result, SIGNAL(triggered()), mapper, SLOT(map())); - mapper->setMapping(result, id); return result; } -void MainWindow::setupDockWidgets(const QMap<QString, QSize> &customSizeHints) +void MainWindow::setupDockWidgets(const CustomSizeHintMap &customSizeHints) { qRegisterMetaType<QDockWidget::DockWidgetFeatures>(); - mapper = new QSignalMapper(this); - connect(mapper, SIGNAL(mapped(int)), this, SLOT(setCorner(int))); - - QMenu *corner_menu = dockWidgetMenu->addMenu(tr("Top left corner")); + QMenu *cornerMenu = dockWidgetMenu->addMenu(tr("Top left corner")); QActionGroup *group = new QActionGroup(this); group->setExclusive(true); - ::addAction(corner_menu, tr("Top dock area"), group, mapper, 0); - ::addAction(corner_menu, tr("Left dock area"), group, mapper, 1); + QAction *cornerAction = addCornerAction(tr("Top dock area"), this, cornerMenu, group, Qt::TopLeftCorner, Qt::TopDockWidgetArea); + cornerAction->setChecked(true); + addCornerAction(tr("Left dock area"), this, cornerMenu, group, Qt::TopLeftCorner, Qt::LeftDockWidgetArea); - corner_menu = dockWidgetMenu->addMenu(tr("Top right corner")); + cornerMenu = dockWidgetMenu->addMenu(tr("Top right corner")); group = new QActionGroup(this); group->setExclusive(true); - ::addAction(corner_menu, tr("Top dock area"), group, mapper, 2); - ::addAction(corner_menu, tr("Right dock area"), group, mapper, 3); + cornerAction = addCornerAction(tr("Top dock area"), this, cornerMenu, group, Qt::TopRightCorner, Qt::TopDockWidgetArea); + cornerAction->setChecked(true); + addCornerAction(tr("Right dock area"), this, cornerMenu, group, Qt::TopRightCorner, Qt::RightDockWidgetArea); - corner_menu = dockWidgetMenu->addMenu(tr("Bottom left corner")); + cornerMenu = dockWidgetMenu->addMenu(tr("Bottom left corner")); group = new QActionGroup(this); group->setExclusive(true); - ::addAction(corner_menu, tr("Bottom dock area"), group, mapper, 4); - ::addAction(corner_menu, tr("Left dock area"), group, mapper, 5); + cornerAction = addCornerAction(tr("Bottom dock area"), this, cornerMenu, group, Qt::BottomLeftCorner, Qt::BottomDockWidgetArea); + cornerAction->setChecked(true); + addCornerAction(tr("Left dock area"), this, cornerMenu, group, Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); - corner_menu = dockWidgetMenu->addMenu(tr("Bottom right corner")); + cornerMenu = dockWidgetMenu->addMenu(tr("Bottom right corner")); group = new QActionGroup(this); group->setExclusive(true); - ::addAction(corner_menu, tr("Bottom dock area"), group, mapper, 6); - ::addAction(corner_menu, tr("Right dock area"), group, mapper, 7); + cornerAction = addCornerAction(tr("Bottom dock area"), this, cornerMenu, group, Qt::BottomRightCorner, Qt::BottomDockWidgetArea); + cornerAction->setChecked(true); + addCornerAction(tr("Right dock area"), this, cornerMenu, group, Qt::BottomRightCorner, Qt::RightDockWidgetArea); dockWidgetMenu->addSeparator(); @@ -337,16 +339,16 @@ void MainWindow::setupDockWidgets(const QMap<QString, QSize> &customSizeHints) }; const int setCount = sizeof(sets) / sizeof(Set); + const QIcon qtIcon(QPixmap(":/res/qt.png")); for (int i = 0; i < setCount; ++i) { ColorSwatch *swatch = new ColorSwatch(tr(sets[i].name), this, Qt::WindowFlags(sets[i].flags)); - if (i%2) - swatch->setWindowIcon(QIcon(QPixmap(":/res/qt.png"))); + if (i % 2) + swatch->setWindowIcon(qtIcon); if (qstrcmp(sets[i].name, "Blue") == 0) { BlueTitleBar *titlebar = new BlueTitleBar(swatch); swatch->setTitleBarWidget(titlebar); - connect(swatch, SIGNAL(topLevelChanged(bool)), titlebar, SLOT(updateMask())); - connect(swatch, SIGNAL(featuresChanged(QDockWidget::DockWidgetFeatures)), titlebar, SLOT(updateMask()), Qt::QueuedConnection); - + connect(swatch, &QDockWidget::topLevelChanged, titlebar, &BlueTitleBar::updateMask); + connect(swatch, &QDockWidget::featuresChanged, titlebar, &BlueTitleBar::updateMask, Qt::QueuedConnection); } QString name = QString::fromLatin1(sets[i].name); @@ -354,69 +356,32 @@ void MainWindow::setupDockWidgets(const QMap<QString, QSize> &customSizeHints) swatch->setCustomSizeHint(customSizeHints.value(name)); addDockWidget(sets[i].area, swatch); - dockWidgetMenu->addMenu(swatch->menu); + dockWidgetMenu->addMenu(swatch->colorSwatchMenu()); } - createDockWidgetAction = new QAction(tr("Add dock widget..."), this); - connect(createDockWidgetAction, SIGNAL(triggered()), this, SLOT(createDockWidget())); destroyDockWidgetMenu = new QMenu(tr("Destroy dock widget"), this); destroyDockWidgetMenu->setEnabled(false); - connect(destroyDockWidgetMenu, SIGNAL(triggered(QAction*)), this, SLOT(destroyDockWidget(QAction*))); + connect(destroyDockWidgetMenu, &QMenu::triggered, this, &MainWindow::destroyDockWidget); dockWidgetMenu->addSeparator(); - dockWidgetMenu->addAction(createDockWidgetAction); + dockWidgetMenu->addAction(tr("Add dock widget..."), this, &MainWindow::createDockWidget); dockWidgetMenu->addMenu(destroyDockWidgetMenu); } -void MainWindow::setCorner(int id) -{ - switch (id) { - case 0: - QMainWindow::setCorner(Qt::TopLeftCorner, Qt::TopDockWidgetArea); - break; - case 1: - QMainWindow::setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); - break; - case 2: - QMainWindow::setCorner(Qt::TopRightCorner, Qt::TopDockWidgetArea); - break; - case 3: - QMainWindow::setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); - break; - case 4: - QMainWindow::setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea); - break; - case 5: - QMainWindow::setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); - break; - case 6: - QMainWindow::setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea); - break; - case 7: - QMainWindow::setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); - break; - } -} - -void MainWindow::showEvent(QShowEvent *event) -{ - QMainWindow::showEvent(event); -} - void MainWindow::switchLayoutDirection() { if (layoutDirection() == Qt::LeftToRight) - qApp->setLayoutDirection(Qt::RightToLeft); + QApplication::setLayoutDirection(Qt::RightToLeft); else - qApp->setLayoutDirection(Qt::LeftToRight); + QApplication::setLayoutDirection(Qt::LeftToRight); } class CreateDockWidgetDialog : public QDialog { public: - CreateDockWidgetDialog(QWidget *parent = 0); + explicit CreateDockWidgetDialog(QWidget *parent = Q_NULLPTR); - QString objectName() const; + QString enteredObjectName() const { return m_objectName->text(); } Qt::DockWidgetArea location() const; private: @@ -426,15 +391,17 @@ private: CreateDockWidgetDialog::CreateDockWidgetDialog(QWidget *parent) : QDialog(parent) + , m_objectName(new QLineEdit(this)) + , m_location(new QComboBox(this)) { + setWindowTitle(tr("Add Dock Widget")); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); QGridLayout *layout = new QGridLayout(this); layout->addWidget(new QLabel(tr("Object name:")), 0, 0); - m_objectName = new QLineEdit; layout->addWidget(m_objectName, 0, 1); layout->addWidget(new QLabel(tr("Location:")), 1, 0); - m_location = new QComboBox; m_location->setEditable(false); m_location->addItem(tr("Top")); m_location->addItem(tr("Left")); @@ -443,23 +410,10 @@ CreateDockWidgetDialog::CreateDockWidgetDialog(QWidget *parent) m_location->addItem(tr("Restore")); layout->addWidget(m_location, 1, 1); - QHBoxLayout *buttonLayout = new QHBoxLayout; - layout->addLayout(buttonLayout, 2, 0, 1, 2); - buttonLayout->addStretch(); - - QPushButton *cancelButton = new QPushButton(tr("Cancel")); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); - buttonLayout->addWidget(cancelButton); - QPushButton *okButton = new QPushButton(tr("Ok")); - connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); - buttonLayout->addWidget(okButton); - - okButton->setDefault(true); -} - -QString CreateDockWidgetDialog::objectName() const -{ - return m_objectName->text(); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::reject); + layout->addWidget(buttonBox, 2, 0, 1, 2); } Qt::DockWidgetArea CreateDockWidgetDialog::location() const @@ -478,13 +432,13 @@ Qt::DockWidgetArea CreateDockWidgetDialog::location() const void MainWindow::createDockWidget() { CreateDockWidgetDialog dialog(this); - int ret = dialog.exec(); - if (ret == QDialog::Rejected) + if (dialog.exec() == QDialog::Rejected) return; QDockWidget *dw = new QDockWidget; - dw->setObjectName(dialog.objectName()); - dw->setWindowTitle(dialog.objectName()); + const QString name = dialog.enteredObjectName(); + dw->setObjectName(name); + dw->setWindowTitle(name); dw->setWidget(new QTextEdit); Qt::DockWidgetArea area = dialog.location(); @@ -506,7 +460,7 @@ void MainWindow::createDockWidget() extraDockWidgets.append(dw); destroyDockWidgetMenu->setEnabled(true); - destroyDockWidgetMenu->addAction(new QAction(dialog.objectName(), this)); + destroyDockWidgetMenu->addAction(new QAction(name, this)); } void MainWindow::destroyDockWidget(QAction *action) diff --git a/examples/widgets/mainwindows/mainwindow/mainwindow.h b/examples/widgets/mainwindows/mainwindow/mainwindow.h index f9a6176b2dcc54fea0c4461e4b1bc232b0d056be..162e977520d9678b70cc869d64e04ba2c88536cc 100644 --- a/examples/widgets/mainwindows/mainwindow/mainwindow.h +++ b/examples/widgets/mainwindows/mainwindow/mainwindow.h @@ -35,37 +35,25 @@ #define MAINWINDOW_H #include <QMainWindow> -#include <QTextEdit> class ToolBar; QT_FORWARD_DECLARE_CLASS(QMenu) -QT_FORWARD_DECLARE_CLASS(QSignalMapper) class MainWindow : public QMainWindow { Q_OBJECT - QTextEdit *center; - QList<ToolBar*> toolBars; - QMenu *dockWidgetMenu; - QMenu *mainWindowMenu; - QSignalMapper *mapper; - QList<QDockWidget*> extraDockWidgets; - QAction *createDockWidgetAction; - QMenu *destroyDockWidgetMenu; - public: - MainWindow(const QMap<QString, QSize> &customSizeHints, - QWidget *parent = 0, Qt::WindowFlags flags = 0); + typedef QMap<QString, QSize> CustomSizeHintMap; -protected: - void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; + explicit MainWindow(const CustomSizeHintMap &customSizeHints, + QWidget *parent = Q_NULLPTR, + Qt::WindowFlags flags = 0); public slots: void actionTriggered(QAction *action); void saveLayout(); void loadLayout(); - void setCorner(int id); void switchLayoutDirection(); void setDockOptions(); @@ -75,8 +63,13 @@ public slots: private: void setupToolBar(); void setupMenuBar(); - void setupDockWidgets(const QMap<QString, QSize> &customSizeHints); -}; + void setupDockWidgets(const CustomSizeHintMap &customSizeHints); + QList<ToolBar*> toolBars; + QMenu *dockWidgetMenu; + QMenu *mainWindowMenu; + QList<QDockWidget *> extraDockWidgets; + QMenu *destroyDockWidgetMenu; +}; -#endif +#endif // MAINWINDOW_H diff --git a/examples/widgets/mainwindows/mainwindow/toolbar.cpp b/examples/widgets/mainwindows/mainwindow/toolbar.cpp index 280ba965d613cb85af66e2074ca2297a6287512c..a9b308370a4b3e69c4d6f2508a871e6552876295 100644 --- a/examples/widgets/mainwindows/mainwindow/toolbar.cpp +++ b/examples/widgets/mainwindows/mainwindow/toolbar.cpp @@ -63,15 +63,15 @@ static QPixmap genIcon(const QSize &iconSize, int number, const QColor &color) { return genIcon(iconSize, QString::number(number), color); } ToolBar::ToolBar(const QString &title, QWidget *parent) - : QToolBar(parent), spinbox(0), spinboxAction(0) + : QToolBar(parent) + , spinbox(Q_NULLPTR) + , spinboxAction(Q_NULLPTR) { - tip = 0; setWindowTitle(title); setObjectName(title); setIconSize(QSize(32, 32)); - QColor bg(palette().background().color()); menu = new QMenu("One", this); menu->setIcon(genIcon(iconSize(), 1, Qt::black)); menu->addAction(genIcon(iconSize(), "A", Qt::blue), "A"); @@ -90,43 +90,43 @@ ToolBar::ToolBar(const QString &title, QWidget *parent) addAction(genIcon(iconSize(), 6, Qt::yellow), "Six"); orderAction = new QAction(this); orderAction->setText(tr("Order Items in Tool Bar")); - connect(orderAction, SIGNAL(triggered()), SLOT(order())); + connect(orderAction, &QAction::triggered, this, &ToolBar::order); randomizeAction = new QAction(this); randomizeAction->setText(tr("Randomize Items in Tool Bar")); - connect(randomizeAction, SIGNAL(triggered()), SLOT(randomize())); + connect(randomizeAction, &QAction::triggered, this, &ToolBar::randomize); addSpinBoxAction = new QAction(this); addSpinBoxAction->setText(tr("Add Spin Box")); - connect(addSpinBoxAction, SIGNAL(triggered()), SLOT(addSpinBox())); + connect(addSpinBoxAction, &QAction::triggered, this, &ToolBar::addSpinBox); removeSpinBoxAction = new QAction(this); removeSpinBoxAction->setText(tr("Remove Spin Box")); removeSpinBoxAction->setEnabled(false); - connect(removeSpinBoxAction, SIGNAL(triggered()), SLOT(removeSpinBox())); + connect(removeSpinBoxAction, &QAction::triggered, this, &ToolBar::removeSpinBox); movableAction = new QAction(tr("Movable"), this); movableAction->setCheckable(true); - connect(movableAction, SIGNAL(triggered(bool)), SLOT(changeMovable(bool))); + connect(movableAction, &QAction::triggered, this, &ToolBar::changeMovable); allowedAreasActions = new QActionGroup(this); allowedAreasActions->setExclusive(false); allowLeftAction = new QAction(tr("Allow on Left"), this); allowLeftAction->setCheckable(true); - connect(allowLeftAction, SIGNAL(triggered(bool)), SLOT(allowLeft(bool))); + connect(allowLeftAction, &QAction::triggered, this, &ToolBar::allowLeft); allowRightAction = new QAction(tr("Allow on Right"), this); allowRightAction->setCheckable(true); - connect(allowRightAction, SIGNAL(triggered(bool)), SLOT(allowRight(bool))); + connect(allowRightAction, &QAction::triggered, this, &ToolBar::allowRight); allowTopAction = new QAction(tr("Allow on Top"), this); allowTopAction->setCheckable(true); - connect(allowTopAction, SIGNAL(triggered(bool)), SLOT(allowTop(bool))); + connect(allowTopAction, &QAction::triggered, this, &ToolBar::allowTop); allowBottomAction = new QAction(tr("Allow on Bottom"), this); allowBottomAction->setCheckable(true); - connect(allowBottomAction, SIGNAL(triggered(bool)), SLOT(allowBottom(bool))); + connect(allowBottomAction, &QAction::triggered, this, &ToolBar::allowBottom); allowedAreasActions->addAction(allowLeftAction); allowedAreasActions->addAction(allowRightAction); @@ -138,31 +138,28 @@ ToolBar::ToolBar(const QString &title, QWidget *parent) leftAction = new QAction(tr("Place on Left") , this); leftAction->setCheckable(true); - connect(leftAction, SIGNAL(triggered(bool)), SLOT(placeLeft(bool))); + connect(leftAction, &QAction::triggered, this, &ToolBar::placeLeft); rightAction = new QAction(tr("Place on Right") , this); rightAction->setCheckable(true); - connect(rightAction, SIGNAL(triggered(bool)), SLOT(placeRight(bool))); + connect(rightAction, &QAction::triggered, this, &ToolBar::placeRight); topAction = new QAction(tr("Place on Top") , this); topAction->setCheckable(true); - connect(topAction, SIGNAL(triggered(bool)), SLOT(placeTop(bool))); + connect(topAction, &QAction::triggered, this, &ToolBar::placeTop); bottomAction = new QAction(tr("Place on Bottom") , this); bottomAction->setCheckable(true); - connect(bottomAction, SIGNAL(triggered(bool)), SLOT(placeBottom(bool))); + connect(bottomAction, &QAction::triggered, this, &ToolBar::placeBottom); areaActions->addAction(leftAction); areaActions->addAction(rightAction); areaActions->addAction(topAction); areaActions->addAction(bottomAction); - toolBarBreakAction = new QAction(tr("Insert break"), this); - connect(toolBarBreakAction, SIGNAL(triggered(bool)), this, SLOT(insertToolBarBreak())); + connect(movableAction, &QAction::triggered, areaActions, &QActionGroup::setEnabled); - connect(movableAction, SIGNAL(triggered(bool)), areaActions, SLOT(setEnabled(bool))); - - connect(movableAction, SIGNAL(triggered(bool)), allowedAreasActions, SLOT(setEnabled(bool))); + connect(movableAction, &QAction::triggered, allowedAreasActions, &QActionGroup::setEnabled); menu = new QMenu(title, this); menu->addAction(toggleViewAction()); @@ -179,9 +176,9 @@ ToolBar::ToolBar(const QString &title, QWidget *parent) menu->addSeparator(); menu->addActions(areaActions->actions()); menu->addSeparator(); - menu->addAction(toolBarBreakAction); + menu->addAction(tr("Insert break"), this, &ToolBar::insertToolBarBreak); - connect(menu, SIGNAL(aboutToShow()), this, SLOT(updateMenu())); + connect(menu, &QMenu::aboutToShow, this, &ToolBar::updateMenu); randomize(); } @@ -223,10 +220,9 @@ void ToolBar::updateMenu() void ToolBar::order() { - QList<QAction *> ordered, actions1 = actions(), - actions2 = findChildren<QAction *>(); - while (!actions2.isEmpty()) { - QAction *action = actions2.takeFirst(); + QList<QAction *> ordered; + QList<QAction *> actions1 = actions(); + foreach (QAction *action, findChildren<QAction *>()) { if (!actions1.contains(action)) continue; actions1.removeAll(action); @@ -241,7 +237,8 @@ void ToolBar::order() void ToolBar::randomize() { - QList<QAction *> randomized, actions = this->actions(); + QList<QAction *> randomized; + QList<QAction *> actions = this->actions(); while (!actions.isEmpty()) { QAction *action = actions.takeAt(rand() % actions.size()); randomized.append(action); @@ -254,9 +251,8 @@ void ToolBar::randomize() void ToolBar::addSpinBox() { - if (!spinbox) { + if (!spinbox) spinbox = new QSpinBox(this); - } if (!spinboxAction) spinboxAction = addWidget(spinbox); else @@ -341,35 +337,3 @@ void ToolBar::insertToolBarBreak() mainWindow->insertToolBarBreak(this); } - -void ToolBar::enterEvent(QEvent*) -{ -/* - These labels on top of toolbars look darn ugly - - if (tip == 0) { - tip = new QLabel(windowTitle(), this); - QPalette pal = tip->palette(); - QColor c = Qt::black; - c.setAlpha(100); - pal.setColor(QPalette::Window, c); - pal.setColor(QPalette::Foreground, Qt::white); - tip->setPalette(pal); - tip->setAutoFillBackground(true); - tip->setMargin(3); - tip->setText(windowTitle()); - } - QPoint c = rect().center(); - QSize hint = tip->sizeHint(); - tip->setGeometry(c.x() - hint.width()/2, c.y() - hint.height()/2, - hint.width(), hint.height()); - - tip->show(); -*/ -} - -void ToolBar::leaveEvent(QEvent*) -{ - if (tip != 0) - tip->hide(); -} diff --git a/examples/widgets/mainwindows/mainwindow/toolbar.h b/examples/widgets/mainwindows/mainwindow/toolbar.h index b1674a203499893b99c792533d255726a0021195..2629d9d7a7033017e120d4a467aeb76e5b7f6096 100644 --- a/examples/widgets/mainwindows/mainwindow/toolbar.h +++ b/examples/widgets/mainwindows/mainwindow/toolbar.h @@ -40,49 +40,15 @@ QT_FORWARD_DECLARE_CLASS(QAction) QT_FORWARD_DECLARE_CLASS(QActionGroup) QT_FORWARD_DECLARE_CLASS(QMenu) QT_FORWARD_DECLARE_CLASS(QSpinBox) -QT_FORWARD_DECLARE_CLASS(QLabel) class ToolBar : public QToolBar { Q_OBJECT - QSpinBox *spinbox; - QAction *spinboxAction; - - QAction *orderAction; - QAction *randomizeAction; - QAction *addSpinBoxAction; - QAction *removeSpinBoxAction; - - QAction *movableAction; - - QActionGroup *allowedAreasActions; - QAction *allowLeftAction; - QAction *allowRightAction; - QAction *allowTopAction; - QAction *allowBottomAction; - - QActionGroup *areaActions; - QAction *leftAction; - QAction *rightAction; - QAction *topAction; - QAction *bottomAction; - - QAction *toolBarBreakAction; - public: - ToolBar(const QString &title, QWidget *parent); - - QMenu *menu; + explicit ToolBar(const QString &title, QWidget *parent); -protected: - void enterEvent(QEvent*) Q_DECL_OVERRIDE; - void leaveEvent(QEvent*) Q_DECL_OVERRIDE; - -private: - void allow(Qt::ToolBarArea area, bool allow); - void place(Qt::ToolBarArea area, bool place); - QLabel *tip; + QMenu *toolbarMenu() const { return menu; } private slots: void order(); @@ -105,6 +71,32 @@ private slots: void updateMenu(); void insertToolBarBreak(); +private: + void allow(Qt::ToolBarArea area, bool allow); + void place(Qt::ToolBarArea area, bool place); + + QSpinBox *spinbox; + QAction *spinboxAction; + + QMenu *menu; + QAction *orderAction; + QAction *randomizeAction; + QAction *addSpinBoxAction; + QAction *removeSpinBoxAction; + + QAction *movableAction; + + QActionGroup *allowedAreasActions; + QAction *allowLeftAction; + QAction *allowRightAction; + QAction *allowTopAction; + QAction *allowBottomAction; + + QActionGroup *areaActions; + QAction *leftAction; + QAction *rightAction; + QAction *topAction; + QAction *bottomAction; }; -#endif +#endif // TOOLBAR_H diff --git a/examples/widgets/mainwindows/mainwindows.pro b/examples/widgets/mainwindows/mainwindows.pro index 52179ec9bd9458bf4a41ca82d934b0588da1116b..dcda89abaf6e1c37d3ddb91516e87bf747e0fc42 100644 --- a/examples/widgets/mainwindows/mainwindows.pro +++ b/examples/widgets/mainwindows/mainwindows.pro @@ -4,5 +4,4 @@ SUBDIRS = application \ mainwindow \ mdi \ menus \ - recentfiles \ sdi diff --git a/examples/widgets/mainwindows/mdi/main.cpp b/examples/widgets/mainwindows/mdi/main.cpp index 5976c85c1c216a65f9e4724d9e3e62a83766857f..f02285d1cf7e545c75cbc9b41ba7bc392a8995fa 100644 --- a/examples/widgets/mainwindows/mdi/main.cpp +++ b/examples/widgets/mainwindows/mdi/main.cpp @@ -49,6 +49,8 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(mdi); QApplication app(argc, argv); + QCoreApplication::setApplicationName("MDI Example"); + QCoreApplication::setOrganizationName("QtProject"); QCoreApplication::setApplicationVersion(QT_VERSION_STR); QCommandLineParser parser; parser.setApplicationDescription("Qt MDI Example"); diff --git a/examples/widgets/mainwindows/mdi/mainwindow.cpp b/examples/widgets/mainwindows/mdi/mainwindow.cpp index 83ffbf65576e78e1fd2f482226b63462bdde6477..35136c81c4cd45a5fd2352819bed49a57de3bae0 100644 --- a/examples/widgets/mainwindows/mdi/mainwindow.cpp +++ b/examples/widgets/mainwindows/mdi/mainwindow.cpp @@ -44,20 +44,15 @@ #include "mdichild.h" MainWindow::MainWindow() + : mdiArea(new QMdiArea) { - mdiArea = new QMdiArea; mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); setCentralWidget(mdiArea); - connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), - this, SLOT(updateMenus())); - windowMapper = new QSignalMapper(this); - connect(windowMapper, SIGNAL(mapped(QWidget*)), - this, SLOT(setActiveSubWindow(QWidget*))); + connect(mdiArea, &QMdiArea::subWindowActivated, + this, &MainWindow::updateMenus); createActions(); - createMenus(); - createToolBars(); createStatusBar(); updateMenus(); @@ -87,20 +82,24 @@ void MainWindow::newFile() void MainWindow::open() { - QString fileName = QFileDialog::getOpenFileName(this); - if (!fileName.isEmpty()) { - QMdiSubWindow *existing = findMdiChild(fileName); - if (existing) { - mdiArea->setActiveSubWindow(existing); - return; - } + const QString fileName = QFileDialog::getOpenFileName(this); + if (!fileName.isEmpty()) + openFile(fileName); +} - if (openFile(fileName)) - statusBar()->showMessage(tr("File loaded"), 2000); +bool MainWindow::openFile(const QString &fileName) +{ + if (QMdiSubWindow *existing = findMdiChild(fileName)) { + mdiArea->setActiveSubWindow(existing); + return true; } + const bool succeeded = loadFile(fileName); + if (succeeded) + statusBar()->showMessage(tr("File loaded"), 2000); + return succeeded; } -bool MainWindow::openFile(const QString &fileName) +bool MainWindow::loadFile(const QString &fileName) { MdiChild *child = createMdiChild(); const bool succeeded = child->loadFile(fileName); @@ -108,9 +107,87 @@ bool MainWindow::openFile(const QString &fileName) child->show(); else child->close(); + MainWindow::prependToRecentFiles(fileName); return succeeded; } +static inline QString recentFilesKey() { return QStringLiteral("recentFileList"); } +static inline QString fileKey() { return QStringLiteral("file"); } + +static QStringList readRecentFiles(QSettings &settings) +{ + QStringList result; + const int count = settings.beginReadArray(recentFilesKey()); + for (int i = 0; i < count; ++i) { + settings.setArrayIndex(i); + result.append(settings.value(fileKey()).toString()); + } + settings.endArray(); + return result; +} + +static void writeRecentFiles(const QStringList &files, QSettings &settings) +{ + const int count = files.size(); + settings.beginWriteArray(recentFilesKey()); + for (int i = 0; i < count; ++i) { + settings.setArrayIndex(i); + settings.setValue(fileKey(), files.at(i)); + } + settings.endArray(); +} + +bool MainWindow::hasRecentFiles() +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const int count = settings.beginReadArray(recentFilesKey()); + settings.endArray(); + return count > 0; +} + +void MainWindow::prependToRecentFiles(const QString &fileName) +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + + const QStringList oldRecentFiles = readRecentFiles(settings); + QStringList recentFiles = oldRecentFiles; + recentFiles.removeAll(fileName); + recentFiles.prepend(fileName); + if (oldRecentFiles != recentFiles) + writeRecentFiles(recentFiles, settings); + + setRecentFilesVisible(!recentFiles.isEmpty()); +} + +void MainWindow::setRecentFilesVisible(bool visible) +{ + recentFileSubMenuAct->setVisible(visible); + recentFileSeparator->setVisible(visible); +} + +void MainWindow::updateRecentFileActions() +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + + const QStringList recentFiles = readRecentFiles(settings); + const int count = qMin(int(MaxRecentFiles), recentFiles.size()); + int i = 0; + for ( ; i < count; ++i) { + const QString fileName = QFileInfo(recentFiles.at(i)).fileName(); + recentFileActs[i]->setText(tr("&%1 %2").arg(i + 1).arg(fileName)); + recentFileActs[i]->setData(recentFiles.at(i)); + recentFileActs[i]->setVisible(true); + } + for ( ; i < MaxRecentFiles; ++i) + recentFileActs[i]->setVisible(false); +} + +void MainWindow::openRecentFile() +{ + if (const QAction *action = qobject_cast<const QAction *>(sender())) + openFile(action->data().toString()); +} + void MainWindow::save() { if (activeMdiChild() && activeMdiChild()->save()) @@ -119,8 +196,11 @@ void MainWindow::save() void MainWindow::saveAs() { - if (activeMdiChild() && activeMdiChild()->saveAs()) + MdiChild *child = activeMdiChild(); + if (child && child->saveAs()) { statusBar()->showMessage(tr("File saved"), 2000); + MainWindow::prependToRecentFiles(child->currentFile()); + } } #ifndef QT_NO_CLIPBOARD @@ -164,7 +244,7 @@ void MainWindow::updateMenus() cascadeAct->setEnabled(hasMdiChild); nextAct->setEnabled(hasMdiChild); previousAct->setEnabled(hasMdiChild); - separatorAct->setVisible(hasMdiChild); + windowMenuSeparatorAct->setVisible(hasMdiChild); #ifndef QT_NO_CLIPBOARD bool hasSelection = (activeMdiChild() && @@ -174,6 +254,16 @@ void MainWindow::updateMenus() #endif } +class ActiveMdiSubWindowFunctor { +public: + explicit ActiveMdiSubWindowFunctor(QMdiArea *mdiArea, QMdiSubWindow *activeWindow) : m_mdiArea(mdiArea), m_activeWindow(activeWindow) {} + void operator()() const { m_mdiArea->setActiveSubWindow(m_activeWindow); } + +private: + QMdiArea *m_mdiArea; + QMdiSubWindow *m_activeWindow; +}; + void MainWindow::updateWindowMenu() { windowMenu->clear(); @@ -185,13 +275,14 @@ void MainWindow::updateWindowMenu() windowMenu->addSeparator(); windowMenu->addAction(nextAct); windowMenu->addAction(previousAct); - windowMenu->addAction(separatorAct); + windowMenu->addAction(windowMenuSeparatorAct); QList<QMdiSubWindow *> windows = mdiArea->subWindowList(); - separatorAct->setVisible(!windows.isEmpty()); + windowMenuSeparatorAct->setVisible(!windows.isEmpty()); for (int i = 0; i < windows.size(); ++i) { - MdiChild *child = qobject_cast<MdiChild *>(windows.at(i)->widget()); + QMdiSubWindow *mdiSubWindow = windows.at(i); + MdiChild *child = qobject_cast<MdiChild *>(mdiSubWindow->widget()); QString text; if (i < 9) { @@ -201,11 +292,9 @@ void MainWindow::updateWindowMenu() text = tr("%1 %2").arg(i + 1) .arg(child->userFriendlyCurrentFile()); } - QAction *action = windowMenu->addAction(text); + QAction *action = windowMenu->addAction(text, mdiSubWindow, ActiveMdiSubWindowFunctor(mdiArea, mdiSubWindow)); action->setCheckable(true); action ->setChecked(child == activeMdiChild()); - connect(action, SIGNAL(triggered()), windowMapper, SLOT(map())); - windowMapper->setMapping(action, windows.at(i)); } } @@ -215,10 +304,8 @@ MdiChild *MainWindow::createMdiChild() mdiArea->addSubWindow(child); #ifndef QT_NO_CLIPBOARD - connect(child, SIGNAL(copyAvailable(bool)), - cutAct, SLOT(setEnabled(bool))); - connect(child, SIGNAL(copyAvailable(bool)), - copyAct, SLOT(setEnabled(bool))); + connect(child, &QTextEdit::copyAvailable, cutAct, &QAction::setEnabled); + connect(child, &QTextEdit::copyAvailable, copyAct, &QAction::setEnabled); #endif return child; @@ -226,139 +313,143 @@ MdiChild *MainWindow::createMdiChild() void MainWindow::createActions() { - newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + QToolBar *fileToolBar = addToolBar(tr("File")); + + const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png")); + newAct = new QAction(newIcon, tr("&New"), this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); + connect(newAct, &QAction::triggered, this, &MainWindow::newFile); + fileMenu->addAction(newAct); + fileToolBar->addAction(newAct); - openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); + const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/images/open.png")); + QAction *openAct = new QAction(openIcon, tr("&Open..."), this); openAct->setShortcuts(QKeySequence::Open); openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(openAct, &QAction::triggered, this, &MainWindow::open); + fileMenu->addAction(openAct); + fileToolBar->addAction(openAct); - saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); + const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png")); + saveAct = new QAction(saveIcon, tr("&Save"), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); + fileToolBar->addAction(saveAct); - saveAsAct = new QAction(tr("Save &As..."), this); + const QIcon saveAsIcon = QIcon::fromTheme("document-save-as"); + saveAsAct = new QAction(saveAsIcon, tr("Save &As..."), this); saveAsAct->setShortcuts(QKeySequence::SaveAs); saveAsAct->setStatusTip(tr("Save the document under a new name")); - connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); + connect(saveAsAct, &QAction::triggered, this, &MainWindow::saveAs); + fileMenu->addAction(saveAsAct); + + fileMenu->addSeparator(); + + QMenu *recentMenu = fileMenu->addMenu(tr("Recent...")); + connect(recentMenu, &QMenu::aboutToShow, this, &MainWindow::updateRecentFileActions); + recentFileSubMenuAct = recentMenu->menuAction(); + + for (int i = 0; i < MaxRecentFiles; ++i) { + recentFileActs[i] = recentMenu->addAction(QString(), this, &MainWindow::openRecentFile); + recentFileActs[i]->setVisible(false); + } + + recentFileSeparator = fileMenu->addSeparator(); + + setRecentFilesVisible(MainWindow::hasRecentFiles()); + + fileMenu->addAction(tr("Switch layout direction"), this, &MainWindow::switchLayoutDirection); + + fileMenu->addSeparator(); //! [0] - exitAct = new QAction(tr("E&xit"), this); + const QIcon exitIcon = QIcon::fromTheme("application-exit"); + QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), qApp, &QApplication::closeAllWindows); exitAct->setShortcuts(QKeySequence::Quit); exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); + fileMenu->addAction(exitAct); //! [0] #ifndef QT_NO_CLIPBOARD - cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this); + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + QToolBar *editToolBar = addToolBar(tr("Edit")); + + const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png")); + cutAct = new QAction(cutIcon, tr("Cu&t"), this); cutAct->setShortcuts(QKeySequence::Cut); cutAct->setStatusTip(tr("Cut the current selection's contents to the " "clipboard")); - connect(cutAct, SIGNAL(triggered()), this, SLOT(cut())); + connect(cutAct, &QAction::triggered, this, &MainWindow::cut); + editMenu->addAction(cutAct); + editToolBar->addAction(cutAct); - copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this); + const QIcon copyIcon = QIcon::fromTheme("edit-copy", QIcon(":/images/copy.png")); + copyAct = new QAction(copyIcon, tr("&Copy"), this); copyAct->setShortcuts(QKeySequence::Copy); copyAct->setStatusTip(tr("Copy the current selection's contents to the " "clipboard")); - connect(copyAct, SIGNAL(triggered()), this, SLOT(copy())); + connect(copyAct, &QAction::triggered, this, &MainWindow::copy); + editMenu->addAction(copyAct); + editToolBar->addAction(copyAct); - pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this); + const QIcon pasteIcon = QIcon::fromTheme("edit-paste", QIcon(":/images/paste.png")); + pasteAct = new QAction(pasteIcon, tr("&Paste"), this); pasteAct->setShortcuts(QKeySequence::Paste); pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " "selection")); - connect(pasteAct, SIGNAL(triggered()), this, SLOT(paste())); + connect(pasteAct, &QAction::triggered, this, &MainWindow::paste); + editMenu->addAction(pasteAct); + editToolBar->addAction(pasteAct); #endif + windowMenu = menuBar()->addMenu(tr("&Window")); + connect(windowMenu, &QMenu::aboutToShow, this, &MainWindow::updateWindowMenu); + closeAct = new QAction(tr("Cl&ose"), this); closeAct->setStatusTip(tr("Close the active window")); - connect(closeAct, SIGNAL(triggered()), - mdiArea, SLOT(closeActiveSubWindow())); + connect(closeAct, &QAction::triggered, + mdiArea, &QMdiArea::closeActiveSubWindow); closeAllAct = new QAction(tr("Close &All"), this); closeAllAct->setStatusTip(tr("Close all the windows")); - connect(closeAllAct, SIGNAL(triggered()), - mdiArea, SLOT(closeAllSubWindows())); + connect(closeAllAct, &QAction::triggered, mdiArea, &QMdiArea::closeAllSubWindows); tileAct = new QAction(tr("&Tile"), this); tileAct->setStatusTip(tr("Tile the windows")); - connect(tileAct, SIGNAL(triggered()), mdiArea, SLOT(tileSubWindows())); + connect(tileAct, &QAction::triggered, mdiArea, &QMdiArea::tileSubWindows); cascadeAct = new QAction(tr("&Cascade"), this); cascadeAct->setStatusTip(tr("Cascade the windows")); - connect(cascadeAct, SIGNAL(triggered()), mdiArea, SLOT(cascadeSubWindows())); + connect(cascadeAct, &QAction::triggered, mdiArea, &QMdiArea::cascadeSubWindows); nextAct = new QAction(tr("Ne&xt"), this); nextAct->setShortcuts(QKeySequence::NextChild); nextAct->setStatusTip(tr("Move the focus to the next window")); - connect(nextAct, SIGNAL(triggered()), - mdiArea, SLOT(activateNextSubWindow())); + connect(nextAct, &QAction::triggered, mdiArea, &QMdiArea::activateNextSubWindow); previousAct = new QAction(tr("Pre&vious"), this); previousAct->setShortcuts(QKeySequence::PreviousChild); previousAct->setStatusTip(tr("Move the focus to the previous " "window")); - connect(previousAct, SIGNAL(triggered()), - mdiArea, SLOT(activatePreviousSubWindow())); - - separatorAct = new QAction(this); - separatorAct->setSeparator(true); - - aboutAct = new QAction(tr("&About"), this); - aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - - aboutQtAct = new QAction(tr("About &Qt"), this); - aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); -} - -void MainWindow::createMenus() -{ - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newAct); - fileMenu->addAction(openAct); - fileMenu->addAction(saveAct); - fileMenu->addAction(saveAsAct); - fileMenu->addSeparator(); - QAction *action = fileMenu->addAction(tr("Switch layout direction")); - connect(action, SIGNAL(triggered()), this, SLOT(switchLayoutDirection())); - fileMenu->addAction(exitAct); + connect(previousAct, &QAction::triggered, mdiArea, &QMdiArea::activatePreviousSubWindow); - editMenu = menuBar()->addMenu(tr("&Edit")); -#ifndef QT_NO_CLIPBOARD - editMenu->addAction(cutAct); - editMenu->addAction(copyAct); - editMenu->addAction(pasteAct); -#endif + windowMenuSeparatorAct = new QAction(this); + windowMenuSeparatorAct->setSeparator(true); - windowMenu = menuBar()->addMenu(tr("&Window")); updateWindowMenu(); - connect(windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu())); menuBar()->addSeparator(); - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); -void MainWindow::createToolBars() -{ - fileToolBar = addToolBar(tr("File")); - fileToolBar->addAction(newAct); - fileToolBar->addAction(openAct); - fileToolBar->addAction(saveAct); + QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about); + aboutAct->setStatusTip(tr("Show the application's About box")); -#ifndef QT_NO_CLIPBOARD - editToolBar = addToolBar(tr("Edit")); - editToolBar->addAction(cutAct); - editToolBar->addAction(copyAct); - editToolBar->addAction(pasteAct); -#endif + QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); + aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); } void MainWindow::createStatusBar() @@ -368,28 +459,32 @@ void MainWindow::createStatusBar() void MainWindow::readSettings() { - QSettings settings("QtProject", "MDI Example"); - QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); - QSize size = settings.value("size", QSize(400, 400)).toSize(); - move(pos); - resize(size); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray(); + if (geometry.isEmpty()) { + const QRect availableGeometry = QApplication::desktop()->availableGeometry(this); + resize(availableGeometry.width() / 3, availableGeometry.height() / 2); + move((availableGeometry.width() - width()) / 2, + (availableGeometry.height() - height()) / 2); + } else { + restoreGeometry(geometry); + } } void MainWindow::writeSettings() { - QSettings settings("QtProject", "MDI Example"); - settings.setValue("pos", pos()); - settings.setValue("size", size()); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + settings.setValue("geometry", saveGeometry()); } -MdiChild *MainWindow::activeMdiChild() +MdiChild *MainWindow::activeMdiChild() const { if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow()) return qobject_cast<MdiChild *>(activeSubWindow->widget()); return 0; } -QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName) +QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName) const { QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath(); @@ -404,14 +499,7 @@ QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName) void MainWindow::switchLayoutDirection() { if (layoutDirection() == Qt::LeftToRight) - qApp->setLayoutDirection(Qt::RightToLeft); + QGuiApplication::setLayoutDirection(Qt::RightToLeft); else - qApp->setLayoutDirection(Qt::LeftToRight); -} - -void MainWindow::setActiveSubWindow(QWidget *window) -{ - if (!window) - return; - mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window)); + QGuiApplication::setLayoutDirection(Qt::LeftToRight); } diff --git a/examples/widgets/mainwindows/mdi/mainwindow.h b/examples/widgets/mainwindows/mdi/mainwindow.h index fa8e0131e992906b1c52e66636f026f522e0bbd1..3ac60282fd8a74243031d960ee20bd57eca2bffc 100644 --- a/examples/widgets/mainwindows/mdi/mainwindow.h +++ b/examples/widgets/mainwindows/mdi/mainwindow.h @@ -49,7 +49,6 @@ class QAction; class QMenu; class QMdiArea; class QMdiSubWindow; -class QSignalMapper; QT_END_NAMESPACE class MainWindow : public QMainWindow @@ -69,6 +68,8 @@ private slots: void open(); void save(); void saveAs(); + void updateRecentFileActions(); + void openRecentFile(); #ifndef QT_NO_CLIPBOARD void cut(); void copy(); @@ -79,32 +80,30 @@ private slots: void updateWindowMenu(); MdiChild *createMdiChild(); void switchLayoutDirection(); - void setActiveSubWindow(QWidget *window); private: + enum { MaxRecentFiles = 5 }; + void createActions(); - void createMenus(); - void createToolBars(); void createStatusBar(); void readSettings(); void writeSettings(); - MdiChild *activeMdiChild(); - QMdiSubWindow *findMdiChild(const QString &fileName); + bool loadFile(const QString &fileName); + static bool hasRecentFiles(); + void prependToRecentFiles(const QString &fileName); + void setRecentFilesVisible(bool visible); + MdiChild *activeMdiChild() const; + QMdiSubWindow *findMdiChild(const QString &fileName) const; QMdiArea *mdiArea; - QSignalMapper *windowMapper; - QMenu *fileMenu; - QMenu *editMenu; QMenu *windowMenu; - QMenu *helpMenu; - QToolBar *fileToolBar; - QToolBar *editToolBar; QAction *newAct; - QAction *openAct; QAction *saveAct; QAction *saveAsAct; - QAction *exitAct; + QAction *recentFileActs[MaxRecentFiles]; + QAction *recentFileSeparator; + QAction *recentFileSubMenuAct; #ifndef QT_NO_CLIPBOARD QAction *cutAct; QAction *copyAct; @@ -116,9 +115,7 @@ private: QAction *cascadeAct; QAction *nextAct; QAction *previousAct; - QAction *separatorAct; - QAction *aboutAct; - QAction *aboutQtAct; + QAction *windowMenuSeparatorAct; }; #endif diff --git a/examples/widgets/mainwindows/mdi/mdichild.cpp b/examples/widgets/mainwindows/mdi/mdichild.cpp index 242e8248a2d04cff31d36fe4cde76ff8d331381b..73364eb3eef8e97d6dcd403f3629a4611c6b55f5 100644 --- a/examples/widgets/mainwindows/mdi/mdichild.cpp +++ b/examples/widgets/mainwindows/mdi/mdichild.cpp @@ -56,8 +56,8 @@ void MdiChild::newFile() curFile = tr("document%1.txt").arg(sequenceNumber++); setWindowTitle(curFile + "[*]"); - connect(document(), SIGNAL(contentsChanged()), - this, SLOT(documentWasModified())); + connect(document(), &QTextDocument::contentsChanged, + this, &MdiChild::documentWasModified); } bool MdiChild::loadFile(const QString &fileName) @@ -78,8 +78,8 @@ bool MdiChild::loadFile(const QString &fileName) setCurrentFile(fileName); - connect(document(), SIGNAL(contentsChanged()), - this, SLOT(documentWasModified())); + connect(document(), &QTextDocument::contentsChanged, + this, &MdiChild::documentWasModified); return true; } @@ -109,8 +109,7 @@ bool MdiChild::saveFile(const QString &fileName) if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("MDI"), tr("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return false; } @@ -144,18 +143,22 @@ void MdiChild::documentWasModified() bool MdiChild::maybeSave() { - if (document()->isModified()) { - QMessageBox::StandardButton ret; - ret = QMessageBox::warning(this, tr("MDI"), - tr("'%1' has been modified.\n" - "Do you want to save your changes?") - .arg(userFriendlyCurrentFile()), - QMessageBox::Save | QMessageBox::Discard - | QMessageBox::Cancel); - if (ret == QMessageBox::Save) - return save(); - else if (ret == QMessageBox::Cancel) - return false; + if (!document()->isModified()) + return true; + const QMessageBox::StandardButton ret + = QMessageBox::warning(this, tr("MDI"), + tr("'%1' has been modified.\n" + "Do you want to save your changes?") + .arg(userFriendlyCurrentFile()), + QMessageBox::Save | QMessageBox::Discard + | QMessageBox::Cancel); + switch (ret) { + case QMessageBox::Save: + return save(); + case QMessageBox::Cancel: + return false; + default: + break; } return true; } diff --git a/examples/widgets/mainwindows/menus/mainwindow.cpp b/examples/widgets/mainwindows/menus/mainwindow.cpp index 31515394bdeac5ec23e50d5ff84d7b0c4796a027..d487e3a277dfbf937ad0b67590c0627ade98694a 100644 --- a/examples/widgets/mainwindows/menus/mainwindow.cpp +++ b/examples/widgets/mainwindows/menus/mainwindow.cpp @@ -198,63 +198,63 @@ void MainWindow::createActions() newAct = new QAction(tr("&New"), this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); + connect(newAct, &QAction::triggered, this, &MainWindow::newFile); //! [4] openAct = new QAction(tr("&Open..."), this); openAct->setShortcuts(QKeySequence::Open); openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(openAct, &QAction::triggered, this, &MainWindow::open); //! [5] saveAct = new QAction(tr("&Save"), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); printAct = new QAction(tr("&Print..."), this); printAct->setShortcuts(QKeySequence::Print); printAct->setStatusTip(tr("Print the document")); - connect(printAct, SIGNAL(triggered()), this, SLOT(print())); + connect(printAct, &QAction::triggered, this, &MainWindow::print); exitAct = new QAction(tr("E&xit"), this); exitAct->setShortcuts(QKeySequence::Quit); exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); + connect(exitAct, &QAction::triggered, this, &QWidget::close); undoAct = new QAction(tr("&Undo"), this); undoAct->setShortcuts(QKeySequence::Undo); undoAct->setStatusTip(tr("Undo the last operation")); - connect(undoAct, SIGNAL(triggered()), this, SLOT(undo())); + connect(undoAct, &QAction::triggered, this, &MainWindow::undo); redoAct = new QAction(tr("&Redo"), this); redoAct->setShortcuts(QKeySequence::Redo); redoAct->setStatusTip(tr("Redo the last operation")); - connect(redoAct, SIGNAL(triggered()), this, SLOT(redo())); + connect(redoAct, &QAction::triggered, this, &MainWindow::redo); cutAct = new QAction(tr("Cu&t"), this); cutAct->setShortcuts(QKeySequence::Cut); cutAct->setStatusTip(tr("Cut the current selection's contents to the " "clipboard")); - connect(cutAct, SIGNAL(triggered()), this, SLOT(cut())); + connect(cutAct, &QAction::triggered, this, &MainWindow::cut); copyAct = new QAction(tr("&Copy"), this); copyAct->setShortcuts(QKeySequence::Copy); copyAct->setStatusTip(tr("Copy the current selection's contents to the " "clipboard")); - connect(copyAct, SIGNAL(triggered()), this, SLOT(copy())); + connect(copyAct, &QAction::triggered, this, &MainWindow::copy); pasteAct = new QAction(tr("&Paste"), this); pasteAct->setShortcuts(QKeySequence::Paste); pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " "selection")); - connect(pasteAct, SIGNAL(triggered()), this, SLOT(paste())); + connect(pasteAct, &QAction::triggered, this, &MainWindow::paste); boldAct = new QAction(tr("&Bold"), this); boldAct->setCheckable(true); boldAct->setShortcut(QKeySequence::Bold); boldAct->setStatusTip(tr("Make the text bold")); - connect(boldAct, SIGNAL(triggered()), this, SLOT(bold())); + connect(boldAct, &QAction::triggered, this, &MainWindow::bold); QFont boldFont = boldAct->font(); boldFont.setBold(true); @@ -264,7 +264,7 @@ void MainWindow::createActions() italicAct->setCheckable(true); italicAct->setShortcut(QKeySequence::Italic); italicAct->setStatusTip(tr("Make the text italic")); - connect(italicAct, SIGNAL(triggered()), this, SLOT(italic())); + connect(italicAct, &QAction::triggered, this, &MainWindow::italic); QFont italicFont = italicAct->font(); italicFont.setItalic(true); @@ -273,45 +273,45 @@ void MainWindow::createActions() setLineSpacingAct = new QAction(tr("Set &Line Spacing..."), this); setLineSpacingAct->setStatusTip(tr("Change the gap between the lines of a " "paragraph")); - connect(setLineSpacingAct, SIGNAL(triggered()), this, SLOT(setLineSpacing())); + connect(setLineSpacingAct, &QAction::triggered, this, &MainWindow::setLineSpacing); setParagraphSpacingAct = new QAction(tr("Set &Paragraph Spacing..."), this); setParagraphSpacingAct->setStatusTip(tr("Change the gap between paragraphs")); - connect(setParagraphSpacingAct, SIGNAL(triggered()), - this, SLOT(setParagraphSpacing())); + connect(setParagraphSpacingAct, &QAction::triggered, + this, &MainWindow::setParagraphSpacing); aboutAct = new QAction(tr("&About"), this); aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); + connect(aboutAct, &QAction::triggered, this, &MainWindow::about); aboutQtAct = new QAction(tr("About &Qt"), this); aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); - connect(aboutQtAct, SIGNAL(triggered()), this, SLOT(aboutQt())); + connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt); + connect(aboutQtAct, &QAction::triggered, this, &MainWindow::aboutQt); leftAlignAct = new QAction(tr("&Left Align"), this); leftAlignAct->setCheckable(true); leftAlignAct->setShortcut(tr("Ctrl+L")); leftAlignAct->setStatusTip(tr("Left align the selected text")); - connect(leftAlignAct, SIGNAL(triggered()), this, SLOT(leftAlign())); + connect(leftAlignAct, &QAction::triggered, this, &MainWindow::leftAlign); rightAlignAct = new QAction(tr("&Right Align"), this); rightAlignAct->setCheckable(true); rightAlignAct->setShortcut(tr("Ctrl+R")); rightAlignAct->setStatusTip(tr("Right align the selected text")); - connect(rightAlignAct, SIGNAL(triggered()), this, SLOT(rightAlign())); + connect(rightAlignAct, &QAction::triggered, this, &MainWindow::rightAlign); justifyAct = new QAction(tr("&Justify"), this); justifyAct->setCheckable(true); justifyAct->setShortcut(tr("Ctrl+J")); justifyAct->setStatusTip(tr("Justify the selected text")); - connect(justifyAct, SIGNAL(triggered()), this, SLOT(justify())); + connect(justifyAct, &QAction::triggered, this, &MainWindow::justify); centerAct = new QAction(tr("&Center"), this); centerAct->setCheckable(true); centerAct->setShortcut(tr("Ctrl+E")); centerAct->setStatusTip(tr("Center the selected text")); - connect(centerAct, SIGNAL(triggered()), this, SLOT(center())); + connect(centerAct, &QAction::triggered, this, &MainWindow::center); //! [6] //! [7] alignmentGroup = new QActionGroup(this); diff --git a/examples/widgets/mainwindows/recentfiles/mainwindow.cpp b/examples/widgets/mainwindows/recentfiles/mainwindow.cpp deleted file mode 100644 index b89797092a3322e1681e9eee0b6c6c0fab17957d..0000000000000000000000000000000000000000 --- a/examples/widgets/mainwindows/recentfiles/mainwindow.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtWidgets> - -#include "mainwindow.h" - -MainWindow::MainWindow() -{ - setAttribute(Qt::WA_DeleteOnClose); - - textEdit = new QTextEdit; - setCentralWidget(textEdit); - - createActions(); - createMenus(); - (void)statusBar(); - - setWindowFilePath(QString()); - resize(400, 300); -} - -void MainWindow::newFile() -{ - MainWindow *other = new MainWindow; - other->show(); -} - -void MainWindow::open() -{ - QString fileName = QFileDialog::getOpenFileName(this); - if (!fileName.isEmpty()) - loadFile(fileName); -} - -void MainWindow::save() -{ - if (curFile.isEmpty()) - saveAs(); - else - saveFile(curFile); -} - -void MainWindow::saveAs() -{ - QString fileName = QFileDialog::getSaveFileName(this); - if (fileName.isEmpty()) - return; - - saveFile(fileName); -} - -void MainWindow::openRecentFile() -{ - QAction *action = qobject_cast<QAction *>(sender()); - if (action) - loadFile(action->data().toString()); -} - -void MainWindow::about() -{ - QMessageBox::about(this, tr("About Recent Files"), - tr("The <b>Recent Files</b> example demonstrates how to provide a " - "recently used file menu in a Qt application.")); -} - -void MainWindow::createActions() -{ - newAct = new QAction(tr("&New"), this); - newAct->setShortcuts(QKeySequence::New); - newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); - - openAct = new QAction(tr("&Open..."), this); - openAct->setShortcuts(QKeySequence::Open); - openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); - - saveAct = new QAction(tr("&Save"), this); - saveAct->setShortcuts(QKeySequence::Save); - saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); - - saveAsAct = new QAction(tr("Save &As..."), this); - saveAsAct->setShortcuts(QKeySequence::SaveAs); - saveAsAct->setStatusTip(tr("Save the document under a new name")); - connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); - - for (int i = 0; i < MaxRecentFiles; ++i) { - recentFileActs[i] = new QAction(this); - recentFileActs[i]->setVisible(false); - connect(recentFileActs[i], SIGNAL(triggered()), - this, SLOT(openRecentFile())); - } - - exitAct = new QAction(tr("E&xit"), this); - exitAct->setShortcuts(QKeySequence::Quit); - exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); - - aboutAct = new QAction(tr("&About"), this); - aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - - aboutQtAct = new QAction(tr("About &Qt"), this); - aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); -} - -void MainWindow::createMenus() -{ - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newAct); - fileMenu->addAction(openAct); - fileMenu->addAction(saveAct); - fileMenu->addAction(saveAsAct); - separatorAct = fileMenu->addSeparator(); - for (int i = 0; i < MaxRecentFiles; ++i) - fileMenu->addAction(recentFileActs[i]); - fileMenu->addSeparator(); - fileMenu->addAction(exitAct); - updateRecentFileActions(); - - menuBar()->addSeparator(); - - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} - -void MainWindow::loadFile(const QString &fileName) -{ - QFile file(fileName); - if (!file.open(QFile::ReadOnly | QFile::Text)) { - QMessageBox::warning(this, tr("Recent Files"), - tr("Cannot read file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - return; - } - - QTextStream in(&file); - QApplication::setOverrideCursor(Qt::WaitCursor); - textEdit->setPlainText(in.readAll()); - QApplication::restoreOverrideCursor(); - - setCurrentFile(fileName); - statusBar()->showMessage(tr("File loaded"), 2000); -} - -void MainWindow::saveFile(const QString &fileName) -{ - QFile file(fileName); - if (!file.open(QFile::WriteOnly | QFile::Text)) { - QMessageBox::warning(this, tr("Recent Files"), - tr("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - return; - } - - QTextStream out(&file); - QApplication::setOverrideCursor(Qt::WaitCursor); - out << textEdit->toPlainText(); - QApplication::restoreOverrideCursor(); - - setCurrentFile(fileName); - statusBar()->showMessage(tr("File saved"), 2000); -} - -void MainWindow::setCurrentFile(const QString &fileName) -{ - curFile = fileName; - setWindowFilePath(curFile); - - QSettings settings; - QStringList files = settings.value("recentFileList").toStringList(); - files.removeAll(fileName); - files.prepend(fileName); - while (files.size() > MaxRecentFiles) - files.removeLast(); - - settings.setValue("recentFileList", files); - - foreach (QWidget *widget, QApplication::topLevelWidgets()) { - MainWindow *mainWin = qobject_cast<MainWindow *>(widget); - if (mainWin) - mainWin->updateRecentFileActions(); - } -} - -void MainWindow::updateRecentFileActions() -{ - QSettings settings; - QStringList files = settings.value("recentFileList").toStringList(); - - int numRecentFiles = qMin(files.size(), (int)MaxRecentFiles); - - for (int i = 0; i < numRecentFiles; ++i) { - QString text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i])); - recentFileActs[i]->setText(text); - recentFileActs[i]->setData(files[i]); - recentFileActs[i]->setVisible(true); - } - for (int j = numRecentFiles; j < MaxRecentFiles; ++j) - recentFileActs[j]->setVisible(false); - - separatorAct->setVisible(numRecentFiles > 0); -} - -QString MainWindow::strippedName(const QString &fullFileName) -{ - return QFileInfo(fullFileName).fileName(); -} diff --git a/examples/widgets/mainwindows/recentfiles/recentfiles.pro b/examples/widgets/mainwindows/recentfiles/recentfiles.pro deleted file mode 100644 index ccf948f5602709cdbf50e98c545fc384fa8b2d7a..0000000000000000000000000000000000000000 --- a/examples/widgets/mainwindows/recentfiles/recentfiles.pro +++ /dev/null @@ -1,9 +0,0 @@ -QT += widgets - -HEADERS = mainwindow.h -SOURCES = main.cpp \ - mainwindow.cpp - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/widgets/mainwindows/recentfiles -INSTALLS += target diff --git a/examples/widgets/mainwindows/sdi/main.cpp b/examples/widgets/mainwindows/sdi/main.cpp index d3350da9467529a5e2a9c7d5849d8d17e5b655ab..4b125722d844696a3c1e5d6c6f1acd401254b457 100644 --- a/examples/widgets/mainwindows/sdi/main.cpp +++ b/examples/widgets/mainwindows/sdi/main.cpp @@ -39,6 +39,7 @@ ****************************************************************************/ #include <QApplication> +#include <QCommandLineParser> #include "mainwindow.h" @@ -46,9 +47,27 @@ int main(int argc, char *argv[]) { Q_INIT_RESOURCE(sdi); QApplication app(argc, argv); - app.setApplicationName("SDI Example"); - app.setOrganizationName("QtProject"); - MainWindow *mainWin = new MainWindow; + QCoreApplication::setApplicationName("SDI Example"); + QCoreApplication::setOrganizationName("QtProject"); + QCoreApplication::setApplicationVersion(QT_VERSION_STR); + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::applicationName()); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("file", "The file(s) to open."); + parser.process(app); + + MainWindow *mainWin = Q_NULLPTR; + foreach (const QString &file, parser.positionalArguments()) { + MainWindow *newWin = new MainWindow(file); + newWin->tile(mainWin); + newWin->show(); + mainWin = newWin; + } + + if (!mainWin) + mainWin = new MainWindow; mainWin->show(); + return app.exec(); } diff --git a/examples/widgets/mainwindows/sdi/mainwindow.cpp b/examples/widgets/mainwindows/sdi/mainwindow.cpp index 1d6226e45cea8b429bc3ac57a31175db8a7d68d1..29618f9ac2f1667fa163ad0b92bdab0d33f336f6 100644 --- a/examples/widgets/mainwindows/sdi/mainwindow.cpp +++ b/examples/widgets/mainwindows/sdi/mainwindow.cpp @@ -45,7 +45,7 @@ MainWindow::MainWindow() { init(); - setCurrentFile(""); + setCurrentFile(QString()); } MainWindow::MainWindow(const QString &fileName) @@ -67,44 +67,44 @@ void MainWindow::closeEvent(QCloseEvent *event) void MainWindow::newFile() { MainWindow *other = new MainWindow; - other->move(x() + 40, y() + 40); + other->tile(this); other->show(); } void MainWindow::open() { - QString fileName = QFileDialog::getOpenFileName(this); - if (!fileName.isEmpty()) { - MainWindow *existing = findMainWindow(fileName); - if (existing) { - existing->show(); - existing->raise(); - existing->activateWindow(); - return; - } - - if (isUntitled && textEdit->document()->isEmpty() - && !isWindowModified()) { - loadFile(fileName); - } else { - MainWindow *other = new MainWindow(fileName); - if (other->isUntitled) { - delete other; - return; - } - other->move(x() + 40, y() + 40); - other->show(); - } + const QString fileName = QFileDialog::getOpenFileName(this); + if (!fileName.isEmpty()) + openFile(fileName); +} + +void MainWindow::openFile(const QString &fileName) +{ + MainWindow *existing = findMainWindow(fileName); + if (existing) { + existing->show(); + existing->raise(); + existing->activateWindow(); + return; + } + + if (isUntitled && textEdit->document()->isEmpty() && !isWindowModified()) { + loadFile(fileName); + return; } + + MainWindow *other = new MainWindow(fileName); + if (other->isUntitled) { + delete other; + return; + } + other->tile(this); + other->show(); } bool MainWindow::save() { - if (isUntitled) { - return saveAs(); - } else { - return saveFile(curFile); - } + return isUntitled ? saveAs() : saveFile(curFile); } bool MainWindow::saveAs() @@ -139,123 +139,131 @@ void MainWindow::init() setCentralWidget(textEdit); createActions(); - createMenus(); - createToolBars(); createStatusBar(); readSettings(); - connect(textEdit->document(), SIGNAL(contentsChanged()), - this, SLOT(documentWasModified())); + connect(textEdit->document(), &QTextDocument::contentsChanged, + this, &MainWindow::documentWasModified); setUnifiedTitleAndToolBarOnMac(true); } +void MainWindow::tile(const QMainWindow *previous) +{ + if (!previous) + return; + int topFrameWidth = previous->geometry().top() - previous->pos().y(); + if (!topFrameWidth) + topFrameWidth = 40; + const QPoint pos = previous->pos() + 2 * QPoint(topFrameWidth, topFrameWidth); + if (QApplication::desktop()->availableGeometry(this).contains(rect().bottomRight() + pos)) + move(pos); +} + +//! [implicit tr context] void MainWindow::createActions() { - newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); +//! [implicit tr context] + QToolBar *fileToolBar = addToolBar(tr("File")); + + const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png")); + QAction *newAct = new QAction(newIcon, tr("&New"), this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); + connect(newAct, &QAction::triggered, this, &MainWindow::newFile); + fileMenu->addAction(newAct); + fileToolBar->addAction(newAct); - openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); + const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/images/open.png")); + QAction *openAct = new QAction(openIcon, tr("&Open..."), this); openAct->setShortcuts(QKeySequence::Open); openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(openAct, &QAction::triggered, this, &MainWindow::open); + fileMenu->addAction(openAct); + fileToolBar->addAction(openAct); - saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); + const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png")); + QAction *saveAct = new QAction(saveIcon, tr("&Save"), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); + fileMenu->addAction(saveAct); + fileToolBar->addAction(saveAct); - saveAsAct = new QAction(tr("Save &As..."), this); + const QIcon saveAsIcon = QIcon::fromTheme("document-save-as"); + QAction *saveAsAct = fileMenu->addAction(saveAsIcon, tr("Save &As..."), this, &MainWindow::saveAs); saveAsAct->setShortcuts(QKeySequence::SaveAs); saveAsAct->setStatusTip(tr("Save the document under a new name")); - connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); - closeAct = new QAction(tr("&Close"), this); + fileMenu->addSeparator(); + + QMenu *recentMenu = fileMenu->addMenu(tr("Recent...")); + connect(recentMenu, &QMenu::aboutToShow, this, &MainWindow::updateRecentFileActions); + recentFileSubMenuAct = recentMenu->menuAction(); + + for (int i = 0; i < MaxRecentFiles; ++i) { + recentFileActs[i] = recentMenu->addAction(QString(), this, &MainWindow::openRecentFile); + recentFileActs[i]->setVisible(false); + } + + recentFileSeparator = fileMenu->addSeparator(); + + setRecentFilesVisible(MainWindow::hasRecentFiles()); + + QAction *closeAct = fileMenu->addAction(tr("&Close"), this, &QWidget::close); closeAct->setShortcut(tr("Ctrl+W")); closeAct->setStatusTip(tr("Close this window")); - connect(closeAct, SIGNAL(triggered()), this, SLOT(close())); - exitAct = new QAction(tr("E&xit"), this); + const QIcon exitIcon = QIcon::fromTheme("application-exit"); + QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), qApp, &QApplication::closeAllWindows); exitAct->setShortcuts(QKeySequence::Quit); exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); - cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this); + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + QToolBar *editToolBar = addToolBar(tr("Edit")); + + const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png")); + QAction *cutAct = new QAction(cutIcon, tr("Cu&t"), this); cutAct->setShortcuts(QKeySequence::Cut); cutAct->setStatusTip(tr("Cut the current selection's contents to the " "clipboard")); - connect(cutAct, SIGNAL(triggered()), textEdit, SLOT(cut())); + connect(cutAct, &QAction::triggered, textEdit, &QTextEdit::cut); + editMenu->addAction(cutAct); + editToolBar->addAction(cutAct); - copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this); + const QIcon copyIcon = QIcon::fromTheme("edit-copy", QIcon(":/images/copy.png")); + QAction *copyAct = new QAction(copyIcon, tr("&Copy"), this); copyAct->setShortcuts(QKeySequence::Copy); copyAct->setStatusTip(tr("Copy the current selection's contents to the " "clipboard")); - connect(copyAct, SIGNAL(triggered()), textEdit, SLOT(copy())); + connect(copyAct, &QAction::triggered, textEdit, &QTextEdit::copy); + editMenu->addAction(copyAct); + editToolBar->addAction(copyAct); - pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this); + const QIcon pasteIcon = QIcon::fromTheme("edit-paste", QIcon(":/images/paste.png")); + QAction *pasteAct = new QAction(pasteIcon, tr("&Paste"), this); pasteAct->setShortcuts(QKeySequence::Paste); pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " "selection")); - connect(pasteAct, SIGNAL(triggered()), textEdit, SLOT(paste())); + connect(pasteAct, &QAction::triggered, textEdit, &QTextEdit::paste); + editMenu->addAction(pasteAct); + editToolBar->addAction(pasteAct); + + menuBar()->addSeparator(); - aboutAct = new QAction(tr("&About"), this); + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); + QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about); aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - aboutQtAct = new QAction(tr("About &Qt"), this); + QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); - cutAct->setEnabled(false); copyAct->setEnabled(false); - connect(textEdit, SIGNAL(copyAvailable(bool)), - cutAct, SLOT(setEnabled(bool))); - connect(textEdit, SIGNAL(copyAvailable(bool)), - copyAct, SLOT(setEnabled(bool))); -} - -//! [implicit tr context] -void MainWindow::createMenus() -{ - fileMenu = menuBar()->addMenu(tr("&File")); -//! [implicit tr context] - fileMenu->addAction(newAct); - fileMenu->addAction(openAct); - fileMenu->addAction(saveAct); - fileMenu->addAction(saveAsAct); - fileMenu->addSeparator(); - fileMenu->addAction(closeAct); - fileMenu->addAction(exitAct); - - editMenu = menuBar()->addMenu(tr("&Edit")); - editMenu->addAction(cutAct); - editMenu->addAction(copyAct); - editMenu->addAction(pasteAct); - - menuBar()->addSeparator(); - - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} - -void MainWindow::createToolBars() -{ -//! [0] - fileToolBar = addToolBar(tr("File")); - fileToolBar->addAction(newAct); - fileToolBar->addAction(openAct); -//! [0] - fileToolBar->addAction(saveAct); - - editToolBar = addToolBar(tr("Edit")); - editToolBar->addAction(cutAct); - editToolBar->addAction(copyAct); - editToolBar->addAction(pasteAct); + connect(textEdit, &QTextEdit::copyAvailable, cutAct, &QAction::setEnabled); + connect(textEdit, &QTextEdit::copyAvailable, copyAct, &QAction::setEnabled); } void MainWindow::createStatusBar() @@ -265,33 +273,41 @@ void MainWindow::createStatusBar() void MainWindow::readSettings() { - QSettings settings; - QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); - QSize size = settings.value("size", QSize(400, 400)).toSize(); - move(pos); - resize(size); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray(); + if (geometry.isEmpty()) { + const QRect availableGeometry = QApplication::desktop()->availableGeometry(this); + resize(availableGeometry.width() / 3, availableGeometry.height() / 2); + move((availableGeometry.width() - width()) / 2, + (availableGeometry.height() - height()) / 2); + } else { + restoreGeometry(geometry); + } } void MainWindow::writeSettings() { - QSettings settings; - settings.setValue("pos", pos()); - settings.setValue("size", size()); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + settings.setValue("geometry", saveGeometry()); } bool MainWindow::maybeSave() { - if (textEdit->document()->isModified()) { - QMessageBox::StandardButton ret; - ret = QMessageBox::warning(this, tr("SDI"), - tr("The document has been modified.\n" - "Do you want to save your changes?"), - QMessageBox::Save | QMessageBox::Discard - | QMessageBox::Cancel); - if (ret == QMessageBox::Save) - return save(); - else if (ret == QMessageBox::Cancel) - return false; + if (!textEdit->document()->isModified()) + return true; + const QMessageBox::StandardButton ret + = QMessageBox::warning(this, tr("SDI"), + tr("The document has been modified.\n" + "Do you want to save your changes?"), + QMessageBox::Save | QMessageBox::Discard + | QMessageBox::Cancel); + switch (ret) { + case QMessageBox::Save: + return save(); + case QMessageBox::Cancel: + return false; + default: + break; } return true; } @@ -303,8 +319,7 @@ void MainWindow::loadFile(const QString &fileName) if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(this, tr("SDI"), tr("Cannot read file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return; } @@ -317,14 +332,90 @@ void MainWindow::loadFile(const QString &fileName) statusBar()->showMessage(tr("File loaded"), 2000); } +void MainWindow::setRecentFilesVisible(bool visible) +{ + recentFileSubMenuAct->setVisible(visible); + recentFileSeparator->setVisible(visible); +} + +static inline QString recentFilesKey() { return QStringLiteral("recentFileList"); } +static inline QString fileKey() { return QStringLiteral("file"); } + +static QStringList readRecentFiles(QSettings &settings) +{ + QStringList result; + const int count = settings.beginReadArray(recentFilesKey()); + for (int i = 0; i < count; ++i) { + settings.setArrayIndex(i); + result.append(settings.value(fileKey()).toString()); + } + settings.endArray(); + return result; +} + +static void writeRecentFiles(const QStringList &files, QSettings &settings) +{ + const int count = files.size(); + settings.beginWriteArray(recentFilesKey()); + for (int i = 0; i < count; ++i) { + settings.setArrayIndex(i); + settings.setValue(fileKey(), files.at(i)); + } + settings.endArray(); +} + +bool MainWindow::hasRecentFiles() +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const int count = settings.beginReadArray(recentFilesKey()); + settings.endArray(); + return count > 0; +} + +void MainWindow::prependToRecentFiles(const QString &fileName) +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + + const QStringList oldRecentFiles = readRecentFiles(settings); + QStringList recentFiles = oldRecentFiles; + recentFiles.removeAll(fileName); + recentFiles.prepend(fileName); + if (oldRecentFiles != recentFiles) + writeRecentFiles(recentFiles, settings); + + setRecentFilesVisible(!recentFiles.isEmpty()); +} + +void MainWindow::updateRecentFileActions() +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + + const QStringList recentFiles = readRecentFiles(settings); + const int count = qMin(int(MaxRecentFiles), recentFiles.size()); + int i = 0; + for ( ; i < count; ++i) { + const QString fileName = MainWindow::strippedName(recentFiles.at(i)); + recentFileActs[i]->setText(tr("&%1 %2").arg(i + 1).arg(fileName)); + recentFileActs[i]->setData(recentFiles.at(i)); + recentFileActs[i]->setVisible(true); + } + for ( ; i < MaxRecentFiles; ++i) + recentFileActs[i]->setVisible(false); +} + +void MainWindow::openRecentFile() +{ + if (const QAction *action = qobject_cast<const QAction *>(sender())) + openFile(action->data().toString()); +} + bool MainWindow::saveFile(const QString &fileName) { QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("SDI"), tr("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return false; } @@ -351,6 +442,10 @@ void MainWindow::setCurrentFile(const QString &fileName) textEdit->document()->setModified(false); setWindowModified(false); + + if (!isUntitled && windowFilePath() != curFile) + MainWindow::prependToRecentFiles(curFile); + setWindowFilePath(curFile); } @@ -359,14 +454,15 @@ QString MainWindow::strippedName(const QString &fullFileName) return QFileInfo(fullFileName).fileName(); } -MainWindow *MainWindow::findMainWindow(const QString &fileName) +MainWindow *MainWindow::findMainWindow(const QString &fileName) const { QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath(); - foreach (QWidget *widget, qApp->topLevelWidgets()) { + foreach (QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast<MainWindow *>(widget); if (mainWin && mainWin->curFile == canonicalFilePath) return mainWin; } + return 0; } diff --git a/examples/widgets/mainwindows/sdi/mainwindow.h b/examples/widgets/mainwindows/sdi/mainwindow.h index f1860a85116cd893cd07c6010cab4ffb5667a573..66ac618c72ec21ec53646ee1b9c813f40dbd71e3 100644 --- a/examples/widgets/mainwindows/sdi/mainwindow.h +++ b/examples/widgets/mainwindows/sdi/mainwindow.h @@ -42,6 +42,7 @@ #define MAINWINDOW_H #include <QMainWindow> +#include <QList> QT_BEGIN_NAMESPACE class QAction; @@ -57,7 +58,9 @@ class MainWindow : public QMainWindow public: MainWindow(); //! [class definition with macro] - MainWindow(const QString &fileName); + explicit MainWindow(const QString &fileName); + + void tile(const QMainWindow *previous); protected: void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; @@ -67,44 +70,38 @@ private slots: void open(); bool save(); bool saveAs(); + void updateRecentFileActions(); + void openRecentFile(); void about(); void documentWasModified(); private: + enum { MaxRecentFiles = 5 }; + void init(); void createActions(); - void createMenus(); - void createToolBars(); void createStatusBar(); void readSettings(); void writeSettings(); bool maybeSave(); + void openFile(const QString &fileName); void loadFile(const QString &fileName); + static bool hasRecentFiles(); + void prependToRecentFiles(const QString &fileName); + void setRecentFilesVisible(bool visible); bool saveFile(const QString &fileName); void setCurrentFile(const QString &fileName); - QString strippedName(const QString &fullFileName); - MainWindow *findMainWindow(const QString &fileName); + static QString strippedName(const QString &fullFileName); + MainWindow *findMainWindow(const QString &fileName) const; QTextEdit *textEdit; + + QAction *recentFileActs[MaxRecentFiles]; + QAction *recentFileSeparator; + QAction *recentFileSubMenuAct; + QString curFile; bool isUntitled; - - QMenu *fileMenu; - QMenu *editMenu; - QMenu *helpMenu; - QToolBar *fileToolBar; - QToolBar *editToolBar; - QAction *newAct; - QAction *openAct; - QAction *saveAct; - QAction *saveAsAct; - QAction *closeAct; - QAction *exitAct; - QAction *cutAct; - QAction *copyAct; - QAction *pasteAct; - QAction *aboutAct; - QAction *aboutQtAct; }; #endif diff --git a/examples/widgets/painting/affine/affine.pro b/examples/widgets/painting/affine/affine.pro index 1f2f8df87f1c2112b22f5931168089435ac5877f..be6a83960df0deafcde02f654ad1ea5ca87aa604 100644 --- a/examples/widgets/painting/affine/affine.pro +++ b/examples/widgets/painting/affine/affine.pro @@ -17,6 +17,6 @@ RESOURCES += affine.qrc target.path = $$[QT_INSTALL_EXAMPLES]/widgets/painting/affine INSTALLS += target -wince*: { +wince { DEPLOYMENT_PLUGIN += qjpeg } diff --git a/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pro b/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pro index 809667b2ad9df02156305f83bba187be7a26a6e3..93cd950b0b66ea4145729d9c71dfd88fb335c046 100644 --- a/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pro +++ b/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pro @@ -11,7 +11,7 @@ target.path = $$[QT_INSTALL_EXAMPLES]/widgets/richtext/syntaxhighlighter INSTALLS += target -wince*: { +wince { addFiles.files = main.cpp mainwindow.cpp addFiles.path = . INSTALLS += addFiles diff --git a/examples/widgets/tutorials/widgets/childwidget/main.cpp b/examples/widgets/tutorials/widgets/childwidget/main.cpp index b89e6f1c4aa4298ab5b44c0ee2a7ef1154ccb3b2..84fcf1ea809d26afca76f8bab993312b83cf619f 100644 --- a/examples/widgets/tutorials/widgets/childwidget/main.cpp +++ b/examples/widgets/tutorials/widgets/childwidget/main.cpp @@ -46,7 +46,8 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); QWidget window; window.resize(320, 240); - window.setWindowTitle(QApplication::translate("childwidget", "Child widget")); + window.setWindowTitle + (QApplication::translate("childwidget", "Child widget")); window.show(); //! [create, position and show] diff --git a/examples/widgets/widgets/icons/icons.pro b/examples/widgets/widgets/icons/icons.pro index 58e6c2137c9a50e07547d95c8ae548673a2c5d0c..4312a40e95d2ffaa018adb53de8ce95356274950 100644 --- a/examples/widgets/widgets/icons/icons.pro +++ b/examples/widgets/widgets/icons/icons.pro @@ -17,7 +17,7 @@ target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/icons INSTALLS += target -wince*: { +wince { imageFiles.files = images/* wincewm*: { imageFiles.path = "/My Documents/My Pictures" diff --git a/examples/widgets/widgets/imageviewer/imageviewer.cpp b/examples/widgets/widgets/imageviewer/imageviewer.cpp index 0b8513f0907381226bb2b2bb67093568c46cbeb3..93b88e9c1855638e192554c5ef5ccc8fcd4ccf90 100644 --- a/examples/widgets/widgets/imageviewer/imageviewer.cpp +++ b/examples/widgets/widgets/imageviewer/imageviewer.cpp @@ -69,7 +69,9 @@ ImageViewer::ImageViewer() bool ImageViewer::loadFile(const QString &fileName) { - QImage image(fileName); + QImageReader reader(fileName); + reader.setAutoTransform(true); + const QImage image = reader.read(); if (image.isNull()) { QMessageBox::information(this, QGuiApplication::applicationDisplayName(), tr("Cannot load %1.").arg(QDir::toNativeSeparators(fileName))); diff --git a/examples/widgets/widgets/imageviewer/imageviewer.pro b/examples/widgets/widgets/imageviewer/imageviewer.pro index 6c9d4a715afd9d22138f0ad2b424f61ac6692bf6..2853f1699fea56322c7c7cd1d44a4eb5b6090141 100644 --- a/examples/widgets/widgets/imageviewer/imageviewer.pro +++ b/examples/widgets/widgets/imageviewer/imageviewer.pro @@ -10,6 +10,6 @@ target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/imageviewer INSTALLS += target -wince*: { +wince { DEPLOYMENT_PLUGIN += qjpeg qgif } diff --git a/examples/widgets/widgets/movie/movie.pro b/examples/widgets/widgets/movie/movie.pro index 58925c98a02acad5ff3568f18e62c17e4eba0be6..94d86454d886f20b54d21a06736141afceb3bd19 100644 --- a/examples/widgets/widgets/movie/movie.pro +++ b/examples/widgets/widgets/movie/movie.pro @@ -11,7 +11,7 @@ target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/movie INSTALLS += target -wince*: { +wince { addFiles.files += *.gif addFiles.path = . INSTALLS += addFiles diff --git a/examples/widgets/widgets/tablet/images.qrc b/examples/widgets/widgets/tablet/images.qrc new file mode 100644 index 0000000000000000000000000000000000000000..eb3eabbace06345b74a8e1df3431984f61ad496f --- /dev/null +++ b/examples/widgets/widgets/tablet/images.qrc @@ -0,0 +1,8 @@ +<RCC> + <qresource> + <file>images/cursor-airbrush.png</file> + <file>images/cursor-eraser.png</file> + <file>images/cursor-felt-marker.png</file> + <file>images/cursor-pencil.png</file> + </qresource> +</RCC> diff --git a/examples/widgets/widgets/tablet/images/cursor-airbrush.png b/examples/widgets/widgets/tablet/images/cursor-airbrush.png new file mode 100644 index 0000000000000000000000000000000000000000..bea756ed6f520b3a9fe08de50fb093ad2f98fb55 Binary files /dev/null and b/examples/widgets/widgets/tablet/images/cursor-airbrush.png differ diff --git a/examples/widgets/widgets/tablet/images/cursor-eraser.png b/examples/widgets/widgets/tablet/images/cursor-eraser.png new file mode 100644 index 0000000000000000000000000000000000000000..e5488a89f2403e4eb311909d8a2e8394d18444d4 Binary files /dev/null and b/examples/widgets/widgets/tablet/images/cursor-eraser.png differ diff --git a/examples/widgets/widgets/tablet/images/cursor-felt-marker.png b/examples/widgets/widgets/tablet/images/cursor-felt-marker.png new file mode 100644 index 0000000000000000000000000000000000000000..132f09aa391ba1912d1ac581dfe9c27f19a2fb67 Binary files /dev/null and b/examples/widgets/widgets/tablet/images/cursor-felt-marker.png differ diff --git a/examples/widgets/widgets/tablet/images/cursor-pencil.png b/examples/widgets/widgets/tablet/images/cursor-pencil.png new file mode 100644 index 0000000000000000000000000000000000000000..cc2f447d02481b5eb930a8d94fd3e27fe641e23f Binary files /dev/null and b/examples/widgets/widgets/tablet/images/cursor-pencil.png differ diff --git a/examples/widgets/widgets/tablet/mainwindow.cpp b/examples/widgets/widgets/tablet/mainwindow.cpp index aed84c50df02c4ec587f4bb95bfe45b2a36100cb..5e84f5b6a2ef52164fb20545039d189781e700c8 100644 --- a/examples/widgets/widgets/tablet/mainwindow.cpp +++ b/examples/widgets/widgets/tablet/mainwindow.cpp @@ -52,7 +52,7 @@ MainWindow::MainWindow(TabletCanvas *canvas) myCanvas->setColor(Qt::red); myCanvas->setLineWidthType(TabletCanvas::LineWidthPressure); - myCanvas->setAlphaChannelType(TabletCanvas::NoAlpha); + myCanvas->setAlphaChannelType(TabletCanvas::AlphaTangentialPressure); myCanvas->setColorSaturationType(TabletCanvas::NoSaturation); setWindowTitle(tr("Tablet Example")); @@ -75,6 +75,8 @@ void MainWindow::alphaActionTriggered(QAction *action) { if (action == alphaChannelPressureAction) { myCanvas->setAlphaChannelType(TabletCanvas::AlphaPressure); + } else if (action == alphaChannelTangentialPressureAction) { + myCanvas->setAlphaChannelType(TabletCanvas::AlphaTangentialPressure); } else if (action == alphaChannelTiltAction) { myCanvas->setAlphaChannelType(TabletCanvas::AlphaTilt); } else { @@ -157,15 +159,19 @@ void MainWindow::createActions() alphaChannelPressureAction = new QAction(tr("&Pressure"), this); alphaChannelPressureAction->setCheckable(true); + alphaChannelTangentialPressureAction = new QAction(tr("T&angential Pressure"), this); + alphaChannelTangentialPressureAction->setCheckable(true); + alphaChannelTangentialPressureAction->setChecked(true); + alphaChannelTiltAction = new QAction(tr("&Tilt"), this); alphaChannelTiltAction->setCheckable(true); noAlphaChannelAction = new QAction(tr("No Alpha Channel"), this); noAlphaChannelAction->setCheckable(true); - noAlphaChannelAction->setChecked(true); alphaChannelGroup = new QActionGroup(this); alphaChannelGroup->addAction(alphaChannelPressureAction); + alphaChannelGroup->addAction(alphaChannelTangentialPressureAction); alphaChannelGroup->addAction(alphaChannelTiltAction); alphaChannelGroup->addAction(noAlphaChannelAction); connect(alphaChannelGroup, SIGNAL(triggered(QAction*)), @@ -259,6 +265,7 @@ void MainWindow::createMenus() alphaChannelMenu = tabletMenu->addMenu(tr("&Alpha Channel")); alphaChannelMenu->addAction(alphaChannelPressureAction); + alphaChannelMenu->addAction(alphaChannelTangentialPressureAction); alphaChannelMenu->addAction(alphaChannelTiltAction); alphaChannelMenu->addAction(noAlphaChannelAction); diff --git a/examples/widgets/widgets/tablet/mainwindow.h b/examples/widgets/widgets/tablet/mainwindow.h index 5e77ea1acfd8c4f543dd0ded35ed511767a2a4d4..c6ac2e60267e667de8a40025cfb64c9ce773985e 100644 --- a/examples/widgets/widgets/tablet/mainwindow.h +++ b/examples/widgets/widgets/tablet/mainwindow.h @@ -79,6 +79,7 @@ private: QActionGroup *alphaChannelGroup; QAction *alphaChannelPressureAction; + QAction *alphaChannelTangentialPressureAction; QAction *alphaChannelTiltAction; QAction *noAlphaChannelAction; diff --git a/examples/widgets/widgets/tablet/tablet.pro b/examples/widgets/widgets/tablet/tablet.pro index de81e7b198b1837ba3fa0d5e0471ab19cb57e75f..9b8927f483bc9ae26f7430408c99ecfa9001f934 100644 --- a/examples/widgets/widgets/tablet/tablet.pro +++ b/examples/widgets/widgets/tablet/tablet.pro @@ -1,12 +1,13 @@ QT += widgets HEADERS = mainwindow.h \ - tabletcanvas.h \ - tabletapplication.h + tabletcanvas.h \ + tabletapplication.h SOURCES = mainwindow.cpp \ - main.cpp \ - tabletcanvas.cpp \ - tabletapplication.cpp + main.cpp \ + tabletcanvas.cpp \ + tabletapplication.cpp +RESOURCES += images.qrc # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/tablet diff --git a/examples/widgets/widgets/tablet/tabletapplication.cpp b/examples/widgets/widgets/tablet/tabletapplication.cpp index c3210f822c79a2b0f22f8dfc1b12b559b8ac1dab..3e1356ee9cc851343f0ac7ccc002b7bcd89b5e67 100644 --- a/examples/widgets/widgets/tablet/tabletapplication.cpp +++ b/examples/widgets/widgets/tablet/tabletapplication.cpp @@ -47,8 +47,7 @@ bool TabletApplication::event(QEvent *event) { if (event->type() == QEvent::TabletEnterProximity || event->type() == QEvent::TabletLeaveProximity) { - myCanvas->setTabletDevice( - static_cast<QTabletEvent *>(event)->device()); + myCanvas->setTabletDevice(static_cast<QTabletEvent *>(event)); return true; } return QApplication::event(event); diff --git a/examples/widgets/widgets/tablet/tabletcanvas.cpp b/examples/widgets/widgets/tablet/tabletcanvas.cpp index 20d6291292dda2d83b2892414996b1772c7491ea..8ff3d41e0e6dbc6ccc174f368a9e0fb5c1c383ac 100644 --- a/examples/widgets/widgets/tablet/tabletcanvas.cpp +++ b/examples/widgets/widgets/tablet/tabletcanvas.cpp @@ -47,14 +47,13 @@ TabletCanvas::TabletCanvas() { resize(500, 500); - myBrush = QBrush(); - myPen = QPen(); + myColor = Qt::red; + myBrush = QBrush(myColor); + myPen = QPen(myBrush, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); initPixmap(); setAutoFillBackground(true); deviceDown = false; - myColor = Qt::red; - myTabletDevice = QTabletEvent::Stylus; - alphaChannelType = NoAlpha; + alphaChannelType = AlphaTangentialPressure; colorSaturationType = NoSaturation; lineWidthType = LineWidthPressure; } @@ -99,24 +98,25 @@ void TabletCanvas::tabletEvent(QTabletEvent *event) case QEvent::TabletPress: if (!deviceDown) { deviceDown = true; - polyLine[0] = polyLine[1] = polyLine[2] = event->pos(); + lastPoint.pos = event->posF(); + lastPoint.rotation = event->rotation(); } break; - case QEvent::TabletRelease: - if (deviceDown) - deviceDown = false; - break; case QEvent::TabletMove: - polyLine[2] = polyLine[1]; - polyLine[1] = polyLine[0]; - polyLine[0] = event->pos(); - + if (event->device() == QTabletEvent::RotationStylus) + updateCursor(event); if (deviceDown) { updateBrush(event); QPainter painter(&pixmap); paintPixmap(painter, event); + lastPoint.pos = event->posF(); + lastPoint.rotation = event->rotation(); } break; + case QEvent::TabletRelease: + if (deviceDown && event->buttons() == Qt::NoButton) + deviceDown = false; + break; default: break; } @@ -135,23 +135,44 @@ void TabletCanvas::paintEvent(QPaintEvent *) //! [5] void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event) { - QPoint brushAdjust(10, 10); + painter.setRenderHint(QPainter::Antialiasing); - switch (myTabletDevice) { + switch (event->device()) { +//! [6] case QTabletEvent::Airbrush: - myBrush.setColor(myColor); - myBrush.setStyle(brushPattern(event->pressure())); - painter.setPen(Qt::NoPen); - painter.setBrush(myBrush); - - for (int i = 0; i < 3; ++i) { - painter.drawEllipse(QRect(polyLine[i] - brushAdjust, - polyLine[i] + brushAdjust)); + { + painter.setPen(Qt::NoPen); + QRadialGradient grad(lastPoint.pos, myPen.widthF() * 10.0); + QColor color = myBrush.color(); + color.setAlphaF(color.alphaF() * 0.25); + grad.setColorAt(0, myBrush.color()); + grad.setColorAt(0.5, Qt::transparent); + painter.setBrush(grad); + qreal radius = grad.radius(); + painter.drawEllipse(event->posF(), radius, radius); + } + break; + case QTabletEvent::RotationStylus: + { + myBrush.setStyle(Qt::SolidPattern); + painter.setPen(Qt::NoPen); + painter.setBrush(myBrush); + QPolygonF poly; + qreal halfWidth = myPen.widthF(); + QPointF brushAdjust(qSin(qDegreesToRadians(lastPoint.rotation)) * halfWidth, + qCos(qDegreesToRadians(lastPoint.rotation)) * halfWidth); + poly << lastPoint.pos + brushAdjust; + poly << lastPoint.pos - brushAdjust; + brushAdjust = QPointF(qSin(qDegreesToRadians(event->rotation())) * halfWidth, + qCos(qDegreesToRadians(event->rotation())) * halfWidth); + poly << event->posF() - brushAdjust; + poly << event->posF() + brushAdjust; + painter.drawConvexPolygon(poly); } break; +//! [6] case QTabletEvent::Puck: case QTabletEvent::FourDMouse: - case QTabletEvent::RotationStylus: { const QString error(tr("This input device is not supported by the example.")); #ifndef QT_NO_STATUSTIP @@ -174,42 +195,15 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event) } // FALL-THROUGH case QTabletEvent::Stylus: - painter.setBrush(myBrush); painter.setPen(myPen); - painter.drawLine(polyLine[1], event->pos()); + painter.drawLine(lastPoint.pos, event->posF()); break; } } //! [5] -//! [6] -Qt::BrushStyle TabletCanvas::brushPattern(qreal value) -{ - int pattern = int((value) * 100.0) % 7; - - switch (pattern) { - case 0: - return Qt::SolidPattern; - case 1: - return Qt::Dense1Pattern; - case 2: - return Qt::Dense2Pattern; - case 3: - return Qt::Dense3Pattern; - case 4: - return Qt::Dense4Pattern; - case 5: - return Qt::Dense5Pattern; - case 6: - return Qt::Dense6Pattern; - default: - return Qt::Dense7Pattern; - } -} -//! [6] - //! [7] -void TabletCanvas::updateBrush(QTabletEvent *event) +void TabletCanvas::updateBrush(const QTabletEvent *event) { int hue, saturation, value, alpha; myColor.getHsv(&hue, &saturation, &value, &alpha); @@ -220,7 +214,13 @@ void TabletCanvas::updateBrush(QTabletEvent *event) switch (alphaChannelType) { case AlphaPressure: - myColor.setAlpha(int(event->pressure() * 255.0)); + myColor.setAlphaF(event->pressure()); + break; + case AlphaTangentialPressure: + if (event->device() == QTabletEvent::Airbrush) + myColor.setAlphaF(qMax(0.01, (event->tangentialPressure() + 1.0) / 2.0)); + else + myColor.setAlpha(255); break; case AlphaTilt: myColor.setAlpha(maximum(abs(vValue - 127), abs(hValue - 127))); @@ -268,8 +268,47 @@ void TabletCanvas::updateBrush(QTabletEvent *event) } //! [11] +void TabletCanvas::updateCursor(const QTabletEvent *event) +{ + QCursor cursor; + if (event->type() != QEvent::TabletLeaveProximity) { + if (event->pointerType() == QTabletEvent::Eraser) { + cursor = QCursor(QPixmap(":/images/cursor-eraser.png"), 3, 28); + } else { + switch (event->device()) { + case QTabletEvent::Stylus: + cursor = QCursor(QPixmap(":/images/cursor-pencil.png"), 0, 0); + break; + case QTabletEvent::Airbrush: + cursor = QCursor(QPixmap(":/images/cursor-airbrush.png"), 3, 4); + break; + case QTabletEvent::RotationStylus: { + QImage origImg(QLatin1String(":/images/cursor-felt-marker.png")); + QImage img(32, 32, QImage::Format_ARGB32); + QColor solid = myColor; + solid.setAlpha(255); + img.fill(solid); + QPainter painter(&img); + QTransform transform = painter.transform(); + transform.translate(16, 16); + transform.rotate(-event->rotation()); + painter.setTransform(transform); + painter.setCompositionMode(QPainter::CompositionMode_DestinationIn); + painter.drawImage(-24, -24, origImg); + painter.setCompositionMode(QPainter::CompositionMode_HardLight); + painter.drawImage(-24, -24, origImg); + painter.end(); + cursor = QCursor(QPixmap::fromImage(img), 16, 16); + } break; + default: + break; + } + } + } + setCursor(cursor); +} + void TabletCanvas::resizeEvent(QResizeEvent *) { initPixmap(); - polyLine[0] = polyLine[1] = polyLine[2] = QPoint(); } diff --git a/examples/widgets/widgets/tablet/tabletcanvas.h b/examples/widgets/widgets/tablet/tabletcanvas.h index 873f3a7ab05b9cbaddf6b04bb9818b26517fb569..a7335dbaf0b914eb3889738877ca9bc9ed6f9ce4 100644 --- a/examples/widgets/widgets/tablet/tabletcanvas.h +++ b/examples/widgets/widgets/tablet/tabletcanvas.h @@ -61,7 +61,7 @@ class TabletCanvas : public QWidget Q_OBJECT public: - enum AlphaChannelType { AlphaPressure, AlphaTilt, NoAlpha }; + enum AlphaChannelType { AlphaPressure, AlphaTangentialPressure, AlphaTilt, NoAlpha }; enum ColorSaturationType { SaturationVTilt, SaturationHTilt, SaturationPressure, NoSaturation }; enum LineWidthType { LineWidthPressure, LineWidthTilt, NoLineWidth }; @@ -80,8 +80,8 @@ public: { myColor = color; } QColor color() const { return myColor; } - void setTabletDevice(QTabletEvent::TabletDevice device) - { myTabletDevice = device; } + void setTabletDevice(QTabletEvent *event) + { myTabletDevice = event->device(); updateCursor(event); } int maximum(int a, int b) { return a > b ? a : b; } @@ -94,7 +94,8 @@ private: void initPixmap(); void paintPixmap(QPainter &painter, QTabletEvent *event); Qt::BrushStyle brushPattern(qreal value); - void updateBrush(QTabletEvent *event); + void updateBrush(const QTabletEvent *event); + void updateCursor(const QTabletEvent *event); AlphaChannelType alphaChannelType; ColorSaturationType colorSaturationType; @@ -107,7 +108,11 @@ private: QBrush myBrush; QPen myPen; bool deviceDown; - QPoint polyLine[3]; + + struct Point { + QPointF pos; + qreal rotation; + } lastPoint; }; //! [0] diff --git a/examples/xml/dombookmarks/dombookmarks.pro b/examples/xml/dombookmarks/dombookmarks.pro index a16cdadcfab11243d8d03151fb99307db9d2d37a..0ab4f0266d6c44c87279f8068aeda6162c7b319d 100644 --- a/examples/xml/dombookmarks/dombookmarks.pro +++ b/examples/xml/dombookmarks/dombookmarks.pro @@ -11,7 +11,7 @@ EXAMPLE_FILES = frank.xbel jennifer.xbel target.path = $$[QT_INSTALL_EXAMPLES]/xml/dombookmarks INSTALLS += target -wince*: { +wince { addFiles.files = frank.xbel jennifer.xbel addFiles.path = "\\My Documents" INSTALLS += addFiles diff --git a/examples/xml/htmlinfo/htmlinfo.pro b/examples/xml/htmlinfo/htmlinfo.pro index 4ad40213fe5d8dd5163c78178f801731d10421e5..8adaa780b8f90fcbdb3b95ea5a6cefd94881922a 100644 --- a/examples/xml/htmlinfo/htmlinfo.pro +++ b/examples/xml/htmlinfo/htmlinfo.pro @@ -6,7 +6,7 @@ RESOURCES = resources.qrc win32: CONFIG += console -wince*:{ +wince { htmlfiles.files = *.html htmlfiles.path = . INSTALLS += htmlfiles diff --git a/examples/xml/saxbookmarks/saxbookmarks.pro b/examples/xml/saxbookmarks/saxbookmarks.pro index aa84ee4f3ed13f1667e9466fe9747961ba2d6809..96a48ef5d4002c24d43cfe77197e969189f72bc3 100644 --- a/examples/xml/saxbookmarks/saxbookmarks.pro +++ b/examples/xml/saxbookmarks/saxbookmarks.pro @@ -13,7 +13,7 @@ EXAMPLE_FILES = frank.xbel jennifer.xbel target.path = $$[QT_INSTALL_EXAMPLES]/xml/saxbookmarks INSTALLS += target -wince*: { +wince { addFiles.files = frank.xbel jennifer.xbel addFiles.path = "\\My Documents" INSTALLS += addFiles diff --git a/mkspecs/common/clang-mac.conf b/mkspecs/common/clang-mac.conf index 3280274f3694e2fc77e5273a965f45f16530e4b6..1e51142f021b4c5954415b72a258c0e9f93355cd 100644 --- a/mkspecs/common/clang-mac.conf +++ b/mkspecs/common/clang-mac.conf @@ -7,4 +7,6 @@ QMAKE_OBJCXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE QMAKE_XCODE_GCC_VERSION = com.apple.compilers.llvm.clang.1_0 QMAKE_CXXFLAGS_CXX11 += -stdlib=libc++ +QMAKE_CXXFLAGS_GNUCXX11 += -stdlib=libc++ QMAKE_LFLAGS_CXX11 += -stdlib=libc++ +QMAKE_LFLAGS_GNUCXX11+= -stdlib=libc++ diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf index a0a2b3f3d1fd78433eaa9abd1b15aa30d2bd4440..ee5fc144586a168e0e1d02df88fa2fc4da0c982a 100644 --- a/mkspecs/common/clang.conf +++ b/mkspecs/common/clang.conf @@ -27,6 +27,7 @@ QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG QMAKE_CXXFLAGS_DISABLE_LTCG = $$QMAKE_CFLAGS_DISABLE_LTCG QMAKE_CXXFLAGS_CXX11 = -std=c++11 +QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11 QMAKE_LFLAGS_CXX11 = QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG diff --git a/mkspecs/common/g++-base.conf b/mkspecs/common/g++-base.conf index d687dbc3f32b7c5a022a1451af0bb8d76cdf8a72..114a4416879f612c6d75b35dccba2f8d964125a7 100644 --- a/mkspecs/common/g++-base.conf +++ b/mkspecs/common/g++-base.conf @@ -28,4 +28,5 @@ QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_P QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE QMAKE_CXXFLAGS_CXX11 = -std=c++0x +QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++0x QMAKE_LFLAGS_CXX11 = diff --git a/mkspecs/common/ios/clang.conf b/mkspecs/common/ios/clang.conf index 8da555e6fa28630ae4747d3bf6fe48b4e936544c..36cb655229d38a36e2e11ede5d9c3158e7768f36 100644 --- a/mkspecs/common/ios/clang.conf +++ b/mkspecs/common/ios/clang.conf @@ -6,7 +6,6 @@ QMAKE_IOS_CFLAGS += -fvisibility=hidden -fpascal-strings -fmessage-length=0 QMAKE_IOS_CFLAGS += -Wno-trigraphs -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -Wno-sign-conversion QMAKE_IOS_CXXFLAGS += -fvisibility-inlines-hidden -QMAKE_IOS_OBJ_CFLAGS += -Wno-arc-abi # Based on the following information, http://clang.llvm.org/doxygen/ObjCRuntime_8h_source.html, # we can conclude that it's safe to always pass the following flags diff --git a/mkspecs/common/msvc-desktop.conf b/mkspecs/common/msvc-desktop.conf index e638af6b6afcd99856d2afaa06f0f0fbea71410d..e1abca46e49ff31457e202a8090c6bcb3eb436f7 100644 --- a/mkspecs/common/msvc-desktop.conf +++ b/mkspecs/common/msvc-desktop.conf @@ -23,7 +23,7 @@ contains(QMAKE_TARGET.arch, x86_64) { QMAKE_CC = cl QMAKE_LEX = flex QMAKE_LEXFLAGS = -QMAKE_YACC = byacc +QMAKE_YACC = bison -y QMAKE_YACCFLAGS = -d QMAKE_CFLAGS = -nologo -Zc:wchar_t QMAKE_CFLAGS_WARN_ON = -W3 diff --git a/mkspecs/common/wince/qmake.conf b/mkspecs/common/wince/qmake.conf index 434e063de8157f7b47e6d24e8af0e411b7731189..3eac38f6b7429ba9eada3eb8a4e6a5e476b186e0 100644 --- a/mkspecs/common/wince/qmake.conf +++ b/mkspecs/common/wince/qmake.conf @@ -15,7 +15,7 @@ QMAKE_COMPILER = msvc QMAKE_CC = cl QMAKE_LEX = flex QMAKE_LEXFLAGS = -QMAKE_YACC = byacc +QMAKE_YACC = bison -y QMAKE_YACCFLAGS = -d QMAKE_CFLAGS = -nologo -Zm200 -Zc:wchar_t- QMAKE_CFLAGS_WARN_ON = -W3 diff --git a/mkspecs/common/winrt_winphone/qmake.conf b/mkspecs/common/winrt_winphone/qmake.conf index 97ef66123097f57bb613b7a625c15bf6abe64af2..ca5119bded6b7f2793e0697fa143d3b91d0e274f 100644 --- a/mkspecs/common/winrt_winphone/qmake.conf +++ b/mkspecs/common/winrt_winphone/qmake.conf @@ -16,7 +16,7 @@ DEPLOYMENT_PLUGIN += qwinrt QMAKE_CC = cl QMAKE_LEX = flex QMAKE_LEXFLAGS = -QMAKE_YACC = byacc +QMAKE_YACC = bison -y QMAKE_YACCFLAGS = -d QMAKE_CFLAGS = -nologo QMAKE_CFLAGS_WARN_ON = -W3 diff --git a/mkspecs/common/winrt_winphone/qplatformdefs.h b/mkspecs/common/winrt_winphone/qplatformdefs.h index 14f6c58253694bc0a344da717f4adeb046530167..6abac1e94df1a71e1bf182eb85b4efee7bf0cd17 100644 --- a/mkspecs/common/winrt_winphone/qplatformdefs.h +++ b/mkspecs/common/winrt_winphone/qplatformdefs.h @@ -130,4 +130,14 @@ typedef int mode_t; +#ifndef INADDR_ANY +# define INADDR_ANY (u_long)0x00000000 +#endif +#ifndef INADDR_LOOPBACK +# define INADDR_LOOPBACK 0x7f000001 +#endif +#ifndef INADDR_BROADCAST +# define INADDR_BROADCAST (u_long)0xffffffff +#endif + #endif // QPLATFORMDEFS_H diff --git a/mkspecs/cygwin-g++/qmake.conf b/mkspecs/cygwin-g++/qmake.conf index caed4133b13d303bba564508c00ba9e97367b791..53cd35611f900caa41220bf07cf13b3fe4805df4 100644 --- a/mkspecs/cygwin-g++/qmake.conf +++ b/mkspecs/cygwin-g++/qmake.conf @@ -14,7 +14,7 @@ QMAKE_COMPILER = gcc QMAKE_CC = gcc QMAKE_LEX = flex QMAKE_LEXFLAGS = -QMAKE_YACC = byacc +QMAKE_YACC = bison -y QMAKE_YACCFLAGS = -d QMAKE_CFLAGS = -pipe QMAKE_CFLAGS_DEPS = -M diff --git a/mkspecs/devices/linux-beagleboard-g++/qmake.conf b/mkspecs/devices/linux-beagleboard-g++/qmake.conf index 1d32d374c6ea97b8ddc2dae03e9fc75e395df707..604da50f6374ef109794d25702b31bfddecff21d 100644 --- a/mkspecs/devices/linux-beagleboard-g++/qmake.conf +++ b/mkspecs/devices/linux-beagleboard-g++/qmake.conf @@ -26,7 +26,7 @@ QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy QMAKE_NM = $${CROSS_COMPILE}nm -P QMAKE_STRIP = $${CROSS_COMPILE}strip -COMPILER_FLAGS = -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp +COMPILER_FLAGS = -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mthumb #modifications to gcc-base.conf QMAKE_CFLAGS += $${COMPILER_FLAGS} @@ -47,11 +47,12 @@ QMAKE_LIBS_EGL = -lEGL -lIMGegl -lsrv_um QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 $${QMAKE_LIBS_EGL} QMAKE_LIBS_OPENVG = -lOpenVG $${QMAKE_LIBS_EGL} +DISTRO_OPTS += hard-float + # No need for any special EGL device integration. # Prioritize the default, compiled-in integration over any plugins. EGLFS_DEVICE_INTEGRATION = none -# Sanity check -deviceSanityCheckCompiler() +include(../common/linux_arm_device_post.conf) load(qt_config) diff --git a/mkspecs/features/c++11.prf b/mkspecs/features/c++11.prf index 32eaca4a9b5ae4552f99becfb0e5ba13636174ab..3f31f8ea82bf604dee92b53f04e57606e1701c7d 100644 --- a/mkspecs/features/c++11.prf +++ b/mkspecs/features/c++11.prf @@ -1,6 +1,12 @@ -QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_CXX11 -QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CXXFLAGS_CXX11 -QMAKE_LFLAGS += $$QMAKE_LFLAGS_CXX11 +strict_c++|isEmpty(QMAKE_CXXFLAGS_GNUCXX11) { + QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_CXX11 + QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CXXFLAGS_CXX11 + QMAKE_LFLAGS += $$QMAKE_LFLAGS_CXX11 +} else { + QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_GNUCXX11 + QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CXXFLAGS_GNUCXX11 + QMAKE_LFLAGS += $$QMAKE_LFLAGS_GNUCXX11 +} contains(QMAKE_LFLAGS, -stdlib=libc++) { equals(QMAKE_MACOSX_DEPLOYMENT_TARGET, 10.6): \ diff --git a/mkspecs/features/c++14.prf b/mkspecs/features/c++14.prf index a54d11840df31fc0b2ee45a082724e183e0e1a21..076458560d2388a47bcbf0087b1f0d024cd5405f 100644 --- a/mkspecs/features/c++14.prf +++ b/mkspecs/features/c++14.prf @@ -2,15 +2,21 @@ intel_icc { # ICC does not support C++14 yet } else: clang { # Clang has supported -std=c++1y since version 3.2 - greaterThan(QT_CLANG_MAJOR_VERSION, 3)|greaterThan(QT_CLANG_MINOR_VERSION, 1): \ + greaterThan(QT_CLANG_MAJOR_VERSION, 3)|greaterThan(QT_CLANG_MINOR_VERSION, 1) { QMAKE_CXXFLAGS_CXX11 = -std=c++1y + QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++1y + } # Unknown how long Apple Clang has supported -std=c++1y, but at least since XCode 5.0 - greaterThan(QT_APPLE_CLANG_MAJOR_VERSION, 4): \ + greaterThan(QT_APPLE_CLANG_MAJOR_VERSION, 4) { QMAKE_CXXFLAGS_CXX11 = -std=c++1y + QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++1y + } } else: gcc { # GCC has supported -std=c++1y since 4.8 - greaterThan(QT_GCC_MAJOR_VERSION, 4)|greaterThan(QT_GCC_MINOR_VERSION, 7): \ + greaterThan(QT_GCC_MAJOR_VERSION, 4)|greaterThan(QT_GCC_MINOR_VERSION, 7) { QMAKE_CXXFLAGS_CXX11 = -std=c++1y + QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++1y + } } # Delegate to c++11.prf diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf index 7b8b1ad2e511a3928d2852c7551f759c68ac2f42..806896ff58a06e5edc7a375a1e2a2dcac2b5b01a 100644 --- a/mkspecs/features/default_post.prf +++ b/mkspecs/features/default_post.prf @@ -62,8 +62,11 @@ debug { QMAKE_LIBFLAGS += $$QMAKE_LIBFLAGS_RELEASE } -use_gold_linker: QMAKE_LFLAGS += $$QMAKE_LFLAGS_USE_GOLD -enable_new_dtags: QMAKE_LFLAGS += $$QMAKE_LFLAGS_NEW_DTAGS +# disable special linker flags for host builds (no proper test for host support yet) +!host_build { + use_gold_linker: QMAKE_LFLAGS += $$QMAKE_LFLAGS_USE_GOLD + enable_new_dtags: QMAKE_LFLAGS += $$QMAKE_LFLAGS_NEW_DTAGS +} dll:win32: QMAKE_LFLAGS += $$QMAKE_LFLAGS_DLL static:mac: QMAKE_LFLAGS += $$QMAKE_LFLAGS_STATIC_LIB diff --git a/mkspecs/features/lex.prf b/mkspecs/features/lex.prf index 43d8fbd03817f5d21e9ed10bc8372ed239d91383..19ffe1932cd8eeea4bbcdfcc95f7ecf0fa8515ce 100644 --- a/mkspecs/features/lex.prf +++ b/mkspecs/features/lex.prf @@ -10,13 +10,22 @@ } else { lex.variable_out = GENERATED_SOURCES } - isEmpty(QMAKE_LEXFLAGS_MANGLE):QMAKE_LEXFLAGS_MANGLE = -P${QMAKE_FILE_BASE} - QMAKE_LEXEXTRAFLAGS = $$QMAKE_LEXFLAGS - !yacc_no_name_mangle:QMAKE_LEXEXTRAFLAGS += $$QMAKE_LEXFLAGS_MANGLE - lex.commands = $$QMAKE_LEX $$QMAKE_LEXEXTRAFLAGS ${QMAKE_FILE_IN}$$escape_expand(\\n\\t) \ - $$QMAKE_DEL_FILE $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}_lex$${first(QMAKE_EXT_CPP)}$$escape_expand(\\n\\t) \ - $$QMAKE_MOVE lex.${QMAKE_FILE_BASE}.c $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}_lex$${first(QMAKE_EXT_CPP)}$$escape_expand(\\n\\t) + contains(QMAKE_LEX, .*flex) { + # GNU flex, we can use -o outfile + lex.commands = $$QMAKE_LEX $$QMAKE_LEXFLAGS --nounistd -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} + } else { + # stupid POSIX lex, it only generates a file called lex.yy.c + # or lex.prefix.c if the -P<prefix> option is active + intermediate_file = lex.yy.c + QMAKE_LEXEXTRAFLAGS = $$QMAKE_LEXFLAGS $$QMAKE_LEXFLAGS_MANGLE + + lex.commands = \ + -$(DEL_FILE) ${QMAKE_FILE_OUT}$$escape_expand(\\n\\t) \ + $$QMAKE_LEX $$QMAKE_LEXEXTRAFLAGS ${QMAKE_FILE_IN}$$escape_expand(\\n\\t) \ + $(MOVE) $$intermediate_file ${QMAKE_FILE_OUT} $$escape_expand(\\n\\t) + unset(intermediate_file) + } lex.output = $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}_lex$${first(QMAKE_EXT_CPP)} silent:lex.commands = @echo Lex ${QMAKE_FILE_IN} && $$lex.commands diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf index bdff17210bfe401c6db3f6180aa69698d534c211..38b0799d3088fe93be7434f0fc79b70cc50cc3a9 100644 --- a/mkspecs/features/mac/default_post.prf +++ b/mkspecs/features/mac/default_post.prf @@ -42,15 +42,13 @@ qt:!isEmpty(QT_CONFIG) { # libraries. This applies only to apps, since all loaded libraries inherit # rpaths from current process executable. else:!if(host_build:force_bootstrap):equals(TEMPLATE, app):!defined(QMAKE_RPATHDIR, var):contains(QT_CONFIG, rpath) { - # If app is outside of Qt SDK prefix use absolute path to Qt libraries, - # otherwise make it relative, so all SDK tools and examples work when - # relocated. - # Tests are an exception, since they are launched in their build not - # install location by CI, so we cannot use relative rpaths there. - if(!contains(target.path, "$$re_escape($$[QT_INSTALL_PREFIX])/.*")|\ - contains(target.path, "$$re_escape($$[QT_INSTALL_TESTS])/.*")) { - QMAKE_RPATHDIR = $$[QT_INSTALL_LIBS] - } else { + # If app is expected to be installed into the Qt prefix build, use + # relative path, so all SDK tools and examples work when relocated. + prefix_build:defined(target.path, var):\ + contains(target.path, "$$re_escape($$[QT_INSTALL_PREFIX])/.*"):\ + # Tests are an exception, since they are launched in their build not + # install location by CI, so we cannot use relative rpaths there. + !contains(target.path, "$$re_escape($$[QT_INSTALL_TESTS])/.*") { app_bundle { ios: binpath = $$target.path/$${TARGET}.app else: binpath = $$target.path/$${TARGET}.app/Contents/MacOS @@ -59,6 +57,9 @@ qt:!isEmpty(QT_CONFIG) { } QMAKE_RPATHDIR = @loader_path/$$relative_path($$[QT_INSTALL_LIBS], $$binpath) unset(binpath) + } else { + # Otherwise, use absolute path to Qt libraries + QMAKE_RPATHDIR = $$[QT_INSTALL_LIBS] } } } diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf index 5ae4c08227f963ca93170ea60397853eb23b48b0..a639ac2969b5e9ba35fabc43a9a076da68eba92f 100644 --- a/mkspecs/features/qml_plugin.prf +++ b/mkspecs/features/qml_plugin.prf @@ -25,6 +25,12 @@ if(win32|mac):!macx-xcode { } isEmpty(TARGETPATH): TARGETPATH = $$eval(QT.$${CXX_MODULE}.name) +!no_cxx_module:win32:CONFIG(shared, static|shared) { + # Embed a VERSIONINFO resource into the plugin's DLL. + isEmpty(VERSION): VERSION = $$MODULE_VERSION + CONFIG += skip_target_version_ext +} + # Insert the plugins URI into its meta data to enable usage # of static plugins in QtDeclarative: URI = $$replace(TARGETPATH, "/", ".") diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 8e7b8bca0a32bafc7204bcee1258d62aa53c5d19..ce93105f4b237e09cc3cbc8c08e6b1df17566844 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -67,7 +67,7 @@ qtAddModules(QT_PRIVATE, LIBS_PRIVATE) } qtAddRpathLink($$QT $$QT_PRIVATE) -wince*:static:gui { +wince:static:gui { QTLIB += qmenu_wce.res } @@ -252,7 +252,10 @@ for(QT_CURRENT_VERIFY, $$list($$QT_PLUGIN_VERIFY)) { # if the plugin is linked statically there is no need to deploy it DEPLOYMENT_PLUGIN -= $$QT_CURRENT_VERIFY } - isEqual(QT_CURRENT_VERIFY, DEPLOYMENT_PLUGIN):shared:if(wince*|winrt): { + + # The following block is currently broken, because qt_plugin_XXX.prf files + # are not generated for dynamic builds. + false:isEqual(QT_CURRENT_VERIFY, DEPLOYMENT_PLUGIN):shared:if(wince*|winrt) { QT_ITEM = debug: QT_ITEM = $${QTPLUG}d4.dll else: QT_ITEM = $${QTPLUG}4.dll diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf index 5861941848b85b386cbebfbd988b76ab2d4628d6..2ed43e5063a17fab7a9e9c64d165a62860b32533 100644 --- a/mkspecs/features/qt_common.prf +++ b/mkspecs/features/qt_common.prf @@ -12,7 +12,7 @@ QMAKE_DIR_REPLACE_SANE += DESTDIR CONFIG -= debug_and_release_target -contains(QT_CONFIG, c++11): CONFIG += c++11 +contains(QT_CONFIG, c++11): CONFIG += c++11 strict_c++ contains(TEMPLATE, .*lib) { # module and plugins !host_build:contains(QT_CONFIG, reduce_exports): CONFIG += hide_symbols @@ -48,10 +48,10 @@ warnings_are_errors:warning_clean { # compiler. clang { # Apple clang 4.0-4.2,5.0-5.1 - # Regular clang 3.3 & 3.4 + # Regular clang 3.3-3.6 apple_ver = $${QT_APPLE_CLANG_MAJOR_VERSION}.$${QT_APPLE_CLANG_MINOR_VERSION} reg_ver = $${QT_CLANG_MAJOR_VERSION}.$${QT_CLANG_MINOR_VERSION} - contains(apple_ver, "4\\.[012]|5\\.[01]")|contains(reg_ver, "3\\.[34]") { + contains(apple_ver, "4\\.[012]|5\\.[01]")|contains(reg_ver, "3\\.[3-6]") { QMAKE_CXXFLAGS_WARN_ON += -Werror -Wno-error=\\$${LITERAL_HASH}warnings -Wno-error=deprecated-declarations $$WERROR } } else:intel_icc:linux { @@ -67,9 +67,9 @@ warnings_are_errors:warning_clean { QMAKE_CXXFLAGS_WARN_ON += -Werror -ww177,1224,1478,1881 $$WERROR } } else:gcc:!clang:!intel_icc { - # GCC 4.6-4.9 + # GCC 4.6-4.9, 5.x ver = $${QT_GCC_MAJOR_VERSION}.$${QT_GCC_MINOR_VERSION} - contains(ver, "4\\.[6789]") { + contains(ver, "(4\\.[6789]|5\\..)") { QMAKE_CXXFLAGS_WARN_ON += -Werror -Wno-error=cpp -Wno-error=deprecated-declarations $$WERROR # GCC prints this bogus warning, after it has inlined a lot of code diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index 5412f3778a018309f3aa416ab674d6fda83b7607..c89b6d2793bcaef69102c51c4433b304bf6fb769 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -67,7 +67,7 @@ header_module { TEMPLATE = lib } DESTDIR = $$MODULE_BASE_OUTDIR/lib -win32:!wince*:!prefix_build: DLLDESTDIR = $$MODULE_BASE_OUTDIR/bin +win32:!wince:!prefix_build: DLLDESTDIR = $$MODULE_BASE_OUTDIR/bin CONFIG += qmake_cache target_qt diff --git a/mkspecs/features/qt_plugin.prf b/mkspecs/features/qt_plugin.prf index 004eee551e19b5456b9022d43009367c25e373bc..17748e518a2dd200ae67205def00923e85b76159 100644 --- a/mkspecs/features/qt_plugin.prf +++ b/mkspecs/features/qt_plugin.prf @@ -89,5 +89,5 @@ CONFIG += create_cmake load(qt_targets) load(qt_common) -wince*:LIBS += $$QMAKE_LIBS_GUI +wince: LIBS += $$QMAKE_LIBS_GUI QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF diff --git a/mkspecs/features/resolve_target.prf b/mkspecs/features/resolve_target.prf index 164271ddc2a62c5a8b5f907578ee88e20889a6bf..911e6b85f01984447197ee021fea698701f438b4 100644 --- a/mkspecs/features/resolve_target.prf +++ b/mkspecs/features/resolve_target.prf @@ -55,7 +55,7 @@ win32 { equals(TEMPLATE, lib) { static { QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}$${LIBPREFIX}$${TARGET}.a - } else:plugin { + } else: plugin|unversioned_libname { QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}$${LIBPREFIX}$${TARGET}.so } else { TEMP_VERSION = $$VERSION diff --git a/mkspecs/features/yacc.prf b/mkspecs/features/yacc.prf index 4d7e0a381b44237927519034fedc42005707809c..22fe4cb0a244e550ea26f438a15a47bf9f1b3125 100644 --- a/mkspecs/features/yacc.prf +++ b/mkspecs/features/yacc.prf @@ -9,9 +9,9 @@ isEmpty(QMAKE_YACCFLAGS_MANGLE) { - QMAKE_YACCFLAGS_MANGLE = -p ${QMAKE_FILE_BASE} - QMAKE_YACC_HEADER = y.tab.h - QMAKE_YACC_SOURCE = y.tab.c + QMAKE_YACCFLAGS_MANGLE = -p ${QMAKE_FILE_BASE} -b ${QMAKE_FILE_BASE} + QMAKE_YACC_HEADER = ${QMAKE_FILE_BASE}.tab.h + QMAKE_YACC_SOURCE = ${QMAKE_FILE_BASE}.tab.c } else { QMAKE_YACCFLAGS_MANGLE ~= s/\\$base/${QMAKE_FILE_BASE}/g #backwards compat QMAKE_YACC_HEADER ~= s/\\$base/${QMAKE_FILE_BASE}/g @@ -21,10 +21,10 @@ !yacc_no_name_mangle:QMAKE_YACCDECLFLAGS += $$QMAKE_YACCFLAGS_MANGLE yacc_decl.commands = \ + -$(DEL_FILE) $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}_yacc$${first(QMAKE_EXT_H)} $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}_yacc$${first(QMAKE_EXT_CPP)}$$escape_expand(\\n\\t) \ $$QMAKE_YACC $$QMAKE_YACCDECLFLAGS ${QMAKE_FILE_IN}$$escape_expand(\\n\\t) \ - $$QMAKE_DEL_FILE $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}_yacc$${first(QMAKE_EXT_H)} $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}_yacc$${first(QMAKE_EXT_CPP)}$$escape_expand(\\n\\t) \ - $$QMAKE_MOVE $${QMAKE_YACC_HEADER} $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}_yacc$${first(QMAKE_EXT_H)}$$escape_expand(\\n\\t) \ - $$QMAKE_MOVE $${QMAKE_YACC_SOURCE} $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}_yacc$${first(QMAKE_EXT_CPP)}$$escape_expand(\\n\\t) + $(MOVE) $${QMAKE_YACC_HEADER} $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}_yacc$${first(QMAKE_EXT_H)}$$escape_expand(\\n\\t) \ + $(MOVE) $${QMAKE_YACC_SOURCE} $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}_yacc$${first(QMAKE_EXT_CPP)}$$escape_expand(\\n\\t) yacc_decl.output = $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}_yacc$${first(QMAKE_EXT_H)} silent:yacc_decl.commands = @echo Yacc ${QMAKE_FILE_IN} && $$yacc_decl.commands diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf index 9190aa9f28cf6b38455a718afd6851d341ca57b5..ca9e81512e3204f472231a1982a0ef879b85a96c 100644 --- a/mkspecs/linux-icc/qmake.conf +++ b/mkspecs/linux-icc/qmake.conf @@ -50,6 +50,7 @@ QMAKE_CXXFLAGS_SPLIT_SECTIONS = $$QMAKE_CFLAGS_SPLIT_SECTIONS # Disabling exceptions disabled - workaround for QTBUG-36577 #QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions QMAKE_CXXFLAGS_CXX11 = -std=c++0x +QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++0x QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG QMAKE_INCDIR = diff --git a/mkspecs/macx-icc/qmake.conf b/mkspecs/macx-icc/qmake.conf index 5e45e67d0ca7296f3f95f239a710fa18e4e3575c..c145c2c8f3e0244822675d1699f464999cd29ac5 100644 --- a/mkspecs/macx-icc/qmake.conf +++ b/mkspecs/macx-icc/qmake.conf @@ -53,6 +53,7 @@ QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD QMAKE_CXXFLAGS_CXX11 = -std=c++11 +QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11 QMAKE_CXXFLAGS_SPLIT_SECTIONS = $$QMAKE_CFLAGS_SPLIT_SECTIONS QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf index c9d3a5d85ba2295aef40c4b24a4ccc6d66953dab..3acd35a038e7cfb99b146a0649c54ce2c5548159 100644 --- a/mkspecs/macx-ios-clang/features/default_post.prf +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -1,179 +1,24 @@ -load(sdk) - -# Resolve config so we don't need to use CONFIG() later on -CONFIG(iphonesimulator, iphonesimulator|iphoneos) { - CONFIG -= iphoneos -} else { - CONFIG -= iphonesimulator - CONFIG += iphoneos -} - -equals(TEMPLATE, app) { +equals(TEMPLATE, app):contains(CONFIG, qt) { # If the application uses Qt, it needs to be an application bundle # to be able to deploy and run on iOS. The only exception to this # is if you're working with a jailbroken device and can run the # resulting binary from the console/over SSH, but that's not a # use-case we care about, so no need to complicate the logic. - qt: CONFIG *= app_bundle - - app_bundle { - macx-xcode { - # There is no way to genereate Xcode projects that are limited to either - # simulator or device builds, so iphonesimulator_and_iphoneos is always - # effectivly active, even if the user disabled it explicitly. - # The Xcode generator doesn't support multiple BUILDS though (exclusive - # builds), so we have to manually set up the simulator suffix. - library_suffix_iphonesimulator.name = "$${QMAKE_XCODE_LIBRARY_SUFFIX_SETTING}[sdk=iphonesimulator*]" - library_suffix_iphonesimulator.value = "_iphonesimulator$($${QMAKE_XCODE_LIBRARY_SUFFIX_SETTING})" - QMAKE_MAC_XCODE_SETTINGS += library_suffix_iphonesimulator - CONFIG *= xcode_dynamic_library_suffix - } else { - # For Qt applications we want Xcode project files as the generated output, - # but since qmake doesn't handle the transition between makefiles and Xcode - # project files (which happens when using subdirs), we create a wrapper - # makefile that takes care of generating the Xcode project, and allows - # building by calling out to xcodebuild. - TEMPLATE = aux - - SOURCES = - OBJECTIVE_SOURCES = - RESOURCES = - INSTALLS = - QMAKE_EXTRA_COMPILERS = - - !build_pass { - CONFIG += debug_and_release - load(resolve_config) - - CONFIG += iphonesimulator_and_iphoneos - iphonesimulator.name = Simulator - iphoneos.name = Device - addExclusiveBuilds(iphonesimulator, iphoneos) - - load(exclusive_builds_post) - - xcode_distclean.commands = "$(DEL_FILE) -R $${TARGET}.xcodeproj" - xcode_distclean.depends = \ - debug-iphonesimulator-distclean debug-iphoneos-distclean \ - release-iphonesimulator-distclean release-iphoneos-distclean - QMAKE_EXTRA_TARGETS += xcode_distclean - DISTCLEAN_DEPS += xcode_distclean - - mkpath($$OUT_PWD)|error("Aborting.") - args = - for(arg, QMAKE_ARGS): \ - args += $$system_quote($$arg) - system("cd $$system_quote($$OUT_PWD) && $$QMAKE_QMAKE $$args $$system_quote($$_PRO_FILE_) -spec macx-xcode") - - # We have a target, even though our template is aux - CONFIG += have_target - - } else { - load(resolve_config) - - iphonesimulator: \ - sdk = iphonesimulator - else: \ - sdk = iphoneos - - debug: \ - cfg = debug - else: \ - cfg = release - - for(action, $$list(build install clean test)) { - equals(action, build) { - action_target_suffix = - action_target = all - } else: equals(action, test) { - action_target_suffix = -check - action_target = check - } else { - action_target_suffix = -$$action - action_target = $$action - } - - target = $${sdk}-$${cfg}$${action_target_suffix} - - xcodebuild = "xcodebuild $$action -scheme $(TARGET) -sdk $$sdk -configuration $$title($$cfg)" - - equals(action, test):equals(sdk, iphoneos) { - AVAILABLE_DEVICE_IDS = "$(shell system_profiler SPUSBDataType | sed -n -E -e '/(iPhone|iPad|iPod)/,/Serial/s/ *Serial Number: *(.+)/\1/p')" - CUSTOM_DEVICE_IDS = "$(filter $(EXPORT_AVAILABLE_DEVICE_IDS), $(IOS_TEST_DEVICE_IDS))" - TEST_DEVICE_IDS = "$(strip $(if $(EXPORT_CUSTOM_DEVICE_IDS), $(EXPORT_CUSTOM_DEVICE_IDS), $(EXPORT_AVAILABLE_DEVICE_IDS)))" - - QMAKE_EXTRA_VARIABLES += AVAILABLE_DEVICE_IDS CUSTOM_DEVICE_IDS TEST_DEVICE_IDS - - xcodebuild = "@$(if $(EXPORT_TEST_DEVICE_IDS),"\ - "echo Running tests on $(words $(EXPORT_TEST_DEVICE_IDS)) device\\(s\\): && ("\ - "$(foreach deviceid, $(EXPORT_TEST_DEVICE_IDS),"\ - "(echo Testing on device ID '$(deviceid)' ... && $${xcodebuild} -destination 'platform=iOS,id=$(deviceid)' && echo) &&"\ - ") echo Tests completed successfully on all devices"\ - "), $(error No iOS devices connected, please connect at least one device that can be used for testing.))" - } - - $${target}.commands = $$xcodebuild - QMAKE_EXTRA_TARGETS += $$target - - $${action_target}.depends += $$target - QMAKE_EXTRA_TARGETS *= $${action_target} - } - - xcode_build_dir_distclean.commands = "$(DEL_FILE) -R $$title($$cfg)-$${sdk}" - xcode_build_dir_distclean.depends = clean - QMAKE_EXTRA_TARGETS += xcode_build_dir_distclean - distclean.depends = xcode_build_dir_distclean - QMAKE_EXTRA_TARGETS += distclean - } - } - } -} else: equals(TEMPLATE, lib) { - iphonesimulator.name = Simulator - iphoneos.name = Device - addExclusiveBuilds(iphonesimulator, iphoneos) -} else: equals(TEMPLATE, subdirs) { - # Prevent recursion into host_builds - for(subdir, SUBDIRS) { - contains($${subdir}.CONFIG, host_build) { - $${subdir}.CONFIG += no_iphoneos_target no_iphonesimulator_target - - # Other targets which we do want to recurse into may depend on this target, - # for example corelib depends on moc, rcc, bootstrap, etc, and other libs - # may depend on host-tools that are needed to build the lib, so we resolve - # the final target name and redirect it to the base target, so that the - # dependency chain is not broken for the other targets. - - !isEmpty($${subdir}.target) { - target = $$eval($${subdir}.target) - } else { - !isEmpty($${subdir}.file): \ - file = $$eval($${subdir}.file) - else: !isEmpty($${subdir}.subdir): \ - file = $$eval($${subdir}.subdir) - else: \ - file = $$subdir - - target = sub-$$file - } - - target ~= s,[^a-zA-Z0-9_],-, - - $${target}-iphonesimulator.depends = $$target - $${target}-iphoneos.depends = $$target - QMAKE_EXTRA_TARGETS += $${target}-iphonesimulator $${target}-iphoneos - } - } - - prepareRecursiveTarget(iphonesimulator) - prepareRecursiveTarget(iphoneos) - QMAKE_EXTRA_TARGETS += iphonesimulator iphoneos - -} else: equals(TEMPLATE, aux) { - # Dummy targets for the 'aux' TEMPLATE, so we can always recurse - QMAKE_EXTRA_TARGETS *= iphonesimulator iphoneos + CONFIG *= app_bundle + + # For Qt applications we want Xcode project files as the generated output, + # but since qmake doesn't handle the transition between makefiles and Xcode + # project files (which happens when using subdirs), we can't just override + # MAKEFILE_GENERATOR. Instead, we generate the Xcode project by spawning a + # child qmake process with -spec macx-xcode and let the top level qmake + # process generate a wrapper makefile that forwards everything to xcodebuild. + equals(MAKEFILE_GENERATOR, UNIX): \ + CONFIG = xcodebuild $$CONFIG } +load(default_post) + macx-xcode { ios_device_family.name = TARGETED_DEVICE_FAMILY ios_device_family.value = $$QMAKE_IOS_TARGETED_DEVICE_FAMILY @@ -251,5 +96,3 @@ macx-xcode { QMAKE_OBJECTIVE_CFLAGS += $$arch_flags QMAKE_LFLAGS += $$arch_flags } - -load(default_post) diff --git a/mkspecs/macx-ios-clang/features/exclusive_builds_post.prf b/mkspecs/macx-ios-clang/features/exclusive_builds_post.prf new file mode 100644 index 0000000000000000000000000000000000000000..1fb0a558466ed852d62297f487754abdcbdfa386 --- /dev/null +++ b/mkspecs/macx-ios-clang/features/exclusive_builds_post.prf @@ -0,0 +1,8 @@ + +xcodebuild { + # Prevent qmake from generating empty output dirs for each exclusive build, + # as Xcode will do this by itself, and with a different name. + QMAKE_DIR_REPLACE = +} + +load(exclusive_builds_post) diff --git a/mkspecs/macx-ios-clang/features/qt.prf b/mkspecs/macx-ios-clang/features/qt.prf index 9e6b486c6e0788fc38eb17da957018dba30866ad..474a195e4bc16ffa471bb916d36c2eb0d7074c9b 100644 --- a/mkspecs/macx-ios-clang/features/qt.prf +++ b/mkspecs/macx-ios-clang/features/qt.prf @@ -19,34 +19,12 @@ equals(TEMPLATE, app):contains(qt_depends, gui(-private)?) { QTPLUGIN.platforms = - !no_main_wrapper { - # We use ld to rename the _main symbol to _qt_main, so that we don't get a symbol clash - # with the _main we provide that calls UIApplicationMain. We need to make a copy of the - # original object file, as ld will not copy over DWARF debug information to the output - # file. Instead, it will inject a reference back to the original object file, so when - # Xcode runs dsymutil to make the final dSYM file it will still find the debug info - # for the object file that provided the original _main. This back-reference has the - # interesting side-effect of the debug information still referring to the original - # symbol name, so stack-traces will show both our wrapper main and the original - # user main as 'main', and adding a symbolic breakpoint for 'main' will break on - # both functions. Although a bit weird, it's a good thing, as the user will still be - # able to add symbolic breakpoints for 'main', not caring that the symbol is actually - # called 'qt_main' now. - - macx-xcode { - objects_dir = "\"${OBJECT_FILE_DIR}-${CURRENT_VARIANT}\"" - archs = "\"${ARCHS}\"" - } else { - isEmpty(OBJECTS_DIR): \ - objects_dir = . - else: \ - objects_dir = $$shell_quote($$OBJECTS_DIR) - archs = $$shell_quote($$QMAKE_IOS_DEVICE_ARCHS $$QMAKE_IOS_SIMULATOR_ARCHS) - } - - !isEmpty(QMAKE_PRE_LINK): \ - QMAKE_PRE_LINK += ";" - - QMAKE_PRE_LINK += $$shell_quote($$QMAKESPEC/rename_main.sh) $$objects_dir $$archs + # The LC_MAIN load command available in iOS 6.0 and above allows dyld to + # directly call the entrypoint instead of going through _start in crt.o. + # Passing -e to the linker changes the entrypoint from _main to our custom + # wrapper that calls UIApplicationMain and dispatches back to main() once + # the application has started up and is ready to initialize QApplication. + QMAKE_LFLAGS += -Wl,-e,_qt_main_wrapper } } diff --git a/mkspecs/macx-ios-clang/features/resolve_config.prf b/mkspecs/macx-ios-clang/features/resolve_config.prf new file mode 100644 index 0000000000000000000000000000000000000000..d1d3e8ca3963761a7495a161831553add95a0dea --- /dev/null +++ b/mkspecs/macx-ios-clang/features/resolve_config.prf @@ -0,0 +1,64 @@ + +xcodebuild { + # Xcode project files always support both Debug and Release configurations + # and iOS device and simulator targets, so we make sure the wrapper-makefile + # also does. + CONFIG += debug_and_release iphonesimulator_and_iphoneos +} + +load(resolve_config) + +CONFIG(iphonesimulator, iphonesimulator|iphoneos): \ + CONFIG -= iphoneos +else: \ + CONFIG -= iphonesimulator + +macx-xcode { + # There is no way to genereate Xcode projects that are limited to either + # simulator or device builds, so iphonesimulator_and_iphoneos is always + # effectivly active, even if the user disabled it explicitly. + # The Xcode generator doesn't support multiple BUILDS though (exclusive + # builds), so we have to manually set up the simulator suffix. + library_suffix_iphonesimulator.name = "$${QMAKE_XCODE_LIBRARY_SUFFIX_SETTING}[sdk=iphonesimulator*]" + library_suffix_iphonesimulator.value = "_iphonesimulator$($${QMAKE_XCODE_LIBRARY_SUFFIX_SETTING})" + QMAKE_MAC_XCODE_SETTINGS += library_suffix_iphonesimulator + CONFIG *= xcode_dynamic_library_suffix +} else { + iphonesimulator.name = Simulator + iphoneos.name = Device + addExclusiveBuilds(iphonesimulator, iphoneos) +} + +equals(TEMPLATE, subdirs) { + # Prevent recursion into host_builds + for(subdir, SUBDIRS) { + contains($${subdir}.CONFIG, host_build) { + $${subdir}.CONFIG += no_iphoneos_target no_iphonesimulator_target + + # Other targets which we do want to recurse into may depend on this target, + # for example corelib depends on moc, rcc, bootstrap, etc, and other libs + # may depend on host-tools that are needed to build the lib, so we resolve + # the final target name and redirect it to the base target, so that the + # dependency chain is not broken for the other targets. + + !isEmpty($${subdir}.target) { + target = $$eval($${subdir}.target) + } else { + !isEmpty($${subdir}.file): \ + file = $$eval($${subdir}.file) + else: !isEmpty($${subdir}.subdir): \ + file = $$eval($${subdir}.subdir) + else: \ + file = $$subdir + + target = sub-$$file + } + + target ~= s,[^a-zA-Z0-9_],-, + + $${target}-iphonesimulator.depends = $$target + $${target}-iphoneos.depends = $$target + QMAKE_EXTRA_TARGETS += $${target}-iphonesimulator $${target}-iphoneos + } + } +} diff --git a/mkspecs/macx-ios-clang/features/testcase.prf b/mkspecs/macx-ios-clang/features/testcase.prf new file mode 100644 index 0000000000000000000000000000000000000000..e16c163ffa39c5c1ec667190caba8bce8503a970 --- /dev/null +++ b/mkspecs/macx-ios-clang/features/testcase.prf @@ -0,0 +1,12 @@ +# Pretend we have a target, even though our template is aux +xcodebuild: \ + CONFIG += have_target + +load(testcase) + +# We provide our own check logic +xcodebuild { + check.depends = + check.commands = + QMAKE_EXTRA_TARGETS *= check +} diff --git a/mkspecs/macx-ios-clang/features/testcase_targets.prf b/mkspecs/macx-ios-clang/features/testcase_targets.prf new file mode 100644 index 0000000000000000000000000000000000000000..e0a2922c3f4dac74e1b3474781607c95b1fda4f5 --- /dev/null +++ b/mkspecs/macx-ios-clang/features/testcase_targets.prf @@ -0,0 +1,3 @@ +# For the xcodebuild wrapper makefile we deal with test targets manually +!xcodebuild: \ + load(testcase_targets) diff --git a/mkspecs/macx-ios-clang/features/xcodebuild.prf b/mkspecs/macx-ios-clang/features/xcodebuild.prf new file mode 100644 index 0000000000000000000000000000000000000000..b897432a4386f7ed04a10d266126a51605898d68 --- /dev/null +++ b/mkspecs/macx-ios-clang/features/xcodebuild.prf @@ -0,0 +1,49 @@ + +# For Qt applications we want Xcode project files as the generated output, +# but since qmake doesn't handle the transition between makefiles and Xcode +# project files (which happens when using subdirs), we can't just override +# MAKEFILE_GENERATOR. Instead, we generate the Xcode project by spawing a +# child qmake process with -spec macx-xcode and let the top level qmake +# process generate a wrapper makefile that forwards everything to xcodebuild. + +TEMPLATE = aux + +SOURCES = +OBJECTIVE_SOURCES = +RESOURCES = +INSTALLS = +QMAKE_EXTRA_COMPILERS = + +!mkpath($$OUT_PWD): \ + error("Failed to create $$OUT_PWD") + +args = +for(arg, QMAKE_ARGS): \ + args += $$system_quote($$arg) + +cmd = "$$QMAKE_QMAKE $$args $$system_quote($$_PRO_FILE_) -spec macx-xcode" +debug(1, "Generating Xcode project in $$OUT_PWD using '$$cmd'") +system("cd $$system_quote($$OUT_PWD) && $$cmd") + +# Subtargets + +for(build, BUILDS): \ + SUBTARGETS += $$eval($${build}.target) +QMAKE_EXTRA_VARIABLES += SUBTARGETS + +CONFIG += no_default_goal_deps + +QMAKE_EXTRA_INCLUDES += $$shell_quote($$QMAKESPEC/xcodebuild.mk) + +# Distclean + +distfiles = $${TARGET}.xcodeproj +for(build, BUILDS): \ + distfiles += $$title($$eval($${build}.target)) +distclean_xcodebuild.commands = -$(DEL_FILE) -R $$distfiles + +distclean.depends += clean_all distclean_xcodebuild +QMAKE_EXTRA_TARGETS += distclean distclean_xcodebuild + +# Empty exclusive builds, we've set them up manually +BUILDS = diff --git a/mkspecs/macx-ios-clang/rename_main.sh b/mkspecs/macx-ios-clang/ios_destinations.sh similarity index 54% rename from mkspecs/macx-ios-clang/rename_main.sh rename to mkspecs/macx-ios-clang/ios_destinations.sh index 1547f5f75c219cd07e971a716da4286f29a6b16d..aebf8f6403d3d7c4dc35c6983fc01b9e659c8406 100755 --- a/mkspecs/macx-ios-clang/rename_main.sh +++ b/mkspecs/macx-ios-clang/ios_destinations.sh @@ -33,46 +33,23 @@ ## ############################################################################# -if [ $# -ne 2 ]; then - echo "$0: wrong number of arguments for internal tool used by iOS mkspec" -else - arch_paths="" - for a in $2; do - arch_paths="$arch_paths -$1/$a" +booted_simulator=$(xcrun simctl list devices | grep -v unavailable | grep Booted | perl -lne 'print $1 if /\((.*?)\)/') +echo "IPHONESIMULATOR_DEVICES = $booted_simulator" + +xcodebuild test -scheme $1 -destination 'id=0' -destination-timeout 1 2>&1| sed -n 's/{ \(platform:.*\) }/\1/p' | while read destination; do + id=$(echo $destination | sed -n -E 's/.*id:([^ ,]+).*/\1/p') + echo $destination | tr ',' '\n' | while read keyval; do + key=$(echo $keyval | cut -d ':' -f 1 | tr '[:lower:]' '[:upper:]') + val=$(echo $keyval | cut -d ':' -f 2) + echo "%_$id: DESTINATION_${key} = $val" + + if [ $key = 'PLATFORM' ]; then + if [ "$val" = "iOS" ]; then + echo "IPHONEOS_DEVICES += $id" + elif [ "$val" = "iOS Simulator" -a "$id" != "$booted_simulator" ]; then + echo "IPHONESIMULATOR_DEVICES += $id" + fi + fi done - for f in $(IFS=" -"; find $arch_paths -name '*.o'); do - # Skip object files without the _main symbol - nm $f 2>/dev/null | grep -q 'T _main$' || continue - - fname=${f#$1/} - - file -b $f | grep -qi 'llvm bit-code' && \ - (cat \ -<<EOF >&2 -$f:: error: The file '$fname' contains LLVM bitcode, not object code. Automatic main() redirection could not be applied. -note: This is most likely due to the use of link-time optimization (-flto). Please disable LTO, or work around the \ -issue by manually renaming your main() function to qtmn(): - -#ifdef Q_OS_IOS -extern "C" int qtmn(int argc, char *argv[]) -#else -int main(int argc, char *argv[]) -#endif -EOF - ) && exit 1 - - echo "Found main() in $fname" - - strings -t d - $f | grep '_main\(\.eh\)\?$' | while read match; do - offset=$(echo $match | cut -d ' ' -f 1) - symbol=$(echo $match | cut -d ' ' -f 2) - - echo " Renaming '$symbol' at offset $offset to '${symbol/main/qtmn}'" - - # In-place rename the string (keeping the same length) - printf '_qtmn' | dd of=$f bs=1 seek=$offset conv=notrunc >/dev/null 2>&1 - done - done -fi \ No newline at end of file + echo +done diff --git a/mkspecs/macx-ios-clang/qmake.conf b/mkspecs/macx-ios-clang/qmake.conf index 0dd761760c55c29d837d32ad633e677118663cf5..d5e5840902a7332e2e1eb24a79dac54ca8f2df72 100644 --- a/mkspecs/macx-ios-clang/qmake.conf +++ b/mkspecs/macx-ios-clang/qmake.conf @@ -7,7 +7,7 @@ CONFIG += app_bundle reduce_exports incremental global_init_link QMAKE_INCREMENTAL_STYLE = sublib QMAKE_MACOSX_DEPLOYMENT_TARGET = -QMAKE_IOS_DEPLOYMENT_TARGET = 5.1.1 +QMAKE_IOS_DEPLOYMENT_TARGET = 6.0 INCLUDEPATH += $$PWD/ios DEFINES += DARWIN_NO_CARBON QT_NO_PRINTER QT_NO_PRINTDIALOG diff --git a/mkspecs/macx-ios-clang/xcodebuild.mk b/mkspecs/macx-ios-clang/xcodebuild.mk new file mode 100644 index 0000000000000000000000000000000000000000..f50010abc1d4f88880ac7b4742ce43be4ebad94a --- /dev/null +++ b/mkspecs/macx-ios-clang/xcodebuild.mk @@ -0,0 +1,96 @@ + +# We don't want xcodebuild to run in parallel +.NOTPARALLEL: + +# Functions +targets = $(foreach target, $(EXPORT_SUBTARGETS), $(target)-$(strip $(1))) +toupper = $(shell echo $1 | tr '[:lower:]' '[:upper:]') +tolower = $(shell echo $1 | tr '[:upper:]' '[:lower:]') +basesdk = $(shell echo $1 | sed 's/[0-9.]*$$//') + +# Explicit comma variable +, := , + +# Default targets +first: build +all: build_all + +.DEFAULT_GOAL = first + +# Top level targets +build: build_first +clean: clean_first +install: install_first +check: check_first +distclean: clean_all + +$(EXPORT_SUBTARGETS): % : %-build + +# Generic targets +%_first: $(firstword $(call targets, %)) ; +%_all: $(call targets, %) ; + +# Actions +%-build: ACTION = build +%-build: xcodebuild-% ; + +%-clean: ACTION = clean +%-clean: xcodebuild-% ; + +%-install: ACTION = install +%-install: xcodebuild-% ; + +# Limit check to a single configuration +%-iphoneos-check: check-iphoneos ; +%-iphonesimulator-check: check-iphonesimulator ; + +# SDK +%-iphoneos: SDK = iphoneos +%-iphonesimulator: SDK = iphonesimulator + +# Configuration +release-%: CONFIGURATION = Release +debug-%: CONFIGURATION = Debug + +# Test and build (device) destinations +ifneq ($(filter check%,$(MAKECMDGOALS)),) + ifeq ($(DEVICES),) + $(info Enumerating test destinations (you may override this by setting DEVICES explicitly), please wait...) + SPECDIR := $(dir $(lastword $(MAKEFILE_LIST))) + DESTINATIONS_INCLUDE = /tmp/ios_destinations.mk + $(shell $(SPECDIR)/ios_destinations.sh $(TARGET) > $(DESTINATIONS_INCLUDE)) + include $(DESTINATIONS_INCLUDE) + endif +endif + +%-iphonesimulator: DEVICES = $(firstword $(IPHONESIMULATOR_DEVICES)) +%-iphoneos: DEVICES = $(IPHONEOS_DEVICES) + +IPHONEOS_GENERIC_DESTINATION := "generic/platform=iOS" +IPHONESIMULATOR_GENERIC_DESTINATION := "id=$(shell xcrun simctl list devices | grep -v unavailable | perl -lne 'print $$1 if /\((.*?)\)/' | tail -n 1)" + +DESTINATION = $(if $(DESTINATION_ID),"id=$(DESTINATION_ID)",$(value $(call toupper,$(call basesdk,$(SDK)))_GENERIC_DESTINATION)) + +# Xcodebuild + +DESTINATION_MESSAGE = "Running $(call tolower,$(CONFIGURATION)) $(ACTION) \ + on '$(DESTINATION_NAME)' ($(DESTINATION_ID))$(if $(DESTINATION_OS),$(,) $(DESTINATION_PLATFORM) $(DESTINATION_OS),)" + +xcodebuild-%: + @$(if $(DESTINATION_NAME), echo $(DESTINATION_MESSAGE),) + xcodebuild $(ACTION) -scheme $(TARGET) $(if $(SDK), -sdk $(SDK),) $(if $(CONFIGURATION), -configuration $(CONFIGURATION),) $(if $(DESTINATION), -destination $(DESTINATION) -destination-timeout 1,) + +xcodebuild-check-device_%: DESTINATION_ID=$(lastword $(subst _, ,$@)) + +# Special check target (requires SECONDEXPANSION due to devices) +.SECONDEXPANSION: +check-%: ACTION = test +check-%: $$(foreach device, $$(DEVICES), xcodebuild-check-device_$$(device)) ; + @echo $(if $^, Ran $(call tolower,$(CONFIGURATION)) tests on $(words $^) $(SDK) destination\(s\): $(DEVICES), No compatible test devices found for \'$(SDK)\' SDK && false) + +# Determined by device +check-%: SDK = + +# Default to debug for testing +check-%: CONFIGURATION = Debug + diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index c6ff808a9990171d5d87308edf7af125d02ed051..019c220de5c95e84b01a2b79bd1d39714beb6acb 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -23,7 +23,7 @@ QMAKE_COMPILER = gcc QMAKE_CC = $${CROSS_COMPILE}gcc QMAKE_LEX = flex QMAKE_LEXFLAGS = -QMAKE_YACC = byacc +QMAKE_YACC = bison -y QMAKE_YACCFLAGS = -d QMAKE_CFLAGS = -pipe -fno-keep-inline-dllexport QMAKE_CFLAGS_DEPS = -M @@ -56,6 +56,7 @@ QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions QMAKE_CXXFLAGS_CXX11 = -std=c++0x +QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++0x QMAKE_CXXFLAGS_SPLIT_SECTIONS = $$QMAKE_CFLAGS_SPLIT_SECTIONS QMAKE_INCDIR = diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf index 2ec0d84918f6ee361a838896675eac90ecad0aa9..31c87fff26ea8deed3297e3c635f2c3d4ed1269f 100644 --- a/mkspecs/win32-icc/qmake.conf +++ b/mkspecs/win32-icc/qmake.conf @@ -15,7 +15,7 @@ QMAKE_COMPILER = msvc intel_icl # icl pretends to be msvc QMAKE_CC = icl QMAKE_LEX = flex QMAKE_LEXFLAGS = -QMAKE_YACC = byacc +QMAKE_YACC = bison -y QMAKE_YACCFLAGS = -d QMAKE_CFLAGS = -nologo -Zm200 /Qprec /Qwd1744,1738 QMAKE_CFLAGS_WARN_ON = -W3 /Qwd673 diff --git a/mkspecs/wince80colibri-armv7-msvc2012/qmake.conf b/mkspecs/wince80colibri-armv7-msvc2012/qmake.conf new file mode 100644 index 0000000000000000000000000000000000000000..47c512bbda780b50ae4538016fdfa533d11091c2 --- /dev/null +++ b/mkspecs/wince80colibri-armv7-msvc2012/qmake.conf @@ -0,0 +1,47 @@ +# qmake configuration for Windows Embedded Compact 2013 with VS2012 on ARM targets +# +# This is just a template for creating WEC2013 mkspecs for ARM targets +# Replace the SDK name with actual SDK name. + +include(../common/wince/qmake.conf) + +CE_SDK = Toradex_CE8_SDK # replace with actual SDK name +CE_ARCH = ARMV7 +QT_CONFIG -= accessibility + +DEFINES += QT_NO_CLIPBOARD QT_NO_ACCESSIBILITY QT_NO_NATIVE_GESTURES QT_NOSTANDARDSHELL_UI_MODEL _CRT_SECURE_NO_DEPRECATE _WIN32_WCE=0x800 $$CE_ARCH _AMRV7_ armv7 _ARM_ UNDER_CE WINCE ARM + +#QMAKE_CXXFLAGS += /P +QMAKE_CFLAGS_RELEASE += -O2 -MT +QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi +QMAKE_CFLAGS_DEBUG += -Zi -MTd +QMAKE_CFLAGS_RELEASE -= -MD +QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO -= -MD +QMAKE_CFLAGS_DEBUG -= -MDd +QMAKE_CXXFLAGS_RELEASE -= -MD +QMAKE_CXXFLAGS_RELEASE += -MT +QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += -MT +QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO -= -MD +QMAKE_CXXFLAGS_DEBUG -= -MDd +QMAKE_CXXFLAGS_DEBUG += -MTd +QMAKE_INCDIR_OPENGL_ES2 += $$(NV_WINCE_T2_PLAT)/include +QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:WINDOWSCE,8.00 /MACHINE:ARM /ENTRY:mainCRTStartup +QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWSCE,8.00 /MACHINE:ARM +QMAKE_LFLAGS_DLL = /SUBSYSTEM:WINDOWSCE,8.00 /MACHINE:ARM /DLL /SAFESEH:NO +QMAKE_LIBFLAGS_RELEASE = /LTCG +QMAKE_LIBS = coredll.lib +QMAKE_LIBS_CORE = ole32.lib oleaut32.lib uuid.lib commctrl.lib coredll.lib winsock.lib +QMAKE_LIBS_GUI = ole32.lib $$QMAKE_LIBS_CORE +QMAKE_LIBS_NETWORK = ws2.lib $$QMAKE_LIBS_GUI +QMAKE_LIBS_OPENGL = +QMAKE_LIBS_COMPAT = +QMAKE_LIBS_OPENVG = +QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib +QMAKE_LIBDIR_OPENGL_ES2 = $$(NV_WINCE_T2_PLAT)/lib/Test +QMAKE_INCDIR_EGL = $$(NV_WINCE_T2_PLAT)/include +QMAKE_LIBDIR_EGL = $$(NV_WINCE_T2_PLAT)/lib/Test + +QMAKE_RC = rc + +QMAKE_COMPILER_DEFINES -= _MSC_VER=1400 +QMAKE_COMPILER_DEFINES += _MSC_VER=1700 diff --git a/tests/auto/widgets/kernel/qapplication/wincmdline/main.cpp b/mkspecs/wince80colibri-armv7-msvc2012/qplatformdefs.h similarity index 83% rename from tests/auto/widgets/kernel/qapplication/wincmdline/main.cpp rename to mkspecs/wince80colibri-armv7-msvc2012/qplatformdefs.h index 2d86b46875eb034b6844ce813ad68756db2866fa..e302bdab03e0d47dd3fed5704386530417703ad3 100644 --- a/tests/auto/widgets/kernel/qapplication/wincmdline/main.cpp +++ b/mkspecs/wince80colibri-armv7-msvc2012/qplatformdefs.h @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the test suite of the Qt Toolkit. +** This file is part of the qmake spec of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL21$ ** Commercial License Usage @@ -30,17 +30,6 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include <QApplication> -#include <stdio.h> -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - if (argc > 1) - fprintf(stderr, "%s", argv[1]); - else - fprintf(stderr, "Failed"); - fflush(stderr); - return 0; -} +#include "../common/wince/qplatformdefs.h" diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 6f855ba9ca63b8dfd57d2c4f0235503a51001e3f..eb484e950179fadcff4d09ec37fa49ed15ea68ae 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -2185,52 +2185,10 @@ \section1 QT - Specifies the Qt modules that are used by your project. + Specifies the \l{All Modules}{Qt modules} that are used by your project. For + the value to add for each module, see the module documentation. - The table below shows the options that can be used with the \c QT variable - and the Qt modules that are associated with each of them: - - \table - \header \li Option \li Module Enabled - \row \li axcontainer \li \l{Using ActiveX controls and COM in Qt} - {QAxContainer}, which is - part of the \l{Active Qt} framework - \row \li axserver \li \l{Building ActiveX servers in Qt} - {QAxServer}, which is - part of the \l{Active Qt} framework - \row \li concurrent \li \l{Qt Concurrent} - \row \li core (included by default) \li \l{Qt Core} - \row \li dbus \li \l{Qt D-Bus} - \row \li declarative \li \l{Qt Quick 1} (deprecated) - \row \li designer \li \l{Qt Designer} - \row \li gui (included by default) \li \l{Qt GUI} - \row \li help \li \l{Qt Help} - \row \li multimedia \li \l{Qt Multimedia} - \row \li multimediawidgets \li \l{Qt Multimedia Widgets} - \row \li network \li \l{Qt Network} - \row \li opengl \li \l{Qt OpenGL} (deprecated) - \row \li printsupport \li \l{Qt Print Support} - \row \li qml \li \l{Qt QML} - \row \li qmltest \li \l{Qt QML Test} - \row \li x11extras \li \l{Qt X11 Extras} - \row \li quick \li \l{Qt Quick} - \row \li script \li \l{Qt Script} (deprecated) - \row \li scripttools \li \l{Qt Script Tools} (deprecated) - \row \li sensors \li \l{Qt Sensors} - \row \li serialport \li \l{Qt Serial Port} - \row \li sql \li \l{Qt SQL} - \row \li svg \li \l{Qt SVG} - \row \li testlib \li \l{Qt Test} - \row \li uitools \li \l{Qt UI Tools} - \row \li webkit \li \l{Qt WebKit} - \row \li webkitwidgets \li \l{Qt WebKit Widgets} - \row \li widgets \li \l{Qt Widgets} - \row \li winextras \li \l{Qt Windows Extras} - \row \li xml \li \l{Qt XML} (deprecated) - \row \li xmlpatterns \li \l{Qt XML Patterns} - \endtable - - By default, \c QT contains both \c core and \c gui, ensuring that standard + By default, \c QT contains \c core and \c gui, ensuring that standard GUI applications can be built without further configuration. If you want to build a project \e without the \l{Qt GUI} module, you need to diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index deacac2c8378af18fb835b02f852757e71f5dfec..81bb0683ac59e5965836f1d5d2536c5db088be16 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1408,6 +1408,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QMap<QString, QString> settings; settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO")); + // Bitcode is only supported with a deployment target >= iOS 6.0. + // Disable it for now, and consider switching it on when later + // bumping the deployment target. + settings.insert("ENABLE_BITCODE", "NO"); settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", as_release ? "NO" : "YES"); if(!as_release) settings.insert("GCC_OPTIMIZATION_LEVEL", "0"); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 5cde7c4ac2739f6a71afe87453b6cec0b84fa845..6fb2e7d0a1c1398198a0a08b2a4a107edd1894bf 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -306,7 +306,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "include " << escapeDependencyPath(*it) << endl; /* rules */ - t << "first: all\n"; + t << "first:" << (!project->isActiveConfig("no_default_goal_deps") ? " all" : "") << "\n"; t << "####### Implicit rules\n\n"; t << ".SUFFIXES: " << Option::obj_ext; for(QStringList::Iterator cit = Option::c_ext.begin(); cit != Option::c_ext.end(); ++cit) diff --git a/qmake/generators/win32/cesdkhandler.cpp b/qmake/generators/win32/cesdkhandler.cpp index cbee1d0dbda59b92112dcd6b20e6401fc7c0a25d..f8235bae279680d1be062037f8e2548adfb0fb74 100644 --- a/qmake/generators/win32/cesdkhandler.cpp +++ b/qmake/generators/win32/cesdkhandler.cpp @@ -49,6 +49,7 @@ struct PropertyContainer QString value; QMap<QString, PropertyContainer> properties; }; +Q_DECLARE_TYPEINFO(PropertyContainer, Q_MOVABLE_TYPE); CeSdkInfo::CeSdkInfo() : m_major(0) , m_minor(0) { @@ -60,7 +61,7 @@ CeSdkHandler::CeSdkHandler() struct ContainsPathKey { - bool operator()(const QString &val) + bool operator()(const QString &val) const { return !(val.endsWith(QStringLiteral("MSBuildToolsPath")) || val.endsWith(QStringLiteral("MSBuildToolsRoot"))); @@ -69,8 +70,8 @@ struct ContainsPathKey struct ValueFromKey { - ValueFromKey(const QSettings *settings) : settings(settings){} - QString operator()(const QString &key) + explicit ValueFromKey(const QSettings *settings) : settings(settings) {} + QString operator()(const QString &key) const { return settings->value(key).toString(); } @@ -178,13 +179,14 @@ QStringList CeSdkHandler::filterMsBuildToolPaths(const QStringList &paths) const { QStringList result; foreach (const QString &path, paths) { - QDir dir(path); + QDir dirVC110(path); if (path.endsWith(QStringLiteral("bin"))) - dir.cdUp(); - if (dir.cd(QStringLiteral("Microsoft.Cpp\\v4.0\\V110\\Platforms")) - || dir.cd(QStringLiteral("Microsoft.Cpp\\v4.0\\V120\\Platforms"))) { - result << dir.absolutePath(); - } + dirVC110.cdUp(); + QDir dirVC120 = dirVC110; + if (dirVC110.cd(QStringLiteral("Microsoft.Cpp\\v4.0\\V110\\Platforms"))) + result << dirVC110.absolutePath(); + if (dirVC120.cd(QStringLiteral("Microsoft.Cpp\\v4.0\\V120\\Platforms"))) + result << dirVC120.absolutePath(); } return result; } @@ -286,6 +288,8 @@ void CeSdkHandler::retrieveWEC2013SDKs() currentSdk.m_minor = currentProperty.properties.value(QLatin1String("OSMinor")).value.toInt(); retrieveEnvironment(currentProperty.properties.value(QLatin1String("MSBuild Files110")).value.split(';'), filteredToolPaths, ¤tSdk); + retrieveEnvironment(currentProperty.properties.value(QLatin1String("MSBuild Files120")).value.split(';'), + filteredToolPaths, ¤tSdk); if (!currentSdk.m_include.isEmpty()) m_list.append(currentSdk); } diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index dfa8f8837b7d133022bcfdd7b872977e1224cf2d..aff8d9fcad0fcc11330fe125d81b5256661ab1f4 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -231,6 +231,9 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) << kitDir + QStringLiteral("/include/shared") << kitDir + QStringLiteral("/include/winrt"); } + + binDirs << vcInstallDir + QStringLiteral("/bin"); + // Inherit PATH binDirs << QString::fromLocal8Bit(qgetenv("PATH")).split(QLatin1Char(';')); diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index aa7320bc277455c7b8321ae6eed81c28650daee0..09937c8ac205c926566bf5291fbaaea6a096cb25 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -2238,6 +2238,8 @@ void VCFilter::modifyPCHstage(QString str) CompilerTool.UsePrecompiledHeader = (isCFile ? pchNone : pchCreateUsingSpecific); if (isCFile) CompilerTool.PrecompiledHeaderThrough = QLatin1String("$(NOINHERIT)"); + else if (autogenSourceFile) + CompilerTool.PrecompiledHeaderThrough = Project->precompHFilename; CompilerTool.ForcedIncludeFiles = QStringList("$(NOINHERIT)"); } diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 8e247d9afab0a78128635d20b47e176f802b32c2..cfb95b946ce80c9b297bd9d596c54d4ae946ce10 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -88,7 +88,7 @@ static int idealThreadCount() // we don't need them all here int cores = 1; # if defined(Q_OS_BSD4) - // FreeBSD, OpenBSD, NetBSD, BSD/OS, Mac OS X + // FreeBSD, OpenBSD, NetBSD, BSD/OS, OS X size_t len = sizeof(cores); int mib[2]; mib[0] = CTL_HW; diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index a60adde84e524d5ffa5471a9040c2e4c2f1a7369..8995d495829576090ab34e1618196381682f1c61 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -310,6 +310,7 @@ public: QMakeHandler *m_handler; QMakeVfs *m_vfs; }; +Q_DECLARE_TYPEINFO(QMakeEvaluator::Location, Q_PRIMITIVE_TYPE); Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeEvaluator::LoadFlags) diff --git a/qtbase.pro b/qtbase.pro index 51e8fb8760b5c37cdaa4d29d0e19f8fcf0149a6b..24d0f5287ba26ee0e53e34c8860c6c7baf7b0268 100644 --- a/qtbase.pro +++ b/qtbase.pro @@ -49,7 +49,7 @@ INSTALLS += qmake #licheck licheck.path = $$[QT_HOST_BINS] licheck.files = $$PWD/bin/$$QT_LICHECK -exists($$licheck.files): INSTALLS += licheck +!isEmpty(QT_LICHECK): INSTALLS += licheck #syncqt syncqt.path = $$[QT_HOST_BINS] diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c index 8d08f403ecb8bed7839176c6bd7678282c8ba654..39eeb6a202a7f66dfab96057c86fb0adef9b44bb 100644 --- a/src/3rdparty/forkfd/forkfd.c +++ b/src/3rdparty/forkfd/forkfd.c @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Intel Corporation +** Copyright (C) 2015 Intel Corporation ** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com ** ** Permission is hereby granted, free of charge, to any person obtaining a copy @@ -25,12 +25,13 @@ #ifndef _GNU_SOURCE # define _GNU_SOURCE -# define _POSIX_C_SOURCE 200809L -# define _XOPEN_SOURCE 700 #endif + #include "forkfd.h" #include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> #include <sys/wait.h> #include <assert.h> #include <errno.h> @@ -38,9 +39,11 @@ #include <signal.h> #include <stdlib.h> #include <string.h> +#include <time.h> #include <unistd.h> #ifdef __linux__ +# define HAVE_WAIT4 1 # if (defined(__GLIBC__) && (__GLIBC__ << 16) + __GLIBC_MINOR__ >= 0x207) || defined(__BIONIC__) # include <sys/eventfd.h> # define HAVE_EVENTFD 1 @@ -53,6 +56,10 @@ #if _POSIX_VERSION-0 >= 200809L || _XOPEN_VERSION-0 >= 500 # define HAVE_WAITID 1 #endif +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) || \ + defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) +# define HAVE_WAIT4 1 +#endif #if defined(__APPLE__) /* Up until OS X 10.7, waitid(P_ALL, ...) will return success, but will not @@ -79,6 +86,12 @@ ret = call; \ } while (ret == -1 && errno == EINTR) +struct pipe_payload +{ + struct forkfd_info info; + struct rusage rusage; +}; + typedef struct process_info { ffd_atomic_int pid; @@ -179,34 +192,55 @@ static int isChildReady(pid_t pid, siginfo_t *info) } #endif -static int tryReaping(pid_t pid, siginfo_t *info) +static void convertStatusToForkfdInfo(int status, struct forkfd_info *info) { - /* reap the child */ -#ifdef HAVE_WAITID - if (waitid_works) { - // we have waitid(2), which fills in siginfo_t for us - info->si_pid = 0; - return waitid(P_PID, pid, info, WEXITED | WNOHANG) == 0 && info->si_pid == pid; - } -#endif - - int status; - if (waitpid(pid, &status, WNOHANG) <= 0) - return 0; // child did not change state - - info->si_signo = SIGCHLD; - info->si_pid = pid; if (WIFEXITED(status)) { - info->si_code = CLD_EXITED; - info->si_status = WEXITSTATUS(status); + info->code = CLD_EXITED; + info->status = WEXITSTATUS(status); } else if (WIFSIGNALED(status)) { - info->si_code = CLD_KILLED; + info->code = CLD_KILLED; # ifdef WCOREDUMP if (WCOREDUMP(status)) - info->si_code = CLD_DUMPED; + info->code = CLD_DUMPED; # endif - info->si_status = WTERMSIG(status); + info->status = WTERMSIG(status); } +} + +static int tryReaping(pid_t pid, struct pipe_payload *payload) +{ + /* reap the child */ +#if defined(HAVE_WAIT4) + int status; + if (wait4(pid, &status, WNOHANG, &payload->rusage) <= 0) + return 0; + convertStatusToForkfdInfo(status, &payload->info); +#else +# if defined(HAVE_WAITID) + if (waitid_works) { + /* we have waitid(2), which gets us some payload values on some systems */ + siginfo_t info; + info.si_pid = 0; + int ret = waitid(P_PID, pid, &info, WEXITED | WNOHANG) == 0 && info.si_pid == pid; + if (!ret) + return ret; + + payload->info.code = info.si_code; + payload->info.status = info.si_status; +# ifdef __linux__ + payload->rusage.ru_utime.tv_sec = info.si_utime / CLOCKS_PER_SEC; + payload->rusage.ru_utime.tv_usec = info.si_utime % CLOCKS_PER_SEC; + payload->rusage.ru_stime.tv_sec = info.si_stime / CLOCKS_PER_SEC; + payload->rusage.ru_stime.tv_usec = info.si_stime % CLOCKS_PER_SEC; +# endif + return 1; + } +# endif // HAVE_WAITID + int status; + if (waitpid(pid, &status, WNOHANG) <= 0) + return 0; // child did not change state + convertStatusToForkfdInfo(status, &payload->info); +#endif // !HAVE_WAIT4 return 1; } @@ -220,10 +254,11 @@ static void freeInfo(Header *header, ProcessInfo *entry) assert(header->busyCount >= 0); } -static void notifyAndFreeInfo(Header *header, ProcessInfo *entry, siginfo_t *info) +static void notifyAndFreeInfo(Header *header, ProcessInfo *entry, + const struct pipe_payload *payload) { ssize_t ret; - EINTR_LOOP(ret, write(entry->deathPipe, info, sizeof(*info))); + EINTR_LOOP(ret, write(entry->deathPipe, payload, sizeof(*payload))); EINTR_LOOP(ret, close(entry->deathPipe)); freeInfo(header, entry); @@ -243,9 +278,11 @@ static void sigchld_handler(int signum) /* is this one of our children? */ BigArray *array; siginfo_t info; + struct pipe_payload payload; int i; memset(&info, 0, sizeof info); + memset(&payload, 0, sizeof payload); #ifdef HAVE_WAITID if (!waitid_works) @@ -275,8 +312,8 @@ search_next_child: FFD_ATOMIC_ACQUIRE, FFD_ATOMIC_RELAXED)) { /* this is our child, send notification and free up this entry */ /* ### FIXME: what if tryReaping returns false? */ - if (tryReaping(pid, &info)) - notifyAndFreeInfo(&children.header, &children.entries[i], &info); + if (tryReaping(pid, &payload)) + notifyAndFreeInfo(&children.header, &children.entries[i], &payload); goto search_next_child; } } @@ -290,8 +327,8 @@ search_next_child: FFD_ATOMIC_ACQUIRE, FFD_ATOMIC_RELAXED)) { /* this is our child, send notification and free up this entry */ /* ### FIXME: what if tryReaping returns false? */ - if (tryReaping(pid, &info)) - notifyAndFreeInfo(&array->header, &array->entries[i], &info); + if (tryReaping(pid, &payload)) + notifyAndFreeInfo(&array->header, &array->entries[i], &payload); goto search_next_child; } } @@ -321,9 +358,9 @@ search_arrays: continue; } #endif - if (tryReaping(pid, &info)) { + if (tryReaping(pid, &payload)) { /* this is our child, send notification and free up this entry */ - notifyAndFreeInfo(&children.header, &children.entries[i], &info); + notifyAndFreeInfo(&children.header, &children.entries[i], &payload); } } @@ -344,9 +381,9 @@ search_arrays: continue; } #endif - if (tryReaping(pid, &info)) { + if (tryReaping(pid, &payload)) { /* this is our child, send notification and free up this entry */ - notifyAndFreeInfo(&array->header, &array->entries[i], &info); + notifyAndFreeInfo(&array->header, &array->entries[i], &payload); } } @@ -463,6 +500,14 @@ static int create_pipe(int filedes[], int flags) return ret; } +static const int system_has_forkfd = 0; +static int system_forkfd(int flags, pid_t *ppid) +{ + (void)flags; + (void)ppid; + return -1; +} + #ifndef FORKFD_NO_FORKFD /** * @brief forkfd returns a file descriptor representing a child process @@ -510,6 +555,12 @@ int forkfd(int flags, pid_t *ppid) int efd; #endif + if (system_has_forkfd) { + ret = system_forkfd(flags, ppid); + if (system_has_forkfd) + return ret; + } + (void) pthread_once(&forkfd_initialization, forkfd_initialize); info = allocateInfo(&header); @@ -626,13 +677,15 @@ int spawnfd(int flags, pid_t *ppid, const char *path, const posix_spawn_file_act { Header *header; ProcessInfo *info; - siginfo_t si; + struct pipe_payload payload; pid_t pid; int death_pipe[2]; int ret = -1; /* we can only do work if we have a way to start the child in stopped mode; * otherwise, we have a major race condition. */ + assert(!system_has_forkfd); + (void) pthread_once(&forkfd_initialization, forkfd_initialize); info = allocateInfo(&header); @@ -664,8 +717,8 @@ int spawnfd(int flags, pid_t *ppid, const char *path, const posix_spawn_file_act ffd_atomic_store(&info->pid, pid, FFD_ATOMIC_RELEASE); /* check if the child has already exited */ - if (tryReaping(pid, &si)) - notifyAndFreeInfo(header, info, &si); + if (tryReaping(pid, &payload)) + notifyAndFreeInfo(header, info, &payload); ret = death_pipe[0]; return ret; @@ -682,3 +735,28 @@ out: return -1; } #endif // _POSIX_SPAWN && !FORKFD_NO_SPAWNFD + + +int forkfd_wait(int ffd, forkfd_info *info, struct rusage *rusage) +{ + struct pipe_payload payload; + int ret; + + ret = read(ffd, &payload, sizeof(payload)); + if (ret == -1) + return ret; /* pass errno, probably EINTR, EBADF or EWOULDBLOCK */ + + assert(ret == sizeof(payload)); + if (info) + *info = payload.info; + if (rusage) + *rusage = payload.rusage; + + return 0; /* success */ +} + + +int forkfd_close(int ffd) +{ + return close(ffd); +} diff --git a/src/3rdparty/forkfd/forkfd.h b/src/3rdparty/forkfd/forkfd.h index b3ffe2bff3f955e21677604c420ca81d7cf61e0a..dcb36f9f33da389fce0f66855529b0f7aa00fe22 100644 --- a/src/3rdparty/forkfd/forkfd.h +++ b/src/3rdparty/forkfd/forkfd.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Intel Corporation +** Copyright (C) 2015 Intel Corporation ** ** Permission is hereby granted, free of charge, to any person obtaining a copy ** of this software and associated documentation files (the "Software"), to deal @@ -26,6 +26,7 @@ #define FORKFD_H #include <fcntl.h> +#include <stdint.h> #include <unistd.h> // to get the POSIX flags #ifdef _POSIX_SPAWN @@ -41,7 +42,14 @@ extern "C" { #define FFD_CHILD_PROCESS (-2) +struct forkfd_info { + int32_t code; + int32_t status; +}; + int forkfd(int flags, pid_t *ppid); +int forkfd_wait(int ffd, forkfd_info *info, struct rusage *rusage); +int forkfd_close(int ffd); #ifdef _POSIX_SPAWN /* only for spawnfd: */ diff --git a/src/3rdparty/libjpeg.pri b/src/3rdparty/libjpeg.pri index 82c6ed536db9790742b29238ee823b903671a1ea..62077c99a9496a9dcfb4743ceda31bd4224cb2fb 100644 --- a/src/3rdparty/libjpeg.pri +++ b/src/3rdparty/libjpeg.pri @@ -1,4 +1,4 @@ -wince*: { +wince { DEFINES += NO_GETENV contains(CE_ARCH,x86):CONFIG -= stl exceptions contains(CE_ARCH,x86):CONFIG += exceptions_off diff --git a/src/3rdparty/pcre/patches/0001-Re-fix-X86-Wince-builds.patch b/src/3rdparty/pcre/patches/0001-Re-fix-X86-Wince-builds.patch new file mode 100644 index 0000000000000000000000000000000000000000..8cb3c8c60887869e187158e182ed566782af3ccf --- /dev/null +++ b/src/3rdparty/pcre/patches/0001-Re-fix-X86-Wince-builds.patch @@ -0,0 +1,35 @@ +From 121e4d1ad09bdbfeb8a871d4f2c3ffe1acb8e2d6 Mon Sep 17 00:00:00 2001 +From: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> +Date: Tue, 30 Jun 2015 09:41:39 +0200 +Subject: [PATCH] Re-fix X86 Wince builds. + +eebb8de21ce4845866f15e444a4c78fc2cbb7f3f fixed the PCRE +build, but was accidentally overwritten by a subsequent +import of the PCRE tarball. + +Now put the same patch also into patches/ so that we don't +forget it needs to be manually applied. + +Change-Id: I93c2ee9c2e2dd1c48d391ce7e16d33208fb2cbbb +--- + src/3rdparty/pcre/sljit/sljitNativeX86_common.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/3rdparty/pcre/sljit/sljitNativeX86_common.c b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c +index 22a163f..21b276f 100644 +--- a/src/3rdparty/pcre/sljit/sljitNativeX86_common.c ++++ b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c +@@ -273,7 +273,9 @@ static sljit_si cpu_has_sse2 = -1; + #endif + static sljit_si cpu_has_cmov = -1; + +-#if defined(_MSC_VER) && _MSC_VER >= 1400 ++#ifdef _WIN32_WCE ++#include <cmnintrin.h> ++#elif defined(_MSC_VER) && _MSC_VER >= 1400 + #include <intrin.h> + #endif + +-- +1.9.1 + diff --git a/src/3rdparty/pcre/sljit/sljitNativeX86_common.c b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c index 22a163fcc6642adb7fba52db09c4f37c6141f8e8..21b276fb8d6325ce7c556e80b50ea951fac5f0f3 100644 --- a/src/3rdparty/pcre/sljit/sljitNativeX86_common.c +++ b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c @@ -273,7 +273,9 @@ static sljit_si cpu_has_sse2 = -1; #endif static sljit_si cpu_has_cmov = -1; -#if defined(_MSC_VER) && _MSC_VER >= 1400 +#ifdef _WIN32_WCE +#include <cmnintrin.h> +#elif defined(_MSC_VER) && _MSC_VER >= 1400 #include <intrin.h> #endif diff --git a/src/3rdparty/sqlite/shell.c b/src/3rdparty/sqlite/shell.c index 9c0481c0dd15b5c30f6e309bddcb647e22f83f6a..7db8dbda0ae52718842803e6ad795b467920e76f 100644 --- a/src/3rdparty/sqlite/shell.c +++ b/src/3rdparty/sqlite/shell.c @@ -24,6 +24,13 @@ #include "msvc.h" #endif +/* +** No support for loadable extensions in VxWorks. +*/ +#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION +# define SQLITE_OMIT_LOAD_EXTENSION 1 +#endif + /* ** Enable large-file support for fopen() and friends on unix. */ @@ -59,18 +66,38 @@ # include <readline/readline.h> # include <readline/history.h> #endif + #if HAVE_EDITLINE -# undef HAVE_READLINE -# define HAVE_READLINE 1 # include <editline/readline.h> #endif -#if !HAVE_READLINE -# define add_history(X) -# define read_history(X) -# define write_history(X) -# define stifle_history(X) + +#if HAVE_EDITLINE || HAVE_READLINE + +# define shell_add_history(X) add_history(X) +# define shell_read_history(X) read_history(X) +# define shell_write_history(X) write_history(X) +# define shell_stifle_history(X) stifle_history(X) +# define shell_readline(X) readline(X) + +#elif HAVE_LINENOISE + +# include "linenoise.h" +# define shell_add_history(X) linenoiseHistoryAdd(X) +# define shell_read_history(X) linenoiseHistoryLoad(X) +# define shell_write_history(X) linenoiseHistorySave(X) +# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X) +# define shell_readline(X) linenoise(X) + +#else + +# define shell_read_history(X) +# define shell_write_history(X) +# define shell_stifle_history(X) + +# define SHELL_USE_LOCAL_GETLINE 1 #endif + #if defined(_WIN32) || defined(WIN32) # include <io.h> # include <fcntl.h> @@ -87,10 +114,15 @@ */ extern int isatty(int); -/* popen and pclose are not C89 functions and so are sometimes omitted from -** the <stdio.h> header */ -extern FILE *popen(const char*,const char*); -extern int pclose(FILE*); +#if !defined(__RTP__) && !defined(_WRS_KERNEL) + /* popen and pclose are not C89 functions and so are sometimes omitted from + ** the <stdio.h> header */ + extern FILE *popen(const char*,const char*); + extern int pclose(FILE*); +#else +# define SQLITE_OMIT_POPEN 1 +#endif + #endif #if defined(_WIN32_WCE) @@ -106,6 +138,26 @@ extern int pclose(FILE*); #define IsDigit(X) isdigit((unsigned char)X) #define ToLower(X) (char)tolower((unsigned char)X) +/* On Windows, we normally run with output mode of TEXT so that \n characters +** are automatically translated into \r\n. However, this behavior needs +** to be disabled in some cases (ex: when generating CSV output and when +** rendering quoted strings that contain \n characters). The following +** routines take care of that. +*/ +#if defined(_WIN32) || defined(WIN32) +static void setBinaryMode(FILE *out){ + fflush(out); + _setmode(_fileno(out), _O_BINARY); +} +static void setTextMode(FILE *out){ + fflush(out); + _setmode(_fileno(out), _O_TEXT); +} +#else +# define setBinaryMode(X) +# define setTextMode(X) +#endif + /* True if the timer is enabled */ static int enableTimer = 0; @@ -125,11 +177,19 @@ static sqlite3_int64 timeOfDay(void){ return t; } -#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \ - && !defined(__minux) +#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) #include <sys/time.h> #include <sys/resource.h> +/* VxWorks does not support getrusage() as far as we can determine */ +#if defined(_WRS_KERNEL) || defined(__RTP__) +struct rusage { + struct timeval ru_utime; /* user CPU time used */ + struct timeval ru_stime; /* system CPU time used */ +}; +#define getrusage(A,B) memset(B,0,sizeof(*B)) +#endif + /* Saved resource information for the beginning of an operation */ static struct rusage sBegin; /* CPU time at start */ static sqlite3_int64 iBegin; /* Wall-clock time at start */ @@ -155,8 +215,8 @@ static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ */ static void endTimer(void){ if( enableTimer ){ - struct rusage sEnd; sqlite3_int64 iEnd = timeOfDay(); + struct rusage sEnd; getrusage(RUSAGE_SELF, &sEnd); printf("Run Time: real %.3f user %f sys %f\n", (iEnd - iBegin)*0.001, @@ -276,7 +336,7 @@ static int stdin_is_interactive = 1; ** to this database a static variable so that it can be accessed ** by the SIGINT handler to interrupt database processing. */ -static sqlite3 *db = 0; +static sqlite3 *globalDb = 0; /* ** True if an interrupt (Control-C) has been received. @@ -310,7 +370,7 @@ static FILE *iotrace = 0; ** is written to iotrace. */ #ifdef SQLITE_ENABLE_IOTRACE -static void iotracePrintf(const char *zFormat, ...){ +static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){ va_list ap; char *z; if( iotrace==0 ) return; @@ -431,14 +491,14 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ zResult = local_getline(zPrior, in); }else{ zPrompt = isContinuation ? continuePrompt : mainPrompt; -#if HAVE_READLINE - free(zPrior); - zResult = readline(zPrompt); - if( zResult && *zResult ) add_history(zResult); -#else +#if SHELL_USE_LOCAL_GETLINE printf("%s", zPrompt); fflush(stdout); zResult = local_getline(zPrior, stdin); +#else + free(zPrior); + zResult = shell_readline(zPrompt); + if( zResult && *zResult ) shell_add_history(zResult); #endif } return zResult; @@ -467,6 +527,7 @@ struct ShellState { int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ int statsOn; /* True to display memory stats before each finalize */ int scanstatsOn; /* True to display scan stats before each finalize */ + int backslashOn; /* Resolve C-style \x escapes in SQL input text */ int outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ @@ -584,6 +645,7 @@ static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ static void output_quoted_string(FILE *out, const char *z){ int i; int nSingle = 0; + setBinaryMode(out); for(i=0; z[i]; i++){ if( z[i]=='\'' ) nSingle++; } @@ -606,6 +668,7 @@ static void output_quoted_string(FILE *out, const char *z){ } fprintf(out,"'"); } + setTextMode(out); } /* @@ -742,7 +805,7 @@ static void interrupt_handler(int NotUsed){ UNUSED_PARAMETER(NotUsed); seenInterrupt++; if( seenInterrupt>2 ) exit(1); - if( db ) sqlite3_interrupt(db); + if( globalDb ) sqlite3_interrupt(globalDb); } #endif @@ -908,10 +971,7 @@ static int shell_callback( break; } case MODE_Csv: { -#if defined(WIN32) || defined(_WIN32) - fflush(p->out); - _setmode(_fileno(p->out), _O_BINARY); -#endif + setBinaryMode(p->out); if( p->cnt++==0 && p->showHeader ){ for(i=0; i<nArg; i++){ output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); @@ -924,16 +984,22 @@ static int shell_callback( } fprintf(p->out, "%s", p->rowSeparator); } -#if defined(WIN32) || defined(_WIN32) - fflush(p->out); - _setmode(_fileno(p->out), _O_TEXT); -#endif + setTextMode(p->out); break; } case MODE_Insert: { p->cnt++; if( azArg==0 ) break; - fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable); + fprintf(p->out,"INSERT INTO %s",p->zDestTable); + if( p->showHeader ){ + fprintf(p->out,"("); + for(i=0; i<nArg; i++){ + char *zSep = i>0 ? ",": ""; + fprintf(p->out, "%s%s", zSep, azCol[i]); + } + fprintf(p->out,")"); + } + fprintf(p->out," VALUES("); for(i=0; i<nArg; i++){ char *zSep = i>0 ? ",": ""; if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ @@ -1134,7 +1200,7 @@ static char *save_err_msg( sqlite3 *db /* Database to query */ ){ int nErrMsg = 1+strlen30(sqlite3_errmsg(db)); - char *zErrMsg = sqlite3_malloc(nErrMsg); + char *zErrMsg = sqlite3_malloc64(nErrMsg); if( zErrMsg ){ memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg); } @@ -1371,8 +1437,8 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ /* Grow the p->aiIndent array as required */ if( iOp>=nAlloc ){ nAlloc += 100; - p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int)); - abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int)); + p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int)); + abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int)); } abYield[iOp] = str_in_array(zOp, azYield); p->aiIndent[iOp] = 0; @@ -1489,7 +1555,7 @@ static int shell_exec( if( xCallback ){ /* allocate space for col name ptr, value ptr, and type */ int nCol = sqlite3_column_count(pStmt); - void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1); + void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1); if( !pData ){ rc = SQLITE_NOMEM; }else{ @@ -1715,8 +1781,10 @@ static int run_schema_dump_query( static char zHelp[] = ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" ".bail on|off Stop after hitting an error. Default OFF\n" + ".binary on|off Turn binary output on or off. Default OFF\n" ".clone NEWDB Clone data into NEWDB from the existing database\n" ".databases List names and files of attached databases\n" + ".dbinfo ?DB? Show status information about the database\n" ".dump ?TABLE? ... Dump the database in an SQL text format\n" " If TABLE specified, only dump tables matching\n" " LIKE pattern TABLE.\n" @@ -1729,12 +1797,13 @@ static char zHelp[] = ".headers on|off Turn display of headers on or off\n" ".help Show this message\n" ".import FILE TABLE Import data from FILE into TABLE\n" - ".indices ?TABLE? Show names of all indices\n" - " If TABLE specified, only show indices for tables\n" + ".indexes ?TABLE? Show names of all indexes\n" + " If TABLE specified, only show indexes for tables\n" " matching LIKE pattern TABLE.\n" #ifdef SQLITE_ENABLE_IOTRACE ".iotrace FILE Enable I/O diagnostic logging to FILE\n" #endif + ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n" #ifndef SQLITE_OMIT_LOAD_EXTENSION ".load FILE ?ENTRY? Load an extension library\n" #endif @@ -1804,7 +1873,7 @@ static void readfileFunc( fseek(in, 0, SEEK_END); nIn = ftell(in); rewind(in); - pBuf = sqlite3_malloc( nIn ); + pBuf = sqlite3_malloc64( nIn ); if( pBuf && 1==fread(pBuf, nIn, 1, in) ){ sqlite3_result_blob(context, pBuf, nIn, sqlite3_free); }else{ @@ -1851,23 +1920,23 @@ static void open_db(ShellState *p, int keepAlive){ if( p->db==0 ){ sqlite3_initialize(); sqlite3_open(p->zDbFilename, &p->db); - db = p->db; - if( db && sqlite3_errcode(db)==SQLITE_OK ){ - sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0, + globalDb = p->db; + if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){ + sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0, shellstaticFunc, 0, 0); } - if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){ + if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ fprintf(stderr,"Error: unable to open database \"%s\": %s\n", - p->zDbFilename, sqlite3_errmsg(db)); + p->zDbFilename, sqlite3_errmsg(p->db)); if( keepAlive ) return; exit(1); } #ifndef SQLITE_OMIT_LOAD_EXTENSION sqlite3_enable_load_extension(p->db, 1); #endif - sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0, + sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0, readfileFunc, 0, 0); - sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0, + sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0, writefileFunc, 0, 0); } } @@ -1875,26 +1944,44 @@ static void open_db(ShellState *p, int keepAlive){ /* ** Do C-language style dequoting. ** +** \a -> alarm +** \b -> backspace ** \t -> tab ** \n -> newline +** \v -> vertical tab +** \f -> form feed ** \r -> carriage return +** \s -> space ** \" -> " -** \NNN -> ascii character NNN in octal +** \' -> ' ** \\ -> backslash +** \NNN -> ascii character NNN in octal */ static void resolve_backslashes(char *z){ int i, j; char c; while( *z && *z!='\\' ) z++; for(i=j=0; (c = z[i])!=0; i++, j++){ - if( c=='\\' ){ + if( c=='\\' && z[i+1]!=0 ){ c = z[++i]; - if( c=='n' ){ - c = '\n'; + if( c=='a' ){ + c = '\a'; + }else if( c=='b' ){ + c = '\b'; }else if( c=='t' ){ c = '\t'; + }else if( c=='n' ){ + c = '\n'; + }else if( c=='v' ){ + c = '\v'; + }else if( c=='f' ){ + c = '\f'; }else if( c=='r' ){ c = '\r'; + }else if( c=='"' ){ + c = '"'; + }else if( c=='\'' ){ + c = '\''; }else if( c=='\\' ){ c = '\\'; }else if( c>='0' && c<='7' ){ @@ -2064,7 +2151,7 @@ struct ImportCtx { static void import_append_char(ImportCtx *p, int c){ if( p->n+1>=p->nAlloc ){ p->nAlloc += p->nAlloc + 100; - p->z = sqlite3_realloc(p->z, p->nAlloc); + p->z = sqlite3_realloc64(p->z, p->nAlloc); if( p->z==0 ){ fprintf(stderr, "out of memory\n"); exit(1); @@ -2078,7 +2165,7 @@ static void import_append_char(ImportCtx *p, int c){ ** ** + Input comes from p->in. ** + Store results in p->z of length p->n. Space to hold p->z comes -** from sqlite3_malloc(). +** from sqlite3_malloc64(). ** + Use p->cSep as the column separator. The default is ",". ** + Use p->rSep as the row separator. The default is "\n". ** + Keep track of the line number in p->nLine. @@ -2086,7 +2173,7 @@ static void import_append_char(ImportCtx *p, int c){ ** EOF on end-of-file. ** + Report syntax errors on stderr */ -static char *csv_read_one_field(ImportCtx *p){ +static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){ int c; int cSep = p->cColSep; int rSep = p->cRowSep; @@ -2152,7 +2239,7 @@ static char *csv_read_one_field(ImportCtx *p){ ** ** + Input comes from p->in. ** + Store results in p->z of length p->n. Space to hold p->z comes -** from sqlite3_malloc(). +** from sqlite3_malloc64(). ** + Use p->cSep as the column separator. The default is "\x1F". ** + Use p->rSep as the row separator. The default is "\x1E". ** + Keep track of the row number in p->nLine. @@ -2160,7 +2247,7 @@ static char *csv_read_one_field(ImportCtx *p){ ** EOF on end-of-file. ** + Report syntax errors on stderr */ -static char *ascii_read_one_field(ImportCtx *p){ +static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){ int c; int cSep = p->cColSep; int rSep = p->cRowSep; @@ -2212,7 +2299,7 @@ static void tryToCloneData( goto end_data_xfer; } n = sqlite3_column_count(pQuery); - zInsert = sqlite3_malloc(200 + nTable + n*3); + zInsert = sqlite3_malloc64(200 + nTable + n*3); if( zInsert==0 ){ fprintf(stderr, "out of memory\n"); goto end_data_xfer; @@ -2402,7 +2489,9 @@ static void tryToClone(ShellState *p, const char *zNewDb){ */ static void output_reset(ShellState *p){ if( p->outfile[0]=='|' ){ +#ifndef SQLITE_OMIT_POPEN pclose(p->out); +#endif }else{ output_file_close(p->out); } @@ -2410,6 +2499,115 @@ static void output_reset(ShellState *p){ p->out = stdout; } +/* +** Run an SQL command and return the single integer result. +*/ +static int db_int(ShellState *p, const char *zSql){ + sqlite3_stmt *pStmt; + int res = 0; + sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ + res = sqlite3_column_int(pStmt,0); + } + sqlite3_finalize(pStmt); + return res; +} + +/* +** Convert a 2-byte or 4-byte big-endian integer into a native integer +*/ +unsigned int get2byteInt(unsigned char *a){ + return (a[0]<<8) + a[1]; +} +unsigned int get4byteInt(unsigned char *a){ + return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; +} + +/* +** Implementation of the ".info" command. +** +** Return 1 on error, 2 to exit, and 0 otherwise. +*/ +static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ + static const struct { const char *zName; int ofst; } aField[] = { + { "file change counter:", 24 }, + { "database page count:", 28 }, + { "freelist page count:", 36 }, + { "schema cookie:", 40 }, + { "schema format:", 44 }, + { "default cache size:", 48 }, + { "autovacuum top root:", 52 }, + { "incremental vacuum:", 64 }, + { "text encoding:", 56 }, + { "user version:", 60 }, + { "application id:", 68 }, + { "software version:", 96 }, + }; + static const struct { const char *zName; const char *zSql; } aQuery[] = { + { "number of tables:", + "SELECT count(*) FROM %s WHERE type='table'" }, + { "number of indexes:", + "SELECT count(*) FROM %s WHERE type='index'" }, + { "number of triggers:", + "SELECT count(*) FROM %s WHERE type='trigger'" }, + { "number of views:", + "SELECT count(*) FROM %s WHERE type='view'" }, + { "schema size:", + "SELECT total(length(sql)) FROM %s" }, + }; + sqlite3_file *pFile; + int i; + char *zSchemaTab; + char *zDb = nArg>=2 ? azArg[1] : "main"; + unsigned char aHdr[100]; + open_db(p, 0); + if( p->db==0 ) return 1; + sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile); + if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){ + return 1; + } + i = pFile->pMethods->xRead(pFile, aHdr, 100, 0); + if( i!=SQLITE_OK ){ + fprintf(stderr, "unable to read database header\n"); + return 1; + } + i = get2byteInt(aHdr+16); + if( i==1 ) i = 65536; + fprintf(p->out, "%-20s %d\n", "database page size:", i); + fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]); + fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]); + fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); + for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){ + int ofst = aField[i].ofst; + unsigned int val = get4byteInt(aHdr + ofst); + fprintf(p->out, "%-20s %u", aField[i].zName, val); + switch( ofst ){ + case 56: { + if( val==1 ) fprintf(p->out, " (utf8)"); + if( val==2 ) fprintf(p->out, " (utf16le)"); + if( val==3 ) fprintf(p->out, " (utf16be)"); + } + } + fprintf(p->out, "\n"); + } + if( zDb==0 ){ + zSchemaTab = sqlite3_mprintf("main.sqlite_master"); + }else if( strcmp(zDb,"temp")==0 ){ + zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master"); + }else{ + zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb); + } + for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){ + char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab); + int val = db_int(p, zSql); + sqlite3_free(zSql); + fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val); + } + sqlite3_free(zSchemaTab); + return 0; +} + + /* ** If an input line begins with "." then invoke this routine to ** process that line. @@ -2417,7 +2615,7 @@ static void output_reset(ShellState *p){ ** Return 1 on error, 2 to exit, and 0 otherwise. */ static int do_meta_command(char *zLine, ShellState *p){ - int i = 1; + int h = 1; int nArg = 0; int n, c; int rc = 0; @@ -2425,24 +2623,24 @@ static int do_meta_command(char *zLine, ShellState *p){ /* Parse the input line into tokens. */ - while( zLine[i] && nArg<ArraySize(azArg) ){ - while( IsSpace(zLine[i]) ){ i++; } - if( zLine[i]==0 ) break; - if( zLine[i]=='\'' || zLine[i]=='"' ){ - int delim = zLine[i++]; - azArg[nArg++] = &zLine[i]; - while( zLine[i] && zLine[i]!=delim ){ - if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++; - i++; + while( zLine[h] && nArg<ArraySize(azArg) ){ + while( IsSpace(zLine[h]) ){ h++; } + if( zLine[h]==0 ) break; + if( zLine[h]=='\'' || zLine[h]=='"' ){ + int delim = zLine[h++]; + azArg[nArg++] = &zLine[h]; + while( zLine[h] && zLine[h]!=delim ){ + if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++; + h++; } - if( zLine[i]==delim ){ - zLine[i++] = 0; + if( zLine[h]==delim ){ + zLine[h++] = 0; } if( delim=='"' ) resolve_backslashes(azArg[nArg-1]); }else{ - azArg[nArg++] = &zLine[i]; - while( zLine[i] && !IsSpace(zLine[i]) ){ i++; } - if( zLine[i] ) zLine[i++] = 0; + azArg[nArg++] = &zLine[h]; + while( zLine[h] && !IsSpace(zLine[h]) ){ h++; } + if( zLine[h] ) zLine[h++] = 0; resolve_backslashes(azArg[nArg-1]); } } @@ -2517,6 +2715,19 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else + if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){ + if( nArg==2 ){ + if( booleanValue(azArg[1]) ){ + setBinaryMode(p->out); + }else{ + setTextMode(p->out); + } + }else{ + fprintf(stderr, "Usage: .binary on|off\n"); + rc = 1; + } + }else + /* The undocumented ".breakpoint" command causes a call to the no-op ** routine named test_breakpoint(). */ @@ -2552,6 +2763,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else + if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){ + rc = shell_dbinfo_command(p, nArg, azArg); + }else + if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ open_db(p, 0); /* When playing back a "dump", the content might appear in an order @@ -2739,8 +2954,8 @@ static int do_meta_command(char *zLine, ShellState *p){ int nSep; /* Number of bytes in p->colSeparator[] */ char *zSql; /* An SQL statement */ ImportCtx sCtx; /* Reader context */ - char *(*xRead)(ImportCtx*); /* Procedure to read one value */ - int (*xCloser)(FILE*); /* Procedure to close th3 connection */ + char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */ + int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */ if( nArg!=3 ){ fprintf(stderr, "Usage: .import FILE TABLE\n"); @@ -2782,9 +2997,14 @@ static int do_meta_command(char *zLine, ShellState *p){ sCtx.zFile = zFile; sCtx.nLine = 1; if( sCtx.zFile[0]=='|' ){ +#ifdef SQLITE_OMIT_POPEN + fprintf(stderr, "Error: pipes are not supported in this OS\n"); + return 1; +#else sCtx.in = popen(sCtx.zFile+1, "r"); sCtx.zFile = "<pipe>"; xCloser = pclose; +#endif }else{ sCtx.in = fopen(sCtx.zFile, "rb"); xCloser = fclose; @@ -2809,7 +3029,7 @@ static int do_meta_command(char *zLine, ShellState *p){ nByte = strlen30(zSql); rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ - if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){ + if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){ char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable); char cSep = '('; while( xRead(&sCtx) ){ @@ -2829,7 +3049,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_free(zCreate); if( rc ){ fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, - sqlite3_errmsg(db)); + sqlite3_errmsg(p->db)); sqlite3_free(sCtx.z); xCloser(sCtx.in); return 1; @@ -2839,7 +3059,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_free(zSql); if( rc ){ if (pStmt) sqlite3_finalize(pStmt); - fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); + fprintf(stderr,"Error: %s\n", sqlite3_errmsg(p->db)); xCloser(sCtx.in); return 1; } @@ -2847,7 +3067,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_finalize(pStmt); pStmt = 0; if( nCol==0 ) return 0; /* no columns, no error */ - zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 ); + zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 ); if( zSql==0 ){ fprintf(stderr, "Error: out of memory\n"); xCloser(sCtx.in); @@ -2864,13 +3084,13 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); if( rc ){ - fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); + fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); if (pStmt) sqlite3_finalize(pStmt); xCloser(sCtx.in); return 1; } - needCommit = sqlite3_get_autocommit(db); - if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0); + needCommit = sqlite3_get_autocommit(p->db); + if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0); do{ int startLine = sCtx.nLine; for(i=0; i<nCol; i++){ @@ -2891,7 +3111,7 @@ static int do_meta_command(char *zLine, ShellState *p){ fprintf(stderr, "%s:%d: expected %d columns but found %d - " "filling the rest with NULL\n", sCtx.zFile, startLine, nCol, i+1); - i++; + i += 2; while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; } } } @@ -2909,7 +3129,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3_reset(pStmt); if( rc!=SQLITE_OK ){ fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine, - sqlite3_errmsg(db)); + sqlite3_errmsg(p->db)); } } }while( sCtx.cTerm!=EOF ); @@ -2917,10 +3137,11 @@ static int do_meta_command(char *zLine, ShellState *p){ xCloser(sCtx.in); sqlite3_free(sCtx.z); sqlite3_finalize(pStmt); - if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0); + if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0); }else - if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){ + if( c=='i' && (strncmp(azArg[0], "indices", n)==0 + || strncmp(azArg[0], "indexes", n)==0) ){ ShellState data; char *zErrMsg = 0; open_db(p, 0); @@ -2950,7 +3171,7 @@ static int do_meta_command(char *zLine, ShellState *p){ ); zShellStatic = 0; }else{ - fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n"); + fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n"); rc = 1; goto meta_command_exit; } @@ -2966,7 +3187,7 @@ static int do_meta_command(char *zLine, ShellState *p){ #ifdef SQLITE_ENABLE_IOTRACE if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){ - extern void (*sqlite3IoTrace)(const char*, ...); + SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...); if( iotrace && iotrace!=stdout ) fclose(iotrace); iotrace = 0; if( nArg<2 ){ @@ -2986,6 +3207,64 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else #endif + if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){ + static const struct { + const char *zLimitName; /* Name of a limit */ + int limitCode; /* Integer code for that limit */ + } aLimit[] = { + { "length", SQLITE_LIMIT_LENGTH }, + { "sql_length", SQLITE_LIMIT_SQL_LENGTH }, + { "column", SQLITE_LIMIT_COLUMN }, + { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH }, + { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT }, + { "vdbe_op", SQLITE_LIMIT_VDBE_OP }, + { "function_arg", SQLITE_LIMIT_FUNCTION_ARG }, + { "attached", SQLITE_LIMIT_ATTACHED }, + { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH }, + { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER }, + { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH }, + { "worker_threads", SQLITE_LIMIT_WORKER_THREADS }, + }; + int i, n2; + open_db(p, 0); + if( nArg==1 ){ + for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){ + printf("%20s %d\n", aLimit[i].zLimitName, + sqlite3_limit(p->db, aLimit[i].limitCode, -1)); + } + }else if( nArg>3 ){ + fprintf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n"); + rc = 1; + goto meta_command_exit; + }else{ + int iLimit = -1; + n2 = strlen30(azArg[1]); + for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){ + if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){ + if( iLimit<0 ){ + iLimit = i; + }else{ + fprintf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]); + rc = 1; + goto meta_command_exit; + } + } + } + if( iLimit<0 ){ + fprintf(stderr, "unknown limit: \"%s\"\n" + "enter \".limits\" with no arguments for a list.\n", + azArg[1]); + rc = 1; + goto meta_command_exit; + } + if( nArg==3 ){ + sqlite3_limit(p->db, aLimit[iLimit].limitCode, + (int)integerValue(azArg[2])); + } + printf("%20s %d\n", aLimit[iLimit].zLimitName, + sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1)); + } + }else #ifndef SQLITE_OMIT_LOAD_EXTENSION if( c=='l' && strncmp(azArg[0], "load", n)==0 ){ @@ -3106,6 +3385,11 @@ static int do_meta_command(char *zLine, ShellState *p){ } output_reset(p); if( zFile[0]=='|' ){ +#ifdef SQLITE_OMIT_POPEN + fprintf(stderr,"Error: pipes are not supported in this OS\n"); + rc = 1; + p->out = stdout; +#else p->out = popen(zFile + 1, "w"); if( p->out==0 ){ fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1); @@ -3114,6 +3398,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else{ sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } +#endif }else{ p->out = output_file_open(zFile); if( p->out==0 ){ @@ -3313,7 +3598,7 @@ static int do_meta_command(char *zLine, ShellState *p){ #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ extern int sqlite3SelectTrace; - sqlite3SelectTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; + sqlite3SelectTrace = integerValue(azArg[1]); }else #endif @@ -3464,13 +3749,13 @@ static int do_meta_command(char *zLine, ShellState *p){ while( sqlite3_step(pStmt)==SQLITE_ROW ){ if( nRow>=nAlloc ){ char **azNew; - int n = nAlloc*2 + 10; - azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n); + int n2 = nAlloc*2 + 10; + azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2); if( azNew==0 ){ fprintf(stderr, "Error: out of memory\n"); break; } - nAlloc = n; + nAlloc = n2; azResult = azNew; } azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); @@ -3519,17 +3804,19 @@ static int do_meta_command(char *zLine, ShellState *p){ { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, + { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT }, + { "imposter", SQLITE_TESTCTRL_IMPOSTER }, }; int testctrl = -1; - int rc = 0; - int i, n; + int rc2 = 0; + int i, n2; open_db(p, 0); /* convert testctrl text option to value. allow any unique prefix ** of the option name, or a numerical value. */ - n = strlen30(azArg[1]); + n2 = strlen30(azArg[1]); for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){ - if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){ + if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){ if( testctrl<0 ){ testctrl = aCtrl[i].ctrlCode; }else{ @@ -3550,8 +3837,8 @@ static int do_meta_command(char *zLine, ShellState *p){ case SQLITE_TESTCTRL_RESERVE: if( nArg==3 ){ int opt = (int)strtol(azArg[2], 0, 0); - rc = sqlite3_test_control(testctrl, p->db, opt); - fprintf(p->out, "%d (0x%08x)\n", rc, rc); + rc2 = sqlite3_test_control(testctrl, p->db, opt); + fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { fprintf(stderr,"Error: testctrl %s takes a single int option\n", azArg[1]); @@ -3564,8 +3851,8 @@ static int do_meta_command(char *zLine, ShellState *p){ case SQLITE_TESTCTRL_PRNG_RESET: case SQLITE_TESTCTRL_BYTEORDER: if( nArg==2 ){ - rc = sqlite3_test_control(testctrl); - fprintf(p->out, "%d (0x%08x)\n", rc, rc); + rc2 = sqlite3_test_control(testctrl); + fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]); } @@ -3575,8 +3862,8 @@ static int do_meta_command(char *zLine, ShellState *p){ case SQLITE_TESTCTRL_PENDING_BYTE: if( nArg==3 ){ unsigned int opt = (unsigned int)integerValue(azArg[2]); - rc = sqlite3_test_control(testctrl, opt); - fprintf(p->out, "%d (0x%08x)\n", rc, rc); + rc2 = sqlite3_test_control(testctrl, opt); + fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { fprintf(stderr,"Error: testctrl %s takes a single unsigned" " int option\n", azArg[1]); @@ -3585,11 +3872,12 @@ static int do_meta_command(char *zLine, ShellState *p){ /* sqlite3_test_control(int, int) */ case SQLITE_TESTCTRL_ASSERT: - case SQLITE_TESTCTRL_ALWAYS: + case SQLITE_TESTCTRL_ALWAYS: + case SQLITE_TESTCTRL_NEVER_CORRUPT: if( nArg==3 ){ int opt = booleanValue(azArg[2]); - rc = sqlite3_test_control(testctrl, opt); - fprintf(p->out, "%d (0x%08x)\n", rc, rc); + rc2 = sqlite3_test_control(testctrl, opt); + fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { fprintf(stderr,"Error: testctrl %s takes a single int option\n", azArg[1]); @@ -3601,8 +3889,8 @@ static int do_meta_command(char *zLine, ShellState *p){ case SQLITE_TESTCTRL_ISKEYWORD: if( nArg==3 ){ const char *opt = azArg[2]; - rc = sqlite3_test_control(testctrl, opt); - fprintf(p->out, "%d (0x%08x)\n", rc, rc); + rc2 = sqlite3_test_control(testctrl, opt); + fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { fprintf(stderr,"Error: testctrl %s takes a single char * option\n", azArg[1]); @@ -3610,6 +3898,18 @@ static int do_meta_command(char *zLine, ShellState *p){ break; #endif + case SQLITE_TESTCTRL_IMPOSTER: + if( nArg==5 ){ + rc2 = sqlite3_test_control(testctrl, p->db, + azArg[2], + integerValue(azArg[3]), + integerValue(azArg[4])); + fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); + }else{ + fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n"); + } + break; + case SQLITE_TESTCTRL_BITVEC_TEST: case SQLITE_TESTCTRL_FAULT_INSTALL: case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: @@ -3642,12 +3942,12 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){ open_db(p, 0); - output_file_close(p->traceOut); if( nArg!=2 ){ fprintf(stderr, "Usage: .trace FILE|off\n"); rc = 1; goto meta_command_exit; } + output_file_close(p->traceOut); p->traceOut = output_file_open(azArg[1]); #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) if( p->traceOut==0 ){ @@ -3912,6 +4212,7 @@ static int process_input(ShellState *p, FILE *in){ && sqlite3_complete(zSql) ){ p->cnt = 0; open_db(p, 0); + if( p->backslashOn ) resolve_backslashes(zSql); BEGIN_TIMER; rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); END_TIMER; @@ -4023,7 +4324,7 @@ static char *find_home_dir(void){ ** ** Returns the number of errors. */ -static int process_sqliterc( +static void process_sqliterc( ShellState *p, /* Configuration data */ const char *sqliterc_override /* Name of config file. NULL to use default */ ){ @@ -4031,15 +4332,13 @@ static int process_sqliterc( const char *sqliterc = sqliterc_override; char *zBuf = 0; FILE *in = NULL; - int rc = 0; if (sqliterc == NULL) { home_dir = find_home_dir(); if( home_dir==0 ){ -#if !defined(__RTP__) && !defined(_WRS_KERNEL) - fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0); -#endif - return 1; + fprintf(stderr, "-- warning: cannot find home directory;" + " cannot read ~/.sqliterc\n"); + return; } sqlite3_initialize(); zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); @@ -4050,11 +4349,10 @@ static int process_sqliterc( if( stdin_is_interactive ){ fprintf(stderr,"-- Loading resources from %s\n",sqliterc); } - rc = process_input(p,in); + process_input(p,in); fclose(in); } sqlite3_free(zBuf); - return rc; } /* @@ -4158,7 +4456,7 @@ static char *cmdline_option_value(int argc, char **argv, int i){ return argv[i]; } -int main(int argc, char **argv){ +int SQLITE_CDECL main(int argc, char **argv){ char *zErrMsg = 0; ShellState data; const char *zInitFile = 0; @@ -4176,6 +4474,8 @@ int main(int argc, char **argv){ exit(1); } #endif + setBinaryMode(stdin); + setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ Argv0 = argv[0]; main_init(&data); stdin_is_interactive = isatty(0); @@ -4328,10 +4628,7 @@ int main(int argc, char **argv){ ** is given on the command line, look for a file named ~/.sqliterc and ** try to process it. */ - rc = process_sqliterc(&data,zInitFile); - if( rc>0 ){ - return rc; - } + process_sqliterc(&data,zInitFile); /* Make a second pass through the command-line argument and set ** options. This second pass is delayed until after the initialization @@ -4382,6 +4679,13 @@ int main(int argc, char **argv){ data.statsOn = 1; }else if( strcmp(z,"-scanstats")==0 ){ data.scanstatsOn = 1; + }else if( strcmp(z,"-backslash")==0 ){ + /* Undocumented command-line option: -backslash + ** Causes C-style backslash escapes to be evaluated in SQL statements + ** prior to sending the SQL into SQLite. Useful for injecting + ** crazy bytes in the middle of SQL statements for testing and debugging. + */ + data.backslashOn = 1; }else if( strcmp(z,"-bail")==0 ){ bail_on_error = 1; }else if( strcmp(z,"-version")==0 ){ @@ -4488,13 +4792,11 @@ int main(int argc, char **argv){ sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); } } -#if HAVE_READLINE - if( zHistory ) read_history(zHistory); -#endif + if( zHistory ) shell_read_history(zHistory); rc = process_input(&data, 0); if( zHistory ){ - stifle_history(100); - write_history(zHistory); + shell_stifle_history(100); + shell_write_history(zHistory); free(zHistory); } }else{ diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index 71f6c1036dfbc5436a90fc45c10c7993b261c328..06f6d154f16585c821f3dc33e0e7adeaeda8632e 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.8.8.2. By combining all the individual C code files into this +** version 3.8.10.2. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -22,9 +22,6 @@ #ifndef SQLITE_PRIVATE # define SQLITE_PRIVATE static #endif -#ifndef SQLITE_API -# define SQLITE_API -#endif /************** Begin file sqliteInt.h ***************************************/ /* ** 2001 September 15 @@ -73,6 +70,7 @@ #pragma warning(disable : 4055) #pragma warning(disable : 4100) #pragma warning(disable : 4127) +#pragma warning(disable : 4130) #pragma warning(disable : 4152) #pragma warning(disable : 4189) #pragma warning(disable : 4206) @@ -90,6 +88,44 @@ /************** End of msvc.h ************************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ +/* +** Special setup for VxWorks +*/ +/************** Include vxworks.h in the middle of sqliteInt.h ***************/ +/************** Begin file vxworks.h *****************************************/ +/* +** 2015-03-02 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code that is specific to Wind River's VxWorks +*/ +#if defined(__RTP__) || defined(_WRS_KERNEL) +/* This is VxWorks. Set up things specially for that OS +*/ +#include <vxWorks.h> +#include <pthread.h> /* amalgamator: dontcache */ +#define OS_VXWORKS 1 +#define SQLITE_OS_OTHER 0 +#define SQLITE_HOMEGROWN_RECURSIVE_MUTEX 1 +#define SQLITE_OMIT_LOAD_EXTENSION 1 +#define SQLITE_ENABLE_LOCKING_STYLE 0 +#define HAVE_UTIME 1 +#else +/* This is not VxWorks. */ +#define OS_VXWORKS 0 +#endif /* defined(_WRS_KERNEL) */ + +/************** End of vxworks.h *********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ + /* ** These #defines should enable >2GB file support on POSIX if the ** underlying operating system supports it. If the OS lacks @@ -214,16 +250,20 @@ extern "C" { /* -** Add the ability to override 'extern' +** Provide the ability to override linkage features of the interface. */ #ifndef SQLITE_EXTERN # define SQLITE_EXTERN extern #endif - #ifndef SQLITE_API # define SQLITE_API #endif - +#ifndef SQLITE_CDECL +# define SQLITE_CDECL +#endif +#ifndef SQLITE_STDCALL +# define SQLITE_STDCALL +#endif /* ** These no-op macros are used in front of interfaces to mark those @@ -278,9 +318,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.8.8.2" -#define SQLITE_VERSION_NUMBER 3008008 -#define SQLITE_SOURCE_ID "2015-01-30 14:30:45 7757fc721220e136620a89c9d28247f28bbbc098" +#define SQLITE_VERSION "3.8.10.2" +#define SQLITE_VERSION_NUMBER 3008010 +#define SQLITE_SOURCE_ID "2015-05-20 18:17:19 2ef4f3a5b1d1d0c4338f8243d40a2452cc1f7fe4" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -313,9 +353,9 @@ extern "C" { ** See also: [sqlite_version()] and [sqlite_source_id()]. */ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; -SQLITE_API const char *sqlite3_libversion(void); -SQLITE_API const char *sqlite3_sourceid(void); -SQLITE_API int sqlite3_libversion_number(void); +SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void); +SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void); +SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void); /* ** CAPI3REF: Run-Time Library Compilation Options Diagnostics @@ -340,8 +380,8 @@ SQLITE_API int sqlite3_libversion_number(void); ** [sqlite_compileoption_get()] and the [compile_options pragma]. */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS -SQLITE_API int sqlite3_compileoption_used(const char *zOptName); -SQLITE_API const char *sqlite3_compileoption_get(int N); +SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName); +SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N); #endif /* @@ -380,7 +420,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N); ** ** See the [threading mode] documentation for additional information. */ -SQLITE_API int sqlite3_threadsafe(void); +SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void); /* ** CAPI3REF: Database Connection Handle @@ -437,6 +477,7 @@ typedef sqlite_uint64 sqlite3_uint64; /* ** CAPI3REF: Closing A Database Connection +** DESTRUCTOR: sqlite3 ** ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors ** for the [sqlite3] object. @@ -476,8 +517,8 @@ typedef sqlite_uint64 sqlite3_uint64; ** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer ** argument is a harmless no-op. */ -SQLITE_API int sqlite3_close(sqlite3*); -SQLITE_API int sqlite3_close_v2(sqlite3*); +SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*); +SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*); /* ** The type for a callback function. @@ -488,6 +529,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); /* ** CAPI3REF: One-Step Query Execution Interface +** METHOD: sqlite3 ** ** The sqlite3_exec() interface is a convenience wrapper around ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], @@ -547,7 +589,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. ** </ul> */ -SQLITE_API int sqlite3_exec( +SQLITE_API int SQLITE_STDCALL sqlite3_exec( sqlite3*, /* An open database */ const char *sql, /* SQL to be evaluated */ int (*callback)(void*,int,char**,char**), /* Callback function */ @@ -927,14 +969,16 @@ struct sqlite3_io_methods { ** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()] ** interface. ** +** <ul> +** <li>[[SQLITE_FCNTL_LOCKSTATE]] ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This ** opcode causes the xFileControl method to write the current state of ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) ** into an integer that the pArg argument points to. This capability -** is used during testing and only needs to be supported when SQLITE_TEST -** is defined. -** <ul> +** is used during testing and is only available when the SQLITE_TEST +** compile-time option is used. +** ** <li>[[SQLITE_FCNTL_SIZE_HINT]] ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS ** layer a hint of how large the database file will grow to be during the @@ -1059,7 +1103,9 @@ struct sqlite3_io_methods { ** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA] ** file control returns [SQLITE_OK], then the parser assumes that the ** VFS has handled the PRAGMA itself and the parser generates a no-op -** prepared statement. ^If the [SQLITE_FCNTL_PRAGMA] file control returns +** prepared statement if result string is NULL, or that returns a copy +** of the result string if the string is non-NULL. +** ^If the [SQLITE_FCNTL_PRAGMA] file control returns ** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means ** that the VFS encountered an error while handling the [PRAGMA] and the ** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] @@ -1117,12 +1163,19 @@ struct sqlite3_io_methods { ** pointed to by the pArg argument. This capability is used during testing ** and only needs to be supported when SQLITE_TEST is defined. ** +** <li>[[SQLITE_FCNTL_WAL_BLOCK]] +** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might +** be advantageous to block on the next WAL lock if the lock is not immediately +** available. The WAL subsystem issues this signal during rare +** circumstances in order to fix a problem with priority inversion. +** Applications should <em>not</em> use this file-control. +** ** </ul> */ #define SQLITE_FCNTL_LOCKSTATE 1 -#define SQLITE_GET_LOCKPROXYFILE 2 -#define SQLITE_SET_LOCKPROXYFILE 3 -#define SQLITE_LAST_ERRNO 4 +#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 +#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 +#define SQLITE_FCNTL_LAST_ERRNO 4 #define SQLITE_FCNTL_SIZE_HINT 5 #define SQLITE_FCNTL_CHUNK_SIZE 6 #define SQLITE_FCNTL_FILE_POINTER 7 @@ -1141,6 +1194,13 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_SYNC 21 #define SQLITE_FCNTL_COMMIT_PHASETWO 22 #define SQLITE_FCNTL_WIN32_SET_HANDLE 23 +#define SQLITE_FCNTL_WAL_BLOCK 24 + +/* deprecated names */ +#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE +#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE +#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO + /* ** CAPI3REF: Mutex Handle @@ -1489,10 +1549,10 @@ struct sqlite3_vfs { ** must return [SQLITE_OK] on success and some other [error code] upon ** failure. */ -SQLITE_API int sqlite3_initialize(void); -SQLITE_API int sqlite3_shutdown(void); -SQLITE_API int sqlite3_os_init(void); -SQLITE_API int sqlite3_os_end(void); +SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void); +SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void); +SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void); +SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void); /* ** CAPI3REF: Configuring The SQLite Library @@ -1523,10 +1583,11 @@ SQLITE_API int sqlite3_os_end(void); ** ^If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. */ -SQLITE_API int sqlite3_config(int, ...); +SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...); /* ** CAPI3REF: Configure database connections +** METHOD: sqlite3 ** ** The sqlite3_db_config() interface is used to make configuration ** changes to a [database connection]. The interface is similar to @@ -1541,7 +1602,7 @@ SQLITE_API int sqlite3_config(int, ...); ** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if ** the call is considered successful. */ -SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); +SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...); /* ** CAPI3REF: Memory Allocation Routines @@ -1701,7 +1762,7 @@ struct sqlite3_mem_methods { ** <li> [sqlite3_memory_used()] ** <li> [sqlite3_memory_highwater()] ** <li> [sqlite3_soft_heap_limit64()] -** <li> [sqlite3_status()] +** <li> [sqlite3_status64()] ** </ul>)^ ** ^Memory allocation statistics are enabled by default unless SQLite is ** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory @@ -1912,7 +1973,6 @@ struct sqlite3_mem_methods { ** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro ** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value ** that specifies the maximum size of the created heap. -** </dl> ** ** [[SQLITE_CONFIG_PCACHE_HDRSZ]] ** <dt>SQLITE_CONFIG_PCACHE_HDRSZ @@ -2025,15 +2085,17 @@ struct sqlite3_mem_methods { /* ** CAPI3REF: Enable Or Disable Extended Result Codes +** METHOD: sqlite3 ** ** ^The sqlite3_extended_result_codes() routine enables or disables the ** [extended result codes] feature of SQLite. ^The extended result ** codes are disabled by default for historical compatibility. */ -SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); +SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff); /* ** CAPI3REF: Last Insert Rowid +** METHOD: sqlite3 ** ** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables) ** has a unique 64-bit signed @@ -2081,10 +2143,11 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); ** unpredictable and might not equal either the old or the new ** last insert [rowid]. */ -SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*); /* ** CAPI3REF: Count The Number Of Rows Modified +** METHOD: sqlite3 ** ** ^This function returns the number of rows modified, inserted or ** deleted by the most recently completed INSERT, UPDATE or DELETE @@ -2133,10 +2196,11 @@ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); ** while [sqlite3_changes()] is running then the value returned ** is unpredictable and not meaningful. */ -SQLITE_API int sqlite3_changes(sqlite3*); +SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*); /* ** CAPI3REF: Total Number Of Rows Modified +** METHOD: sqlite3 ** ** ^This function returns the total number of rows inserted, modified or ** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed @@ -2156,10 +2220,11 @@ SQLITE_API int sqlite3_changes(sqlite3*); ** while [sqlite3_total_changes()] is running then the value ** returned is unpredictable and not meaningful. */ -SQLITE_API int sqlite3_total_changes(sqlite3*); +SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*); /* ** CAPI3REF: Interrupt A Long-Running Query +** METHOD: sqlite3 ** ** ^This function causes any pending database operation to abort and ** return at its earliest opportunity. This routine is typically @@ -2195,7 +2260,7 @@ SQLITE_API int sqlite3_total_changes(sqlite3*); ** If the database connection closes while [sqlite3_interrupt()] ** is running then bad things will likely happen. */ -SQLITE_API void sqlite3_interrupt(sqlite3*); +SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*); /* ** CAPI3REF: Determine If An SQL Statement Is Complete @@ -2230,12 +2295,13 @@ SQLITE_API void sqlite3_interrupt(sqlite3*); ** The input to [sqlite3_complete16()] must be a zero-terminated ** UTF-16 string in native byte order. */ -SQLITE_API int sqlite3_complete(const char *sql); -SQLITE_API int sqlite3_complete16(const void *sql); +SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql); +SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql); /* ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors ** KEYWORDS: {busy-handler callback} {busy handler} +** METHOD: sqlite3 ** ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X ** that might be invoked with argument P whenever @@ -2291,10 +2357,11 @@ SQLITE_API int sqlite3_complete16(const void *sql); ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ -SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); +SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); /* ** CAPI3REF: Set A Busy Timeout +** METHOD: sqlite3 ** ** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps ** for a specified amount of time when a table is locked. ^The handler @@ -2313,10 +2380,11 @@ SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); ** ** See also: [PRAGMA busy_timeout] */ -SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); +SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms); /* ** CAPI3REF: Convenience Routines For Running Queries +** METHOD: sqlite3 ** ** This is a legacy interface that is preserved for backwards compatibility. ** Use of this interface is not recommended. @@ -2387,7 +2455,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); ** reflected in subsequent calls to [sqlite3_errcode()] or ** [sqlite3_errmsg()]. */ -SQLITE_API int sqlite3_get_table( +SQLITE_API int SQLITE_STDCALL sqlite3_get_table( sqlite3 *db, /* An open database */ const char *zSql, /* SQL to be evaluated */ char ***pazResult, /* Results of the query */ @@ -2395,13 +2463,17 @@ SQLITE_API int sqlite3_get_table( int *pnColumn, /* Number of result columns written here */ char **pzErrmsg /* Error msg written here */ ); -SQLITE_API void sqlite3_free_table(char **result); +SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result); /* ** CAPI3REF: Formatted String Printing Functions ** ** These routines are work-alikes of the "printf()" family of functions ** from the standard C library. +** These routines understand most of the common K&R formatting options, +** plus some additional non-standard formats, detailed below. +** Note that some of the more obscure formatting options from recent +** C-library standards are omitted from this implementation. ** ** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their ** results into memory obtained from [sqlite3_malloc()]. @@ -2434,7 +2506,7 @@ SQLITE_API void sqlite3_free_table(char **result); ** These routines all implement some additional formatting ** options that are useful for constructing SQL statements. ** All of the usual printf() formatting options apply. In addition, there -** is are "%q", "%Q", and "%z" options. +** is are "%q", "%Q", "%w" and "%z" options. ** ** ^(The %q option works like %s in that it substitutes a nul-terminated ** string from the argument list. But %q also doubles every '\'' character. @@ -2487,14 +2559,20 @@ SQLITE_API void sqlite3_free_table(char **result); ** The code above will render a correct SQL statement in the zSQL ** variable even if the zText variable is a NULL pointer. ** +** ^(The "%w" formatting option is like "%q" except that it expects to +** be contained within double-quotes instead of single quotes, and it +** escapes the double-quote character instead of the single-quote +** character.)^ The "%w" formatting option is intended for safely inserting +** table and column names into a constructed SQL statement. +** ** ^(The "%z" formatting option works like "%s" but with the ** addition that after the string has been read and copied into ** the result, [sqlite3_free()] is called on the input string.)^ */ -SQLITE_API char *sqlite3_mprintf(const char*,...); -SQLITE_API char *sqlite3_vmprintf(const char*, va_list); -SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...); -SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list); +SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...); +SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list); +SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...); +SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list); /* ** CAPI3REF: Memory Allocation Subsystem @@ -2584,12 +2662,12 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list); ** a block of memory after it has been released using ** [sqlite3_free()] or [sqlite3_realloc()]. */ -SQLITE_API void *sqlite3_malloc(int); -SQLITE_API void *sqlite3_malloc64(sqlite3_uint64); -SQLITE_API void *sqlite3_realloc(void*, int); -SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64); -SQLITE_API void sqlite3_free(void*); -SQLITE_API sqlite3_uint64 sqlite3_msize(void*); +SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int); +SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64); +SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int); +SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64); +SQLITE_API void SQLITE_STDCALL sqlite3_free(void*); +SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*); /* ** CAPI3REF: Memory Allocator Statistics @@ -2614,8 +2692,8 @@ SQLITE_API sqlite3_uint64 sqlite3_msize(void*); ** by [sqlite3_memory_highwater(1)] is the high-water mark ** prior to the reset. */ -SQLITE_API sqlite3_int64 sqlite3_memory_used(void); -SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag); /* ** CAPI3REF: Pseudo-Random Number Generator @@ -2638,10 +2716,11 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); ** internally and without recourse to the [sqlite3_vfs] xRandomness ** method. */ -SQLITE_API void sqlite3_randomness(int N, void *P); +SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P); /* ** CAPI3REF: Compile-Time Authorization Callbacks +** METHOD: sqlite3 ** ** ^This routine registers an authorizer callback with a particular ** [database connection], supplied in the first argument. @@ -2720,7 +2799,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** as stated in the previous paragraph, sqlite3_step() invokes ** sqlite3_prepare_v2() to reprepare a statement after a schema change. */ -SQLITE_API int sqlite3_set_authorizer( +SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer( sqlite3*, int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), void *pUserData @@ -2798,6 +2877,7 @@ SQLITE_API int sqlite3_set_authorizer( /* ** CAPI3REF: Tracing And Profiling Functions +** METHOD: sqlite3 ** ** These routines register callback functions that can be used for ** tracing and profiling the execution of SQL statements. @@ -2824,12 +2904,13 @@ SQLITE_API int sqlite3_set_authorizer( ** sqlite3_profile() function is considered experimental and is ** subject to change in future versions of SQLite. */ -SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); -SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, +SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_profile(sqlite3*, void(*xProfile)(void*,const char*,sqlite3_uint64), void*); /* ** CAPI3REF: Query Progress Callbacks +** METHOD: sqlite3 ** ** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback ** function X to be invoked periodically during long running calls to @@ -2859,10 +2940,11 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, ** database connections for the meaning of "modify" in this paragraph. ** */ -SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); +SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection +** CONSTRUCTOR: sqlite3 ** ** ^These routines open an SQLite database file as specified by the ** filename argument. ^The filename argument is interpreted as UTF-8 for @@ -3087,15 +3169,15 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** ** See also: [sqlite3_temp_directory] */ -SQLITE_API int sqlite3_open( +SQLITE_API int SQLITE_STDCALL sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */ ); -SQLITE_API int sqlite3_open16( +SQLITE_API int SQLITE_STDCALL sqlite3_open16( const void *filename, /* Database filename (UTF-16) */ sqlite3 **ppDb /* OUT: SQLite db handle */ ); -SQLITE_API int sqlite3_open_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_open_v2( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb, /* OUT: SQLite db handle */ int flags, /* Flags */ @@ -3141,19 +3223,22 @@ SQLITE_API int sqlite3_open_v2( ** VFS method, then the behavior of this routine is undefined and probably ** undesirable. */ -SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); -SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); -SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); +SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam); +SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const char*, sqlite3_int64); /* ** CAPI3REF: Error Codes And Messages -** -** ^The sqlite3_errcode() interface returns the numeric [result code] or -** [extended result code] for the most recent failed sqlite3_* API call -** associated with a [database connection]. If a prior API call failed -** but the most recent API call succeeded, the return value from -** sqlite3_errcode() is undefined. ^The sqlite3_extended_errcode() +** METHOD: sqlite3 +** +** ^If the most recent sqlite3_* API call associated with +** [database connection] D failed, then the sqlite3_errcode(D) interface +** returns the numeric [result code] or [extended result code] for that +** API call. +** If the most recent API call was successful, +** then the return value from sqlite3_errcode() is undefined. +** ^The sqlite3_extended_errcode() ** interface is the same except that it always returns the ** [extended result code] even when extended result codes are ** disabled. @@ -3184,40 +3269,41 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int ** was invoked incorrectly by the application. In that case, the ** error code and message may or may not be set. */ -SQLITE_API int sqlite3_errcode(sqlite3 *db); -SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); -SQLITE_API const char *sqlite3_errmsg(sqlite3*); -SQLITE_API const void *sqlite3_errmsg16(sqlite3*); -SQLITE_API const char *sqlite3_errstr(int); +SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db); +SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db); +SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*); +SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int); /* -** CAPI3REF: SQL Statement Object +** CAPI3REF: Prepared Statement Object ** KEYWORDS: {prepared statement} {prepared statements} ** -** An instance of this object represents a single SQL statement. -** This object is variously known as a "prepared statement" or a -** "compiled SQL statement" or simply as a "statement". +** An instance of this object represents a single SQL statement that +** has been compiled into binary form and is ready to be evaluated. +** +** Think of each SQL statement as a separate computer program. The +** original SQL text is source code. A prepared statement object +** is the compiled object code. All SQL must be converted into a +** prepared statement before it can be run. ** -** The life of a statement object goes something like this: +** The life-cycle of a prepared statement object usually goes like this: ** ** <ol> -** <li> Create the object using [sqlite3_prepare_v2()] or a related -** function. -** <li> Bind values to [host parameters] using the sqlite3_bind_*() +** <li> Create the prepared statement object using [sqlite3_prepare_v2()]. +** <li> Bind values to [parameters] using the sqlite3_bind_*() ** interfaces. ** <li> Run the SQL by calling [sqlite3_step()] one or more times. -** <li> Reset the statement using [sqlite3_reset()] then go back +** <li> Reset the prepared statement using [sqlite3_reset()] then go back ** to step 2. Do this zero or more times. ** <li> Destroy the object using [sqlite3_finalize()]. ** </ol> -** -** Refer to documentation on individual methods above for additional -** information. */ typedef struct sqlite3_stmt sqlite3_stmt; /* ** CAPI3REF: Run-time Limits +** METHOD: sqlite3 ** ** ^(This interface allows the size of various constructs to be limited ** on a connection by connection basis. The first parameter is the @@ -3255,7 +3341,7 @@ typedef struct sqlite3_stmt sqlite3_stmt; ** ** New run-time limit categories may be added in future releases. */ -SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); +SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal); /* ** CAPI3REF: Run-Time Limit Categories @@ -3329,6 +3415,8 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); /* ** CAPI3REF: Compiling An SQL Statement ** KEYWORDS: {SQL statement compiler} +** METHOD: sqlite3 +** CONSTRUCTOR: sqlite3_stmt ** ** To execute an SQL query, it must first be compiled into a byte-code ** program using one of these routines. @@ -3342,16 +3430,14 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2() ** use UTF-16. ** -** ^If the nByte argument is less than zero, then zSql is read up to the -** first zero terminator. ^If nByte is non-negative, then it is the maximum -** number of bytes read from zSql. ^When nByte is non-negative, the -** zSql string ends at either the first '\000' or '\u0000' character or -** the nByte-th byte, whichever comes first. If the caller knows -** that the supplied string is nul-terminated, then there is a small -** performance advantage to be gained by passing an nByte parameter that -** is equal to the number of bytes in the input string <i>including</i> -** the nul-terminator bytes as this saves SQLite from having to -** make a copy of the input string. +** ^If the nByte argument is negative, then zSql is read up to the +** first zero terminator. ^If nByte is positive, then it is the +** number of bytes read from zSql. ^If nByte is zero, then no prepared +** statement is generated. +** If the caller knows that the supplied string is nul-terminated, then +** there is a small performance advantage to passing an nByte parameter that +** is the number of bytes in the input string <i>including</i> +** the nul-terminator. ** ** ^If pzTail is not NULL then *pzTail is made to point to the first byte ** past the end of the first SQL statement in zSql. These routines only @@ -3407,28 +3493,28 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** </li> ** </ol> */ -SQLITE_API int sqlite3_prepare( +SQLITE_API int SQLITE_STDCALL sqlite3_prepare( sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); -SQLITE_API int sqlite3_prepare_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2( sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); -SQLITE_API int sqlite3_prepare16( +SQLITE_API int SQLITE_STDCALL sqlite3_prepare16( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); -SQLITE_API int sqlite3_prepare16_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ @@ -3438,15 +3524,17 @@ SQLITE_API int sqlite3_prepare16_v2( /* ** CAPI3REF: Retrieving Statement SQL +** METHOD: sqlite3_stmt ** ** ^This interface can be used to retrieve a saved copy of the original ** SQL text used to create a [prepared statement] if that statement was ** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. */ -SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); +SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt); /* ** CAPI3REF: Determine If An SQL Statement Writes The Database +** METHOD: sqlite3_stmt ** ** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if ** and only if the [prepared statement] X makes no direct changes to @@ -3474,10 +3562,11 @@ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); ** change the configuration of a database connection, they do not make ** changes to the content of the database files on disk. */ -SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt); /* ** CAPI3REF: Determine If A Prepared Statement Has Been Reset +** METHOD: sqlite3_stmt ** ** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the ** [prepared statement] S has been stepped at least once using @@ -3493,7 +3582,7 @@ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); ** for example, in diagnostic routines to search for prepared ** statements that are holding a transaction open. */ -SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*); /* ** CAPI3REF: Dynamically Typed Value Object @@ -3552,6 +3641,7 @@ typedef struct sqlite3_context sqlite3_context; ** CAPI3REF: Binding Values To Prepared Statements ** KEYWORDS: {host parameter} {host parameters} {host parameter name} ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} +** METHOD: sqlite3_stmt ** ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, ** literals may be replaced by a [parameter] that matches one of following @@ -3654,22 +3744,23 @@ typedef struct sqlite3_context sqlite3_context; ** See also: [sqlite3_bind_parameter_count()], ** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. */ -SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); -SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, +SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, void(*)(void*)); -SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double); -SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int); -SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); -SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int); -SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); -SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); -SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, +SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, void(*)(void*), unsigned char encoding); -SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); -SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); /* ** CAPI3REF: Number Of SQL Parameters +** METHOD: sqlite3_stmt ** ** ^This routine can be used to find the number of [SQL parameters] ** in a [prepared statement]. SQL parameters are tokens of the @@ -3686,10 +3777,11 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); ** [sqlite3_bind_parameter_name()], and ** [sqlite3_bind_parameter_index()]. */ -SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*); /* ** CAPI3REF: Name Of A Host Parameter +** METHOD: sqlite3_stmt ** ** ^The sqlite3_bind_parameter_name(P,N) interface returns ** the name of the N-th [SQL parameter] in the [prepared statement] P. @@ -3713,10 +3805,11 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); ** [sqlite3_bind_parameter_count()], and ** [sqlite3_bind_parameter_index()]. */ -SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); +SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int); /* ** CAPI3REF: Index Of A Parameter With A Given Name +** METHOD: sqlite3_stmt ** ** ^Return the index of an SQL parameter given its name. ^The ** index value returned is suitable for use as the second @@ -3729,19 +3822,21 @@ SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); ** [sqlite3_bind_parameter_count()], and ** [sqlite3_bind_parameter_index()]. */ -SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); /* ** CAPI3REF: Reset All Bindings On A Prepared Statement +** METHOD: sqlite3_stmt ** ** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset ** the [sqlite3_bind_blob | bindings] on a [prepared statement]. ** ^Use this routine to reset all host parameters to NULL. */ -SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); +SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*); /* ** CAPI3REF: Number Of Columns In A Result Set +** METHOD: sqlite3_stmt ** ** ^Return the number of columns in the result set returned by the ** [prepared statement]. ^This routine returns 0 if pStmt is an SQL @@ -3749,10 +3844,11 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); ** ** See also: [sqlite3_data_count()] */ -SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); +SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt); /* ** CAPI3REF: Column Names In A Result Set +** METHOD: sqlite3_stmt ** ** ^These routines return the name assigned to a particular column ** in the result set of a [SELECT] statement. ^The sqlite3_column_name() @@ -3777,11 +3873,12 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); ** then the name of the column is unspecified and may change from ** one release of SQLite to the next. */ -SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N); -SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N); /* ** CAPI3REF: Source Of Data In A Query Result +** METHOD: sqlite3_stmt ** ** ^These routines provide a means to determine the database, table, and ** table column that is the origin of a particular result column in @@ -3825,15 +3922,16 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); ** for the same [prepared statement] and result column ** at the same time then the results are undefined. */ -SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int); -SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int); -SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int); -SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int); -SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int); -SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int); +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int); +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int); /* ** CAPI3REF: Declared Datatype Of A Query Result +** METHOD: sqlite3_stmt ** ** ^(The first parameter is a [prepared statement]. ** If this statement is a [SELECT] statement and the Nth column of the @@ -3861,11 +3959,12 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); ** is associated with individual values, not with the containers ** used to hold those values. */ -SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int); -SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int); /* ** CAPI3REF: Evaluate An SQL Statement +** METHOD: sqlite3_stmt ** ** After a [prepared statement] has been prepared using either ** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy @@ -3941,10 +4040,11 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** then the more specific [error codes] are returned directly ** by sqlite3_step(). The use of the "v2" interface is recommended. */ -SQLITE_API int sqlite3_step(sqlite3_stmt*); +SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*); /* ** CAPI3REF: Number of columns in a result set +** METHOD: sqlite3_stmt ** ** ^The sqlite3_data_count(P) interface returns the number of columns in the ** current row of the result set of [prepared statement] P. @@ -3961,7 +4061,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt*); ** ** See also: [sqlite3_column_count()] */ -SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); +SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt); /* ** CAPI3REF: Fundamental Datatypes @@ -3998,6 +4098,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); /* ** CAPI3REF: Result Values From A Query ** KEYWORDS: {column access functions} +** METHOD: sqlite3_stmt ** ** These routines form the "result set" interface. ** @@ -4157,19 +4258,20 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** pointer. Subsequent calls to [sqlite3_errcode()] will return ** [SQLITE_NOMEM].)^ */ -SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); -SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); -SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); -SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); -SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); -SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol); +SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol); /* ** CAPI3REF: Destroy A Prepared Statement Object +** DESTRUCTOR: sqlite3_stmt ** ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. ** ^If the most recent evaluation of the statement encountered no errors @@ -4193,10 +4295,11 @@ SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); ** statement after it has been finalized can result in undefined and ** undesirable behavior such as segfaults and heap corruption. */ -SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); +SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt); /* ** CAPI3REF: Reset A Prepared Statement Object +** METHOD: sqlite3_stmt ** ** The sqlite3_reset() function is called to reset a [prepared statement] ** object back to its initial state, ready to be re-executed. @@ -4219,13 +4322,14 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); ** ^The [sqlite3_reset(S)] interface does not change the values ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. */ -SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); +SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt); /* ** CAPI3REF: Create Or Redefine SQL Functions ** KEYWORDS: {function creation routines} ** KEYWORDS: {application-defined SQL function} ** KEYWORDS: {application-defined SQL functions} +** METHOD: sqlite3 ** ** ^These functions (collectively known as "function creation routines") ** are used to add SQL functions or aggregates or to redefine the behavior @@ -4318,7 +4422,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** close the database connection nor finalize or reset the prepared ** statement in which the function is running. */ -SQLITE_API int sqlite3_create_function( +SQLITE_API int SQLITE_STDCALL sqlite3_create_function( sqlite3 *db, const char *zFunctionName, int nArg, @@ -4328,7 +4432,7 @@ SQLITE_API int sqlite3_create_function( void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); -SQLITE_API int sqlite3_create_function16( +SQLITE_API int SQLITE_STDCALL sqlite3_create_function16( sqlite3 *db, const void *zFunctionName, int nArg, @@ -4338,7 +4442,7 @@ SQLITE_API int sqlite3_create_function16( void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); -SQLITE_API int sqlite3_create_function_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2( sqlite3 *db, const char *zFunctionName, int nArg, @@ -4380,21 +4484,22 @@ SQLITE_API int sqlite3_create_function_v2( ** These functions are [deprecated]. In order to maintain ** backwards compatibility with older code, these functions continue ** to be supported. However, new applications should avoid -** the use of these functions. To help encourage people to avoid -** using these functions, we are not going to tell you what they do. +** the use of these functions. To encourage programmers to avoid +** these functions, we will not explain what they do. */ #ifndef SQLITE_OMIT_DEPRECATED -SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*); -SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); -SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); -SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void); -SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); -SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void); +SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), void*,sqlite3_int64); #endif /* ** CAPI3REF: Obtaining SQL Function Parameter Values +** METHOD: sqlite3_value ** ** The C-language implementation of SQL functions and aggregates uses ** this set of interface routines to access the parameter values on @@ -4438,21 +4543,22 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 ** These routines must be called from the same thread as ** the SQL function that supplied the [sqlite3_value*] parameters. */ -SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); -SQLITE_API int sqlite3_value_bytes(sqlite3_value*); -SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); -SQLITE_API double sqlite3_value_double(sqlite3_value*); -SQLITE_API int sqlite3_value_int(sqlite3_value*); -SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); -SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); -SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); -SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); -SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); -SQLITE_API int sqlite3_value_type(sqlite3_value*); -SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*); +SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*); +SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*); /* ** CAPI3REF: Obtain Aggregate Function Context +** METHOD: sqlite3_context ** ** Implementations of aggregate SQL functions use this ** routine to allocate memory for storing their state. @@ -4493,10 +4599,11 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); ** This routine must be called from the same thread in which ** the aggregate SQL function is running. */ -SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); +SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes); /* ** CAPI3REF: User Data For Functions +** METHOD: sqlite3_context ** ** ^The sqlite3_user_data() interface returns a copy of ** the pointer that was the pUserData parameter (the 5th parameter) @@ -4507,10 +4614,11 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); ** This routine must be called from the same thread in which ** the application-defined function is running. */ -SQLITE_API void *sqlite3_user_data(sqlite3_context*); +SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*); /* ** CAPI3REF: Database Connection For Functions +** METHOD: sqlite3_context ** ** ^The sqlite3_context_db_handle() interface returns a copy of ** the pointer to the [database connection] (the 1st parameter) @@ -4518,10 +4626,11 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context*); ** and [sqlite3_create_function16()] routines that originally ** registered the application defined function. */ -SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); +SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*); /* ** CAPI3REF: Function Auxiliary Data +** METHOD: sqlite3_context ** ** These functions may be used by (non-aggregate) SQL functions to ** associate metadata with argument values. If the same value is passed to @@ -4570,8 +4679,8 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** These routines must be called from the same thread in which ** the SQL function is running. */ -SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); -SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); +SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N); +SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); /* @@ -4594,6 +4703,7 @@ typedef void (*sqlite3_destructor_type)(void*); /* ** CAPI3REF: Setting The Result Of An SQL Function +** METHOD: sqlite3_context ** ** These routines are used by the xFunc or xFinal callbacks that ** implement SQL functions and aggregates. See @@ -4706,29 +4816,30 @@ typedef void (*sqlite3_destructor_type)(void*); ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. */ -SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); -SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*, +SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*, sqlite3_uint64,void(*)(void*)); -SQLITE_API void sqlite3_result_double(sqlite3_context*, double); -SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); -SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); -SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); -SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); -SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int); -SQLITE_API void sqlite3_result_int(sqlite3_context*, int); -SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); -SQLITE_API void sqlite3_result_null(sqlite3_context*); -SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); -SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, +SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, void(*)(void*), unsigned char encoding); -SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); -SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); -SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); -SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); -SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n); /* ** CAPI3REF: Define New Collating Sequences +** METHOD: sqlite3 ** ** ^These functions add, remove, or modify a [collation] associated ** with the [database connection] specified as the first argument. @@ -4806,14 +4917,14 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); ** ** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. */ -SQLITE_API int sqlite3_create_collation( +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation( sqlite3*, const char *zName, int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*) ); -SQLITE_API int sqlite3_create_collation_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2( sqlite3*, const char *zName, int eTextRep, @@ -4821,7 +4932,7 @@ SQLITE_API int sqlite3_create_collation_v2( int(*xCompare)(void*,int,const void*,int,const void*), void(*xDestroy)(void*) ); -SQLITE_API int sqlite3_create_collation16( +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16( sqlite3*, const void *zName, int eTextRep, @@ -4831,6 +4942,7 @@ SQLITE_API int sqlite3_create_collation16( /* ** CAPI3REF: Collation Needed Callbacks +** METHOD: sqlite3 ** ** ^To avoid having to register all collation sequences before a database ** can be used, a single callback function may be registered with the @@ -4855,12 +4967,12 @@ SQLITE_API int sqlite3_create_collation16( ** [sqlite3_create_collation()], [sqlite3_create_collation16()], or ** [sqlite3_create_collation_v2()]. */ -SQLITE_API int sqlite3_collation_needed( +SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed( sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const char*) ); -SQLITE_API int sqlite3_collation_needed16( +SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16( sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const void*) @@ -4874,11 +4986,11 @@ SQLITE_API int sqlite3_collation_needed16( ** The code to implement this API is not available in the public release ** of SQLite. */ -SQLITE_API int sqlite3_key( +SQLITE_API int SQLITE_STDCALL sqlite3_key( sqlite3 *db, /* Database to be rekeyed */ const void *pKey, int nKey /* The key */ ); -SQLITE_API int sqlite3_key_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_key_v2( sqlite3 *db, /* Database to be rekeyed */ const char *zDbName, /* Name of the database */ const void *pKey, int nKey /* The key */ @@ -4892,11 +5004,11 @@ SQLITE_API int sqlite3_key_v2( ** The code to implement this API is not available in the public release ** of SQLite. */ -SQLITE_API int sqlite3_rekey( +SQLITE_API int SQLITE_STDCALL sqlite3_rekey( sqlite3 *db, /* Database to be rekeyed */ const void *pKey, int nKey /* The new key */ ); -SQLITE_API int sqlite3_rekey_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2( sqlite3 *db, /* Database to be rekeyed */ const char *zDbName, /* Name of the database */ const void *pKey, int nKey /* The new key */ @@ -4906,7 +5018,7 @@ SQLITE_API int sqlite3_rekey_v2( ** Specify the activation key for a SEE database. Unless ** activated, none of the SEE routines will work. */ -SQLITE_API void sqlite3_activate_see( +SQLITE_API void SQLITE_STDCALL sqlite3_activate_see( const char *zPassPhrase /* Activation phrase */ ); #endif @@ -4916,7 +5028,7 @@ SQLITE_API void sqlite3_activate_see( ** Specify the activation key for a CEROD database. Unless ** activated, none of the CEROD routines will work. */ -SQLITE_API void sqlite3_activate_cerod( +SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod( const char *zPassPhrase /* Activation phrase */ ); #endif @@ -4938,7 +5050,7 @@ SQLITE_API void sqlite3_activate_cerod( ** all, then the behavior of sqlite3_sleep() may deviate from the description ** in the previous paragraphs. */ -SQLITE_API int sqlite3_sleep(int); +SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int); /* ** CAPI3REF: Name Of The Folder Holding Temporary Files @@ -5038,6 +5150,7 @@ SQLITE_API char *sqlite3_data_directory; /* ** CAPI3REF: Test For Auto-Commit Mode ** KEYWORDS: {autocommit mode} +** METHOD: sqlite3 ** ** ^The sqlite3_get_autocommit() interface returns non-zero or ** zero if the given database connection is or is not in autocommit mode, @@ -5056,10 +5169,11 @@ SQLITE_API char *sqlite3_data_directory; ** connection while this routine is running, then the return value ** is undefined. */ -SQLITE_API int sqlite3_get_autocommit(sqlite3*); +SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*); /* ** CAPI3REF: Find The Database Handle Of A Prepared Statement +** METHOD: sqlite3_stmt ** ** ^The sqlite3_db_handle interface returns the [database connection] handle ** to which a [prepared statement] belongs. ^The [database connection] @@ -5068,10 +5182,11 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3*); ** to the [sqlite3_prepare_v2()] call (or its variants) that was used to ** create the statement in the first place. */ -SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); +SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*); /* ** CAPI3REF: Return The Filename For A Database Connection +** METHOD: sqlite3 ** ** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename ** associated with database N of connection D. ^The main database file @@ -5084,19 +5199,21 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); ** will be an absolute pathname, even if the filename used ** to open the database originally was a URI or relative pathname. */ -SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); +SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName); /* ** CAPI3REF: Determine if a database is read-only +** METHOD: sqlite3 ** ** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N ** of connection D is read-only, 0 if it is read/write, or -1 if N is not ** the name of a database on connection D. */ -SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); +SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName); /* ** CAPI3REF: Find the next prepared statement +** METHOD: sqlite3 ** ** ^This interface returns a pointer to the next [prepared statement] after ** pStmt associated with the [database connection] pDb. ^If pStmt is NULL @@ -5108,10 +5225,11 @@ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); ** [sqlite3_next_stmt(D,S)] must refer to an open database ** connection and in particular must not be a NULL pointer. */ -SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); +SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); /* ** CAPI3REF: Commit And Rollback Notification Callbacks +** METHOD: sqlite3 ** ** ^The sqlite3_commit_hook() interface registers a callback ** function to be invoked whenever a transaction is [COMMIT | committed]. @@ -5156,11 +5274,12 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); ** ** See also the [sqlite3_update_hook()] interface. */ -SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); -SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); +SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); /* ** CAPI3REF: Data Change Notification Callbacks +** METHOD: sqlite3 ** ** ^The sqlite3_update_hook() interface registers a callback function ** with the [database connection] identified by the first argument @@ -5207,7 +5326,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()] ** interfaces. */ -SQLITE_API void *sqlite3_update_hook( +SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook( sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* @@ -5237,12 +5356,17 @@ SQLITE_API void *sqlite3_update_hook( ** future releases of SQLite. Applications that care about shared ** cache setting should set it explicitly. ** +** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0 +** and will always return SQLITE_MISUSE. On those systems, +** shared cache mode should be enabled per-database connection via +** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. +** ** This interface is threadsafe on processors where writing a ** 32-bit integer is atomic. ** ** See Also: [SQLite Shared-Cache Mode] */ -SQLITE_API int sqlite3_enable_shared_cache(int); +SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int); /* ** CAPI3REF: Attempt To Free Heap Memory @@ -5258,10 +5382,11 @@ SQLITE_API int sqlite3_enable_shared_cache(int); ** ** See also: [sqlite3_db_release_memory()] */ -SQLITE_API int sqlite3_release_memory(int); +SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int); /* ** CAPI3REF: Free Memory Used By A Database Connection +** METHOD: sqlite3 ** ** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap ** memory as possible from database connection D. Unlike the @@ -5271,7 +5396,7 @@ SQLITE_API int sqlite3_release_memory(int); ** ** See also: [sqlite3_release_memory()] */ -SQLITE_API int sqlite3_db_release_memory(sqlite3*); +SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*); /* ** CAPI3REF: Impose A Limit On Heap Size @@ -5323,7 +5448,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); ** The circumstances under which SQLite will enforce the soft heap limit may ** changes in future releases of SQLite. */ -SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N); /* ** CAPI3REF: Deprecated Soft Heap Limit Interface @@ -5334,11 +5459,12 @@ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); ** only. All new applications should use the ** [sqlite3_soft_heap_limit64()] interface rather than this one. */ -SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); +SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N); /* ** CAPI3REF: Extract Metadata About A Column Of A Table +** METHOD: sqlite3 ** ** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns ** information about column C of table T in database D @@ -5403,7 +5529,7 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); ** parsed, if that has not already been done, and returns an error if ** any errors are encountered while loading the schema. */ -SQLITE_API int sqlite3_table_column_metadata( +SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata( sqlite3 *db, /* Connection handle */ const char *zDbName, /* Database name or NULL */ const char *zTableName, /* Table name */ @@ -5417,6 +5543,7 @@ SQLITE_API int sqlite3_table_column_metadata( /* ** CAPI3REF: Load An Extension +** METHOD: sqlite3 ** ** ^This interface loads an SQLite extension library from the named file. ** @@ -5449,7 +5576,7 @@ SQLITE_API int sqlite3_table_column_metadata( ** ** See also the [load_extension() SQL function]. */ -SQLITE_API int sqlite3_load_extension( +SQLITE_API int SQLITE_STDCALL sqlite3_load_extension( sqlite3 *db, /* Load the extension into this database connection */ const char *zFile, /* Name of the shared library containing extension */ const char *zProc, /* Entry point. Derived from zFile if 0 */ @@ -5458,6 +5585,7 @@ SQLITE_API int sqlite3_load_extension( /* ** CAPI3REF: Enable Or Disable Extension Loading +** METHOD: sqlite3 ** ** ^So as not to open security holes in older applications that are ** unprepared to deal with [extension loading], and as a means of disabling @@ -5469,7 +5597,7 @@ SQLITE_API int sqlite3_load_extension( ** to turn extension loading on and call it with onoff==0 to turn ** it back off again. */ -SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); +SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff); /* ** CAPI3REF: Automatically Load Statically Linked Extensions @@ -5507,7 +5635,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); ** See also: [sqlite3_reset_auto_extension()] ** and [sqlite3_cancel_auto_extension()] */ -SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void)); +SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xEntryPoint)(void)); /* ** CAPI3REF: Cancel Automatic Extension Loading @@ -5519,7 +5647,7 @@ SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void)); ** unregistered and it returns 0 if X was not on the list of initialization ** routines. */ -SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void)); +SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xEntryPoint)(void)); /* ** CAPI3REF: Reset Automatic Extension Loading @@ -5527,7 +5655,7 @@ SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void)); ** ^This interface disables all automatic extensions previously ** registered using [sqlite3_auto_extension()]. */ -SQLITE_API void sqlite3_reset_auto_extension(void); +SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void); /* ** The interface to the virtual-table mechanism is currently considered @@ -5707,6 +5835,7 @@ struct sqlite3_index_info { /* ** CAPI3REF: Register A Virtual Table Implementation +** METHOD: sqlite3 ** ** ^These routines are used to register a new [virtual table module] name. ** ^Module names must be registered before @@ -5730,13 +5859,13 @@ struct sqlite3_index_info { ** interface is equivalent to sqlite3_create_module_v2() with a NULL ** destructor. */ -SQLITE_API int sqlite3_create_module( +SQLITE_API int SQLITE_STDCALL sqlite3_create_module( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ void *pClientData /* Client data for xCreate/xConnect */ ); -SQLITE_API int sqlite3_create_module_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ @@ -5764,7 +5893,7 @@ SQLITE_API int sqlite3_create_module_v2( */ struct sqlite3_vtab { const sqlite3_module *pModule; /* The module for this virtual table */ - int nRef; /* NO LONGER USED */ + int nRef; /* Number of open cursors */ char *zErrMsg; /* Error message from sqlite3_mprintf() */ /* Virtual table implementations will typically add additional fields */ }; @@ -5799,10 +5928,11 @@ struct sqlite3_vtab_cursor { ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. */ -SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); +SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL); /* ** CAPI3REF: Overload A Function For A Virtual Table +** METHOD: sqlite3 ** ** ^(Virtual tables can provide alternative implementations of functions ** using the [xFindFunction] method of the [virtual table module]. @@ -5817,7 +5947,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); ** purpose is to be a placeholder function that can be overloaded ** by a [virtual table]. */ -SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); +SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); /* ** The interface to the virtual-table mechanism defined above (back up @@ -5845,6 +5975,8 @@ typedef struct sqlite3_blob sqlite3_blob; /* ** CAPI3REF: Open A BLOB For Incremental I/O +** METHOD: sqlite3 +** CONSTRUCTOR: sqlite3_blob ** ** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located ** in row iRow, column zColumn, table zTable in database zDb; @@ -5914,7 +6046,7 @@ typedef struct sqlite3_blob sqlite3_blob; ** To avoid a resource leak, every open [BLOB handle] should eventually ** be released by a call to [sqlite3_blob_close()]. */ -SQLITE_API int sqlite3_blob_open( +SQLITE_API int SQLITE_STDCALL sqlite3_blob_open( sqlite3*, const char *zDb, const char *zTable, @@ -5926,6 +6058,7 @@ SQLITE_API int sqlite3_blob_open( /* ** CAPI3REF: Move a BLOB Handle to a New Row +** METHOD: sqlite3_blob ** ** ^This function is used to move an existing blob handle so that it points ** to a different row of the same database table. ^The new row is identified @@ -5946,10 +6079,11 @@ SQLITE_API int sqlite3_blob_open( ** ** ^This function sets the database handle error code and message. */ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); +SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); /* ** CAPI3REF: Close A BLOB Handle +** DESTRUCTOR: sqlite3_blob ** ** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed ** unconditionally. Even if this routine returns an error code, the @@ -5968,10 +6102,11 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_i ** is passed a valid open blob handle, the values returned by the ** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning. */ -SQLITE_API int sqlite3_blob_close(sqlite3_blob *); +SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *); /* ** CAPI3REF: Return The Size Of An Open BLOB +** METHOD: sqlite3_blob ** ** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The @@ -5983,10 +6118,11 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *); ** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. */ -SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); +SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *); /* ** CAPI3REF: Read Data From A BLOB Incrementally +** METHOD: sqlite3_blob ** ** ^(This function is used to read data from an open [BLOB handle] into a ** caller-supplied buffer. N bytes of data are copied into buffer Z @@ -6011,10 +6147,11 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); ** ** See also: [sqlite3_blob_write()]. */ -SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); +SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); /* ** CAPI3REF: Write Data Into A BLOB Incrementally +** METHOD: sqlite3_blob ** ** ^(This function is used to write data into an open [BLOB handle] from a ** caller-supplied buffer. N bytes of data are copied from the buffer Z @@ -6052,7 +6189,7 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); ** ** See also: [sqlite3_blob_read()]. */ -SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); +SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); /* ** CAPI3REF: Virtual File System Objects @@ -6083,9 +6220,9 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOff ** ^(If the default VFS is unregistered, another VFS is chosen as ** the default. The choice for the new VFS is arbitrary.)^ */ -SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); -SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); -SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); +SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName); +SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*); /* ** CAPI3REF: Mutexes @@ -6198,11 +6335,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. */ -SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int); -SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*); -SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*); -SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*); -SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); +SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int); +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*); +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*); +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*); +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*); /* ** CAPI3REF: Mutex Methods Object @@ -6312,8 +6449,8 @@ struct sqlite3_mutex_methods { ** interface should also return 1 when given a NULL pointer. */ #ifndef NDEBUG -SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); -SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*); +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*); #endif /* @@ -6342,6 +6479,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); /* ** CAPI3REF: Retrieve the mutex for a database connection +** METHOD: sqlite3 ** ** ^This interface returns a pointer the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument @@ -6349,10 +6487,11 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); ** ^If the [threading mode] is Single-thread or Multi-thread then this ** routine returns a NULL pointer. */ -SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); +SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*); /* ** CAPI3REF: Low-Level Control Of Database Files +** METHOD: sqlite3 ** ** ^The [sqlite3_file_control()] interface makes a direct call to the ** xFileControl method for the [sqlite3_io_methods] object associated @@ -6383,7 +6522,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); ** ** See also: [SQLITE_FCNTL_LOCKSTATE] */ -SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); +SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); /* ** CAPI3REF: Testing Interface @@ -6402,7 +6541,7 @@ SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void* ** Unlike most of the SQLite API, this function is not guaranteed to ** operate consistently from one release to the next. */ -SQLITE_API int sqlite3_test_control(int op, ...); +SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...); /* ** CAPI3REF: Testing Interface Operation Codes @@ -6436,12 +6575,13 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_BYTEORDER 22 #define SQLITE_TESTCTRL_ISINIT 23 #define SQLITE_TESTCTRL_SORTER_MMAP 24 -#define SQLITE_TESTCTRL_LAST 24 +#define SQLITE_TESTCTRL_IMPOSTER 25 +#define SQLITE_TESTCTRL_LAST 25 /* ** CAPI3REF: SQLite Runtime Status ** -** ^This interface is used to retrieve runtime status information +** ^These interfaces are used to retrieve runtime status information ** about the performance of SQLite, and optionally to reset various ** highwater marks. ^The first argument is an integer code for ** the specific parameter to measure. ^(Recognized integer codes @@ -6455,19 +6595,22 @@ SQLITE_API int sqlite3_test_control(int op, ...); ** ^(Other parameters record only the highwater mark and not the current ** value. For these latter parameters nothing is written into *pCurrent.)^ ** -** ^The sqlite3_status() routine returns SQLITE_OK on success and a -** non-zero [error code] on failure. +** ^The sqlite3_status() and sqlite3_status64() routines return +** SQLITE_OK on success and a non-zero [error code] on failure. ** -** This routine is threadsafe but is not atomic. This routine can be -** called while other threads are running the same or different SQLite -** interfaces. However the values returned in *pCurrent and -** *pHighwater reflect the status of SQLite at different points in time -** and it is possible that another thread might change the parameter -** in between the times when *pCurrent and *pHighwater are written. +** If either the current value or the highwater mark is too large to +** be represented by a 32-bit integer, then the values returned by +** sqlite3_status() are undefined. ** ** See also: [sqlite3_db_status()] */ -SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); +SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); +SQLITE_API int SQLITE_STDCALL sqlite3_status64( + int op, + sqlite3_int64 *pCurrent, + sqlite3_int64 *pHighwater, + int resetFlag +); /* @@ -6565,6 +6708,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF /* ** CAPI3REF: Database Connection Status +** METHOD: sqlite3 ** ** ^This interface is used to retrieve runtime status information ** about a single [database connection]. ^The first argument is the @@ -6585,7 +6729,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF ** ** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. */ -SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); +SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); /* ** CAPI3REF: Status Parameters for database connections @@ -6693,6 +6837,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r /* ** CAPI3REF: Prepared Statement Status +** METHOD: sqlite3_stmt ** ** ^(Each prepared statement maintains various ** [SQLITE_STMTSTATUS counters] that measure the number @@ -6714,7 +6859,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** ** See also: [sqlite3_status()] and [sqlite3_db_status()]. */ -SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); /* ** CAPI3REF: Status Parameters for prepared statements @@ -7137,20 +7282,20 @@ typedef struct sqlite3_backup sqlite3_backup; ** is not a permanent error and does not affect the return value of ** sqlite3_backup_finish(). ** -** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]] +** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]] ** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b> ** -** ^Each call to sqlite3_backup_step() sets two values inside -** the [sqlite3_backup] object: the number of pages still to be backed -** up and the total number of pages in the source database file. -** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces -** retrieve these two values, respectively. -** -** ^The values returned by these functions are only updated by -** sqlite3_backup_step(). ^If the source database is modified during a backup -** operation, then the values are not updated to account for any extra -** pages that need to be updated or the size of the source database file -** changing. +** ^The sqlite3_backup_remaining() routine returns the number of pages still +** to be backed up at the conclusion of the most recent sqlite3_backup_step(). +** ^The sqlite3_backup_pagecount() routine returns the total number of pages +** in the source database at the conclusion of the most recent +** sqlite3_backup_step(). +** ^(The values returned by these functions are only updated by +** sqlite3_backup_step(). If the source database is modified in a way that +** changes the size of the source database or the number of pages remaining, +** those changes are not reflected in the output of sqlite3_backup_pagecount() +** and sqlite3_backup_remaining() until after the next +** sqlite3_backup_step().)^ ** ** <b>Concurrent Usage of Database Handles</b> ** @@ -7183,19 +7328,20 @@ typedef struct sqlite3_backup sqlite3_backup; ** same time as another thread is invoking sqlite3_backup_step() it is ** possible that they return invalid values. */ -SQLITE_API sqlite3_backup *sqlite3_backup_init( +SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init( sqlite3 *pDest, /* Destination database handle */ const char *zDestName, /* Destination database name */ sqlite3 *pSource, /* Source database handle */ const char *zSourceName /* Source database name */ ); -SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage); -SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p); -SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p); -SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p); /* ** CAPI3REF: Unlock Notification +** METHOD: sqlite3 ** ** ^When running in shared-cache mode, a database operation may fail with ** an [SQLITE_LOCKED] error if the required locks on the shared-cache or @@ -7308,7 +7454,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** the special "DROP TABLE/INDEX" case, the extended error code is just ** SQLITE_LOCKED.)^ */ -SQLITE_API int sqlite3_unlock_notify( +SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify( sqlite3 *pBlocked, /* Waiting connection */ void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ void *pNotifyArg /* Argument to pass to xNotify */ @@ -7323,8 +7469,8 @@ SQLITE_API int sqlite3_unlock_notify( ** strings in a case-independent fashion, using the same definition of "case ** independence" that SQLite uses internally when comparing identifiers. */ -SQLITE_API int sqlite3_stricmp(const char *, const char *); -SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); +SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *); +SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int); /* ** CAPI3REF: String Globbing @@ -7339,7 +7485,7 @@ SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); ** Note that this routine returns zero on a match and non-zero if the strings ** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. */ -SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr); +SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr); /* ** CAPI3REF: Error Logging Interface @@ -7362,10 +7508,11 @@ SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr); ** a few hundred characters, it will be truncated to the length of the ** buffer. */ -SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); +SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...); /* ** CAPI3REF: Write-Ahead Log Commit Hook +** METHOD: sqlite3 ** ** ^The [sqlite3_wal_hook()] function is used to register a callback that ** is invoked each time data is committed to a database in wal mode. @@ -7397,7 +7544,7 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will ** those overwrite any prior [sqlite3_wal_hook()] settings. */ -SQLITE_API void *sqlite3_wal_hook( +SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook( sqlite3*, int(*)(void *,sqlite3*,const char*,int), void* @@ -7405,6 +7552,7 @@ SQLITE_API void *sqlite3_wal_hook( /* ** CAPI3REF: Configure an auto-checkpoint +** METHOD: sqlite3 ** ** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around ** [sqlite3_wal_hook()] that causes any database on [database connection] D @@ -7431,10 +7579,11 @@ SQLITE_API void *sqlite3_wal_hook( ** is only necessary if the default setting is found to be suboptimal ** for a particular application. */ -SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); +SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N); /* ** CAPI3REF: Checkpoint a database +** METHOD: sqlite3 ** ** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to ** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ @@ -7452,10 +7601,11 @@ SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); ** start a callback but which do not need the full power (and corresponding ** complication) of [sqlite3_wal_checkpoint_v2()]. */ -SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); +SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); /* ** CAPI3REF: Checkpoint a database +** METHOD: sqlite3 ** ** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint ** operation on database X of [database connection] D in mode M. Status @@ -7545,7 +7695,7 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); ** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface ** from SQL. */ -SQLITE_API int sqlite3_wal_checkpoint_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2( sqlite3 *db, /* Database handle */ const char *zDb, /* Name of attached database (or NULL) */ int eMode, /* SQLITE_CHECKPOINT_* value */ @@ -7581,7 +7731,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( ** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options ** may be added in the future. */ -SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); +SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...); /* ** CAPI3REF: Virtual Table Configuration Options @@ -7634,7 +7784,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); ** of the SQL statement that triggered the call to the [xUpdate] method of the ** [virtual table]. */ -SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); +SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *); /* ** CAPI3REF: Conflict resolution modes @@ -7710,6 +7860,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); /* ** CAPI3REF: Prepared Statement Scan Status +** METHOD: sqlite3_stmt ** ** This interface returns information about the predicted and measured ** performance for pStmt. Advanced applications can use this @@ -7738,7 +7889,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); ** ** See also: [sqlite3_stmt_scanstatus_reset()] */ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus( +SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ @@ -7747,13 +7898,14 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus( /* ** CAPI3REF: Zero Scan-Status Counters +** METHOD: sqlite3_stmt ** ** ^Zero all [sqlite3_stmt_scanstatus()] related event counters. ** ** This API is only available if the library is built with pre-processor ** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined. */ -SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); +SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); /* @@ -7808,7 +7960,7 @@ typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ -SQLITE_API int sqlite3_rtree_geometry_callback( +SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback( sqlite3 *db, const char *zGeom, int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), @@ -7834,7 +7986,7 @@ struct sqlite3_rtree_geometry { ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...) */ -SQLITE_API int sqlite3_rtree_query_callback( +SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback( sqlite3 *db, const char *zQueryFunc, int (*xQueryFunc)(sqlite3_rtree_query_info*), @@ -7998,15 +8150,17 @@ struct sqlite3_rtree_query_info { #endif /* -** The maximum number of in-memory pages to use for the main database -** table and for temporary tables. The SQLITE_DEFAULT_CACHE_SIZE +** The suggested maximum number of in-memory pages to use for +** the main database table and for temporary tables. +** +** IMPLEMENTATION-OF: R-31093-59126 The default suggested cache size +** is 2000 pages. +** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be +** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options. */ #ifndef SQLITE_DEFAULT_CACHE_SIZE # define SQLITE_DEFAULT_CACHE_SIZE 2000 #endif -#ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE -# define SQLITE_DEFAULT_TEMP_CACHE_SIZE 500 -#endif /* ** The default number of frames to accumulate in the log file before @@ -8355,6 +8509,32 @@ SQLITE_PRIVATE void sqlite3Coverage(int); # define NEVER(X) (X) #endif +/* +** Declarations used for tracing the operating system interfaces. +*/ +#if defined(SQLITE_FORCE_OS_TRACE) || defined(SQLITE_TEST) || \ + (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) + extern int sqlite3OSTrace; +# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X +# define SQLITE_HAVE_OS_TRACE +#else +# define OSTRACE(X) +# undef SQLITE_HAVE_OS_TRACE +#endif + +/* +** Is the sqlite3ErrName() function needed in the build? Currently, +** it is needed by "mutex_w32.c" (when debugging), "os_win.c" (when +** OSTRACE is enabled), and by several "test*.c" files (which are +** compiled using SQLITE_TEST). +*/ +#if defined(SQLITE_HAVE_OS_TRACE) || defined(SQLITE_TEST) || \ + (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) +# define SQLITE_NEED_ERR_NAME +#else +# undef SQLITE_NEED_ERR_NAME +#endif + /* ** Return true (non-zero) if the input is an integer that is too large ** to fit in 32-bits. This macro is used inside of various testcase() @@ -8850,6 +9030,20 @@ typedef INT8_TYPE i8; /* 1-byte signed integer */ */ typedef INT16_TYPE LogEst; +/* +** Set the SQLITE_PTRSIZE macro to the number of bytes in a pointer +*/ +#ifndef SQLITE_PTRSIZE +# if defined(__SIZEOF_POINTER__) +# define SQLITE_PTRSIZE __SIZEOF_POINTER__ +# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(_M_ARM) || defined(__arm__) || defined(__x86) +# define SQLITE_PTRSIZE 4 +# else +# define SQLITE_PTRSIZE 8 +# endif +#endif + /* ** Macros to determine whether the machine is big or little endian, ** and whether or not that determination is run-time or compile-time. @@ -9062,8 +9256,8 @@ struct BusyHandler { #define SQLITE_WSD const #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v))) #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config) -SQLITE_API int sqlite3_wsd_init(int N, int J); -SQLITE_API void *sqlite3_wsd_find(void *K, int L); +SQLITE_API int SQLITE_STDCALL sqlite3_wsd_init(int N, int J); +SQLITE_API void *SQLITE_STDCALL sqlite3_wsd_find(void *K, int L); #else #define SQLITE_WSD #define GLOBAL(t,v) v @@ -9221,10 +9415,8 @@ SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*); SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int); SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*); SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int); -SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*); -#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG) +SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree*); SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p); -#endif SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int); SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *); SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int); @@ -9302,8 +9494,18 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p); /* ** Values that may be OR'd together to form the second argument of an ** sqlite3BtreeCursorHints() call. +** +** The BTREE_BULKLOAD flag is set on index cursors when the index is going +** to be filled with content that is already in sorted order. +** +** The BTREE_SEEK_EQ flag is set on cursors that will get OP_SeekGE or +** OP_SeekLE opcodes for a range search, but where the range of entries +** selected will all have the same key. In other words, the cursor will +** be used only for equality key searches. +** */ -#define BTREE_BULKLOAD 0x00000001 +#define BTREE_BULKLOAD 0x00000001 /* Used to full index in sorted order */ +#define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */ SQLITE_PRIVATE int sqlite3BtreeCursor( Btree*, /* BTree containing table to open */ @@ -9349,6 +9551,9 @@ SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *); SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask); +#endif SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt); SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void); @@ -9715,23 +9920,25 @@ typedef struct VdbeOpList VdbeOpList; #define OP_MemMax 136 /* synopsis: r[P1]=max(r[P1],r[P2]) */ #define OP_IfPos 137 /* synopsis: if r[P1]>0 goto P2 */ #define OP_IfNeg 138 /* synopsis: r[P1]+=P3, if r[P1]<0 goto P2 */ -#define OP_IfZero 139 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ -#define OP_AggFinal 140 /* synopsis: accum=r[P1] N=P2 */ -#define OP_IncrVacuum 141 -#define OP_Expire 142 -#define OP_TableLock 143 /* synopsis: iDb=P1 root=P2 write=P3 */ -#define OP_VBegin 144 -#define OP_VCreate 145 -#define OP_VDestroy 146 -#define OP_VOpen 147 -#define OP_VColumn 148 /* synopsis: r[P3]=vcolumn(P2) */ -#define OP_VNext 149 -#define OP_VRename 150 -#define OP_Pagecount 151 -#define OP_MaxPgcnt 152 -#define OP_Init 153 /* synopsis: Start at P2 */ -#define OP_Noop 154 -#define OP_Explain 155 +#define OP_IfNotZero 139 /* synopsis: if r[P1]!=0 then r[P1]+=P3, goto P2 */ +#define OP_DecrJumpZero 140 /* synopsis: if (--r[P1])==0 goto P2 */ +#define OP_JumpZeroIncr 141 /* synopsis: if (r[P1]++)==0 ) goto P2 */ +#define OP_AggFinal 142 /* synopsis: accum=r[P1] N=P2 */ +#define OP_IncrVacuum 143 +#define OP_Expire 144 +#define OP_TableLock 145 /* synopsis: iDb=P1 root=P2 write=P3 */ +#define OP_VBegin 146 +#define OP_VCreate 147 +#define OP_VDestroy 148 +#define OP_VOpen 149 +#define OP_VColumn 150 /* synopsis: r[P3]=vcolumn(P2) */ +#define OP_VNext 151 +#define OP_VRename 152 +#define OP_Pagecount 153 +#define OP_MaxPgcnt 154 +#define OP_Init 155 /* synopsis: Start at P2 */ +#define OP_Noop 156 +#define OP_Explain 157 /* Properties such as "out2" or "jump" that are specified in @@ -9739,33 +9946,32 @@ typedef struct VdbeOpList VdbeOpList; ** are encoded into bitvectors as follows: */ #define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */ -#define OPFLG_OUT2_PRERELEASE 0x0002 /* out2-prerelease: */ -#define OPFLG_IN1 0x0004 /* in1: P1 is an input */ -#define OPFLG_IN2 0x0008 /* in2: P2 is an input */ -#define OPFLG_IN3 0x0010 /* in3: P3 is an input */ -#define OPFLG_OUT2 0x0020 /* out2: P2 is an output */ -#define OPFLG_OUT3 0x0040 /* out3: P3 is an output */ +#define OPFLG_IN1 0x0002 /* in1: P1 is an input */ +#define OPFLG_IN2 0x0004 /* in2: P2 is an input */ +#define OPFLG_IN3 0x0008 /* in3: P3 is an input */ +#define OPFLG_OUT2 0x0010 /* out2: P2 is an output */ +#define OPFLG_OUT3 0x0020 /* out3: P3 is an output */ #define OPFLG_INITIALIZER {\ /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\ -/* 8 */ 0x01, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,\ -/* 16 */ 0x01, 0x01, 0x04, 0x24, 0x01, 0x04, 0x05, 0x10,\ -/* 24 */ 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02,\ -/* 32 */ 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x05, 0x04,\ -/* 40 */ 0x04, 0x00, 0x00, 0x01, 0x01, 0x05, 0x05, 0x00,\ -/* 48 */ 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x00, 0x00,\ -/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\ -/* 64 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x4c,\ -/* 72 */ 0x4c, 0x02, 0x02, 0x00, 0x05, 0x05, 0x15, 0x15,\ -/* 80 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c,\ -/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00,\ -/* 96 */ 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,\ -/* 104 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x08, 0x08, 0x00,\ -/* 112 */ 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x00,\ -/* 120 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 128 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x02, 0x00, 0x01,\ -/* 136 */ 0x08, 0x05, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00,\ -/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,\ -/* 152 */ 0x02, 0x01, 0x00, 0x00,} +/* 8 */ 0x01, 0x01, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\ +/* 16 */ 0x01, 0x01, 0x02, 0x12, 0x01, 0x02, 0x03, 0x08,\ +/* 24 */ 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10,\ +/* 32 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x03, 0x02,\ +/* 40 */ 0x02, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x00,\ +/* 48 */ 0x00, 0x00, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00,\ +/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09,\ +/* 64 */ 0x09, 0x09, 0x04, 0x09, 0x09, 0x09, 0x09, 0x26,\ +/* 72 */ 0x26, 0x10, 0x10, 0x00, 0x03, 0x03, 0x0b, 0x0b,\ +/* 80 */ 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x26, 0x26, 0x26,\ +/* 88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00,\ +/* 96 */ 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\ +/* 104 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x00,\ +/* 112 */ 0x10, 0x01, 0x01, 0x01, 0x01, 0x10, 0x00, 0x00,\ +/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 128 */ 0x06, 0x23, 0x0b, 0x01, 0x10, 0x10, 0x00, 0x01,\ +/* 136 */ 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x01,\ +/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\ +/* 152 */ 0x00, 0x10, 0x10, 0x01, 0x00, 0x00,} /************** End of opcodes.h *********************************************/ /************** Continuing where we left off in vdbe.h ***********************/ @@ -9824,6 +10030,7 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); +SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); @@ -10841,11 +11048,13 @@ struct sqlite3 { u8 iDb; /* Which db file is being initialized */ u8 busy; /* TRUE if currently initializing */ u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */ + u8 imposterTable; /* Building an imposter table */ } init; int nVdbeActive; /* Number of VDBEs currently running */ int nVdbeRead; /* Number of active VDBEs that read or write */ int nVdbeWrite; /* Number of active VDBEs that read and write */ int nVdbeExec; /* Number of nested calls to VdbeExec() */ + int nVDestroy; /* Number of active OP_VDestroy operations */ int nExtension; /* Number of loaded extensions */ void **aExtension; /* Array of shared library handles */ void (*xTrace)(void*,const char*); /* Trace function */ @@ -10959,6 +11168,7 @@ struct sqlite3 { #define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */ #define SQLITE_QueryOnly 0x02000000 /* Disable database changes */ #define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */ +#define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */ /* @@ -11289,34 +11499,8 @@ struct VTable { }; /* -** Each SQL table is represented in memory by an instance of the -** following structure. -** -** Table.zName is the name of the table. The case of the original -** CREATE TABLE statement is stored, but case is not significant for -** comparisons. -** -** Table.nCol is the number of columns in this table. Table.aCol is a -** pointer to an array of Column structures, one for each column. -** -** If the table has an INTEGER PRIMARY KEY, then Table.iPKey is the index of -** the column that is that key. Otherwise Table.iPKey is negative. Note -** that the datatype of the PRIMARY KEY must be INTEGER for this field to -** be set. An INTEGER PRIMARY KEY is used as the rowid for each row of -** the table. If a table has no INTEGER PRIMARY KEY, then a random rowid -** is generated for each row of the table. TF_HasPrimaryKey is set if -** the table has any PRIMARY KEY, INTEGER or otherwise. -** -** Table.tnum is the page number for the root BTree page of the table in the -** database file. If Table.iDb is the index of the database table backend -** in sqlite.aDb[]. 0 is for the main database and 1 is for the file that -** holds temporary tables and indices. If TF_Ephemeral is set -** then the table is stored in a file that is automatically deleted -** when the VDBE cursor to the table is closed. In this case Table.tnum -** refers VDBE cursor number that holds the table open, not to the root -** page number. Transient tables are used to hold the results of a -** sub-query that appears instead of a real table name in the FROM clause -** of a SELECT statement. +** The schema for each SQL table and view is represented in memory +** by an instance of the following structure. */ struct Table { char *zName; /* Name of the table or view */ @@ -11328,11 +11512,11 @@ struct Table { #ifndef SQLITE_OMIT_CHECK ExprList *pCheck; /* All CHECK constraints */ #endif - LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */ - int tnum; /* Root BTree node for this table (see note above) */ - i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */ + int tnum; /* Root BTree page for this table */ + i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */ i16 nCol; /* Number of columns in this table */ u16 nRef; /* Number of pointers to this Table */ + LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */ LogEst szTabRow; /* Estimated size of each table row in bytes */ #ifdef SQLITE_ENABLE_COSTMULT LogEst costMult; /* Cost multiplier for using this table */ @@ -11354,6 +11538,12 @@ struct Table { /* ** Allowed values for Table.tabFlags. +** +** TF_OOOHidden applies to virtual tables that have hidden columns that are +** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING +** vtab1(a HIDDEN, b);". Since "b" is a non-hidden column but "a" is hidden, +** the TF_OOOHidden attribute would apply in this case. Such tables require +** special handling during INSERT processing. */ #define TF_Readonly 0x01 /* Read-only system table */ #define TF_Ephemeral 0x02 /* An ephemeral table */ @@ -11361,6 +11551,7 @@ struct Table { #define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ #define TF_Virtual 0x10 /* Is a virtual table */ #define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */ +#define TF_OOOHidden 0x40 /* Out-of-Order hidden columns */ /* @@ -11797,8 +11988,14 @@ struct Expr { #define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ #define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ -#define EP_Constant 0x080000 /* Node is a constant */ +#define EP_ConstFunc 0x080000 /* Node is a SQLITE_FUNC_CONSTANT function */ #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ +#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ + +/* +** Combinations of two or more EP_* flags +*/ +#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */ /* ** These macros can be used to test, set, or clear bits in the @@ -11997,7 +12194,7 @@ struct SrcList { #define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */ #define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */ #define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */ - /* 0x0080 // not currently used */ +#define WHERE_NO_AUTOINDEX 0x0080 /* Disallow automatic indexes */ #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ @@ -12111,11 +12308,12 @@ struct Select { #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ #define SF_Compound 0x0040 /* Part of a compound query */ #define SF_Values 0x0080 /* Synthesized from VALUES clause */ -#define SF_AllValues 0x0100 /* All terms of compound are VALUES */ +#define SF_MultiValue 0x0100 /* Single VALUES term with multiple rows */ #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */ #define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */ #define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */ #define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */ +#define SF_Converted 0x2000 /* By convertCompoundSelectToSubquery() */ /* @@ -12434,7 +12632,8 @@ struct AuthContext { #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ -#define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */ +#define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */ +#define OPFLAG_P2ISREG 0x04 /* P2 to OP_Open** is a register number */ #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ /* @@ -12493,7 +12692,7 @@ struct Trigger { * orconf -> stores the ON CONFLICT algorithm * pSelect -> If this is an INSERT INTO ... SELECT ... statement, then * this stores a pointer to the SELECT statement. Otherwise NULL. - * target -> A token holding the quoted name of the table to insert into. + * zTarget -> Dequoted name of the table to insert into. * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then * this stores values to be inserted. Otherwise NULL. * pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ... @@ -12501,12 +12700,12 @@ struct Trigger { * inserted into. * * (op == TK_DELETE) - * target -> A token holding the quoted name of the table to delete from. + * zTarget -> Dequoted name of the table to delete from. * pWhere -> The WHERE clause of the DELETE statement if one is specified. * Otherwise NULL. * * (op == TK_UPDATE) - * target -> A token holding the quoted name of the table to update rows of. + * zTarget -> Dequoted name of the table to update. * pWhere -> The WHERE clause of the UPDATE statement if one is specified. * Otherwise NULL. * pExprList -> A list of the columns to update and the expressions to update @@ -12518,8 +12717,8 @@ struct TriggerStep { u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */ u8 orconf; /* OE_Rollback etc. */ Trigger *pTrig; /* The trigger that this step is a part of */ - Select *pSelect; /* SELECT statment or RHS of INSERT INTO .. SELECT ... */ - Token target; /* Target table for DELETE, UPDATE, INSERT */ + Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */ + char *zTarget; /* Target table for DELETE, UPDATE, INSERT */ Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */ ExprList *pExprList; /* SET clause for UPDATE. */ IdList *pIdList; /* Column names for INSERT */ @@ -12552,8 +12751,7 @@ struct StrAccum { char *zText; /* The string collected so far */ int nChar; /* Length of the string so far */ int nAlloc; /* Amount of space allocated in zText */ - int mxAlloc; /* Maximum allowed string length */ - u8 useMalloc; /* 0: none, 1: sqlite3DbMalloc, 2: sqlite3_malloc */ + int mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */ }; #define STRACCUM_NOMEM 1 @@ -12838,10 +13036,15 @@ SQLITE_PRIVATE int sqlite3MutexInit(void); SQLITE_PRIVATE int sqlite3MutexEnd(void); #endif -SQLITE_PRIVATE int sqlite3StatusValue(int); -SQLITE_PRIVATE void sqlite3StatusAdd(int, int); +SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int); +SQLITE_PRIVATE void sqlite3StatusUp(int, int); +SQLITE_PRIVATE void sqlite3StatusDown(int, int); SQLITE_PRIVATE void sqlite3StatusSet(int, int); +/* Access to mutexes used by sqlite3_status() */ +SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void); +SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void); + #ifndef SQLITE_OMIT_FLOATING_POINT SQLITE_PRIVATE int sqlite3IsNaN(double); #else @@ -12865,7 +13068,7 @@ SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, u32, const char*, ...); SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...); SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list); SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...); -#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...); #endif #if defined(SQLITE_TEST) @@ -12906,6 +13109,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*); SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); +SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); @@ -13211,7 +13415,7 @@ SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); SQLITE_PRIVATE u8 sqlite3HexToInt(int h); SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); -#if defined(SQLITE_TEST) +#if defined(SQLITE_NEED_ERR_NAME) SQLITE_PRIVATE const char *sqlite3ErrName(int); #endif @@ -13220,7 +13424,7 @@ SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); -SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*); +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int); SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*); SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *); @@ -13305,7 +13509,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); -SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int); +SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int); SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*); SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char); @@ -13489,12 +13693,11 @@ SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *); SQLITE_PRIVATE int sqlite3MemJournalSize(void); SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *); +SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p); #if SQLITE_MAX_EXPR_DEPTH>0 -SQLITE_PRIVATE void sqlite3ExprSetHeight(Parse *pParse, Expr *p); SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *); SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse*, int); #else - #define sqlite3ExprSetHeight(x,y) #define sqlite3SelectExprHeight(x) 0 #define sqlite3ExprCheckHeight(x,y) #endif @@ -13524,7 +13727,7 @@ SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *); #ifdef SQLITE_ENABLE_IOTRACE # define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; } SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*); -void (*sqlite3IoTrace)(const char*,...); +SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...); #else # define IOTRACE(A) # define sqlite3VdbeIOTraceSql(X) @@ -13631,16 +13834,16 @@ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */ - 96, 97, 66, 67, 68, 69, 70, 71, 72, 73,106,107,108,109,110,111, /* 6x */ - 112, 81, 82, 83, 84, 85, 86, 87, 88, 89,122,123,124,125,126,127, /* 7x */ + 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 6x */ + 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 7x */ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */ - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,156,159, /* 9x */ + 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, /* 9x */ 160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */ 192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */ 208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */ - 224,225,162,163,164,165,166,167,168,169,232,203,204,205,206,207, /* Ex */ - 239,240,241,242,243,244,245,246,247,248,249,219,220,221,222,255, /* Fx */ + 224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */ + 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */ #endif }; @@ -13923,6 +14126,9 @@ static const char * const azCompileOpt[] = { #if SQLITE_ENABLE_COLUMN_METADATA "ENABLE_COLUMN_METADATA", #endif +#if SQLITE_ENABLE_DBSTAT_VTAB + "ENABLE_DBSTAT_VTAB", +#endif #if SQLITE_ENABLE_EXPENSIVE_ASSERT "ENABLE_EXPENSIVE_ASSERT", #endif @@ -14237,7 +14443,7 @@ static const char * const azCompileOpt[] = { ** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix ** is not required for a match. */ -SQLITE_API int sqlite3_compileoption_used(const char *zOptName){ +SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName){ int i, n; #if SQLITE_ENABLE_API_ARMOR @@ -14265,7 +14471,7 @@ SQLITE_API int sqlite3_compileoption_used(const char *zOptName){ ** Return the N-th compile-time option string. If N is out of range, ** return a NULL pointer. */ -SQLITE_API const char *sqlite3_compileoption_get(int N){ +SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N){ if( N>=0 && N<ArraySize(azCompileOpt) ){ return azCompileOpt[N]; } @@ -14608,14 +14814,6 @@ struct ScanStatus { ** ** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare() ** is really a pointer to an instance of this structure. -** -** The Vdbe.inVtabMethod variable is set to non-zero for the duration of -** any virtual table method invocations made by the vdbe program. It is -** set to 2 for xDestroy method calls and 1 for all other methods. This -** variable is used for two purposes: to allow xDestroy methods to execute -** "DROP TABLE" statements and to prevent some nasty side effects of -** malloc failure when SQLite is invoked recursively by a virtual table -** method function. */ struct Vdbe { sqlite3 *db; /* The database connection that owns this statement */ @@ -14639,11 +14837,13 @@ struct Vdbe { u32 cacheCtr; /* VdbeCursor row cache generation counter */ int pc; /* The program counter */ int rc; /* Value to return */ +#ifdef SQLITE_DEBUG + int rcApp; /* errcode set by sqlite3_result_error_code() */ +#endif u16 nResColumn; /* Number of columns in one row of the result set */ u8 errorAction; /* Recovery action to do in case of an error */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ bft explain:2; /* True if EXPLAIN present on SQL command */ - bft inVtabMethod:2; /* See comments above */ bft changeCntOn:1; /* True to update the change-counter */ bft expired:1; /* True if the VM needs to be recompiled */ bft runOnlyOnce:1; /* Automatically expire on reset */ @@ -14803,10 +15003,32 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *); */ typedef struct sqlite3StatType sqlite3StatType; static SQLITE_WSD struct sqlite3StatType { - int nowValue[10]; /* Current value */ - int mxValue[10]; /* Maximum value */ +#if SQLITE_PTRSIZE>4 + sqlite3_int64 nowValue[10]; /* Current value */ + sqlite3_int64 mxValue[10]; /* Maximum value */ +#else + u32 nowValue[10]; /* Current value */ + u32 mxValue[10]; /* Maximum value */ +#endif } sqlite3Stat = { {0,}, {0,} }; +/* +** Elements of sqlite3Stat[] are protected by either the memory allocator +** mutex, or by the pcache1 mutex. The following array determines which. +*/ +static const char statMutex[] = { + 0, /* SQLITE_STATUS_MEMORY_USED */ + 1, /* SQLITE_STATUS_PAGECACHE_USED */ + 1, /* SQLITE_STATUS_PAGECACHE_OVERFLOW */ + 0, /* SQLITE_STATUS_SCRATCH_USED */ + 0, /* SQLITE_STATUS_SCRATCH_OVERFLOW */ + 0, /* SQLITE_STATUS_MALLOC_SIZE */ + 0, /* SQLITE_STATUS_PARSER_STACK */ + 1, /* SQLITE_STATUS_PAGECACHE_SIZE */ + 0, /* SQLITE_STATUS_SCRATCH_SIZE */ + 0, /* SQLITE_STATUS_MALLOC_COUNT */ +}; + /* The "wsdStat" macro will resolve to the status information ** state vector. If writable static data is unsupported on the target, @@ -14823,33 +15045,60 @@ static SQLITE_WSD struct sqlite3StatType { #endif /* -** Return the current value of a status parameter. +** Return the current value of a status parameter. The caller must +** be holding the appropriate mutex. */ -SQLITE_PRIVATE int sqlite3StatusValue(int op){ +SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int op){ wsdStatInit; assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); + assert( op>=0 && op<ArraySize(statMutex) ); + assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex() + : sqlite3MallocMutex()) ); return wsdStat.nowValue[op]; } /* -** Add N to the value of a status record. It is assumed that the -** caller holds appropriate locks. +** Add N to the value of a status record. The caller must hold the +** appropriate mutex. (Locking is checked by assert()). +** +** The StatusUp() routine can accept positive or negative values for N. +** The value of N is added to the current status value and the high-water +** mark is adjusted if necessary. +** +** The StatusDown() routine lowers the current value by N. The highwater +** mark is unchanged. N must be non-negative for StatusDown(). */ -SQLITE_PRIVATE void sqlite3StatusAdd(int op, int N){ +SQLITE_PRIVATE void sqlite3StatusUp(int op, int N){ wsdStatInit; assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); + assert( op>=0 && op<ArraySize(statMutex) ); + assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex() + : sqlite3MallocMutex()) ); wsdStat.nowValue[op] += N; if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){ wsdStat.mxValue[op] = wsdStat.nowValue[op]; } } +SQLITE_PRIVATE void sqlite3StatusDown(int op, int N){ + wsdStatInit; + assert( N>=0 ); + assert( op>=0 && op<ArraySize(statMutex) ); + assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex() + : sqlite3MallocMutex()) ); + assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); + wsdStat.nowValue[op] -= N; +} /* -** Set the value of a status to X. +** Set the value of a status to X. The highwater mark is adjusted if +** necessary. The caller must hold the appropriate mutex. */ SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){ wsdStatInit; assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); + assert( op>=0 && op<ArraySize(statMutex) ); + assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex() + : sqlite3MallocMutex()) ); wsdStat.nowValue[op] = X; if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){ wsdStat.mxValue[op] = wsdStat.nowValue[op]; @@ -14858,12 +15107,14 @@ SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){ /* ** Query status information. -** -** This implementation assumes that reading or writing an aligned -** 32-bit integer is an atomic operation. If that assumption is not true, -** then this routine is not threadsafe. */ -SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ +SQLITE_API int SQLITE_STDCALL sqlite3_status64( + int op, + sqlite3_int64 *pCurrent, + sqlite3_int64 *pHighwater, + int resetFlag +){ + sqlite3_mutex *pMutex; wsdStatInit; if( op<0 || op>=ArraySize(wsdStat.nowValue) ){ return SQLITE_MISUSE_BKPT; @@ -14871,18 +15122,35 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF #ifdef SQLITE_ENABLE_API_ARMOR if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT; #endif + pMutex = statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex(); + sqlite3_mutex_enter(pMutex); *pCurrent = wsdStat.nowValue[op]; *pHighwater = wsdStat.mxValue[op]; if( resetFlag ){ wsdStat.mxValue[op] = wsdStat.nowValue[op]; } + sqlite3_mutex_leave(pMutex); + (void)pMutex; /* Prevent warning when SQLITE_THREADSAFE=0 */ return SQLITE_OK; } +SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ + sqlite3_int64 iCur, iHwtr; + int rc; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT; +#endif + rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag); + if( rc==0 ){ + *pCurrent = (int)iCur; + *pHighwater = (int)iHwtr; + } + return rc; +} /* ** Query status information for a single database connection */ -SQLITE_API int sqlite3_db_status( +SQLITE_API int SQLITE_STDCALL sqlite3_db_status( sqlite3 *db, /* The database connection whose status is desired */ int op, /* Status verb */ int *pCurrent, /* Write current value here */ @@ -16511,7 +16779,7 @@ static sqlite3_vfs * SQLITE_WSD vfsList = 0; ** Locate a VFS by name. If no name is given, simply return the ** first VFS on the list. */ -SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){ +SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfs){ sqlite3_vfs *pVfs = 0; #if SQLITE_THREADSAFE sqlite3_mutex *mutex; @@ -16557,7 +16825,7 @@ static void vfsUnlink(sqlite3_vfs *pVfs){ ** VFS multiple times. The new VFS becomes the default if makeDflt is ** true. */ -SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ +SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ MUTEX_LOGIC(sqlite3_mutex *mutex;) #ifndef SQLITE_OMIT_AUTOINIT int rc = sqlite3_initialize(); @@ -16585,7 +16853,7 @@ SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ /* ** Unregister a VFS so that it is no longer accessible. */ -SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ +SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ #if SQLITE_THREADSAFE sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); #endif @@ -18921,7 +19189,7 @@ SQLITE_PRIVATE int sqlite3MutexEnd(void){ /* ** Retrieve a pointer to a static mutex or allocate a new dynamic one. */ -SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){ +SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int id){ #ifndef SQLITE_OMIT_AUTOINIT if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0; if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0; @@ -18940,7 +19208,7 @@ SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){ /* ** Free a dynamic mutex. */ -SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){ +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex *p){ if( p ){ sqlite3GlobalConfig.mutex.xMutexFree(p); } @@ -18950,7 +19218,7 @@ SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){ ** Obtain the mutex p. If some other thread already has the mutex, block ** until it can be obtained. */ -SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){ +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex *p){ if( p ){ sqlite3GlobalConfig.mutex.xMutexEnter(p); } @@ -18960,7 +19228,7 @@ SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){ ** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another ** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY. */ -SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){ +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex *p){ int rc = SQLITE_OK; if( p ){ return sqlite3GlobalConfig.mutex.xMutexTry(p); @@ -18974,7 +19242,7 @@ SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){ ** is not currently entered. If a NULL pointer is passed as an argument ** this function is a no-op. */ -SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){ +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex *p){ if( p ){ sqlite3GlobalConfig.mutex.xMutexLeave(p); } @@ -18985,10 +19253,10 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){ ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are ** intended for use inside assert() statements. */ -SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){ +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex *p){ return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p); } -SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex *p){ return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p); } #endif @@ -19118,8 +19386,12 @@ static sqlite3_mutex *debugMutexAlloc(int id){ break; } default: { - assert( id-2 >= 0 ); - assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) ); +#ifdef SQLITE_ENABLE_API_ARMOR + if( id-2<0 || id-2>=ArraySize(aStatic) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif pNew = &aStatic[id-2]; pNew->id = id; break; @@ -19134,8 +19406,13 @@ static sqlite3_mutex *debugMutexAlloc(int id){ static void debugMutexFree(sqlite3_mutex *pX){ sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; assert( p->cnt==0 ); - assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); - sqlite3_free(p); + if( p->id==SQLITE_MUTEX_RECURSIVE || p->id==SQLITE_MUTEX_FAST ){ + sqlite3_free(p); + }else{ +#ifdef SQLITE_ENABLE_API_ARMOR + (void)SQLITE_MISUSE_BKPT; +#endif + } } /* @@ -19246,8 +19523,10 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ */ struct sqlite3_mutex { pthread_mutex_t mutex; /* Mutex controlling the lock */ -#if SQLITE_MUTEX_NREF +#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) int id; /* Mutex type */ +#endif +#if SQLITE_MUTEX_NREF volatile int nRef; /* Number of entrances */ volatile pthread_t owner; /* Thread that is within this mutex */ int trace; /* True to trace changes */ @@ -19363,9 +19642,6 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){ pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&p->mutex, &recursiveAttr); pthread_mutexattr_destroy(&recursiveAttr); -#endif -#if SQLITE_MUTEX_NREF - p->id = iType; #endif } break; @@ -19373,9 +19649,6 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){ case SQLITE_MUTEX_FAST: { p = sqlite3MallocZero( sizeof(*p) ); if( p ){ -#if SQLITE_MUTEX_NREF - p->id = iType; -#endif pthread_mutex_init(&p->mutex, 0); } break; @@ -19388,12 +19661,12 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){ } #endif p = &staticMutexes[iType-2]; -#if SQLITE_MUTEX_NREF - p->id = iType; -#endif break; } } +#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) + if( p ) p->id = iType; +#endif return p; } @@ -19405,9 +19678,18 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){ */ static void pthreadMutexFree(sqlite3_mutex *p){ assert( p->nRef==0 ); - assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); - pthread_mutex_destroy(&p->mutex); - sqlite3_free(p); +#if SQLITE_ENABLE_API_ARMOR + if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ) +#endif + { + pthread_mutex_destroy(&p->mutex); + sqlite3_free(p); + } +#ifdef SQLITE_ENABLE_API_ARMOR + else{ + (void)SQLITE_MISUSE_BKPT; + } +#endif } /* @@ -19619,16 +19901,6 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." #endif -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) -# ifndef SQLITE_DEBUG_OS_TRACE -# define SQLITE_DEBUG_OS_TRACE 0 -# endif - int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; -# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X -#else -# define OSTRACE(X) -#endif - /* ** Macros for performance tracing. Normally turned off. Only works ** on i486 hardware. @@ -19877,6 +20149,17 @@ SQLITE_API int sqlite3_open_file_count = 0; # define SQLITE_WIN32_VOLATILE volatile #endif +/* +** For some Windows sub-platforms, the _beginthreadex() / _endthreadex() +** functions are not available (e.g. those not using MSVC, Cygwin, etc). +*/ +#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ + SQLITE_THREADSAFE>0 && !defined(__CYGWIN__) +# define SQLITE_OS_WIN_THREADS 1 +#else +# define SQLITE_OS_WIN_THREADS 0 +#endif + #endif /* _OS_WIN_H_ */ /************** End of os_win.h **********************************************/ @@ -19959,8 +20242,8 @@ static int winMutex_isNt = -1; /* <0 means "need to query" */ */ static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0; -SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */ -SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ +SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void); /* os_win.c */ +SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ static int winMutexInit(void){ /* The first to increment to 1 does actual initialization */ @@ -20052,8 +20335,8 @@ static sqlite3_mutex *winMutexAlloc(int iType){ case SQLITE_MUTEX_RECURSIVE: { p = sqlite3MallocZero( sizeof(*p) ); if( p ){ -#ifdef SQLITE_DEBUG p->id = iType; +#ifdef SQLITE_DEBUG #ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC p->trace = 1; #endif @@ -20073,12 +20356,9 @@ static sqlite3_mutex *winMutexAlloc(int iType){ return 0; } #endif - assert( iType-2 >= 0 ); - assert( iType-2 < ArraySize(winMutex_staticMutexes) ); - assert( winMutex_isInit==1 ); p = &winMutex_staticMutexes[iType-2]; -#ifdef SQLITE_DEBUG p->id = iType; +#ifdef SQLITE_DEBUG #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC p->trace = 1; #endif @@ -20097,13 +20377,15 @@ static sqlite3_mutex *winMutexAlloc(int iType){ */ static void winMutexFree(sqlite3_mutex *p){ assert( p ); -#ifdef SQLITE_DEBUG assert( p->nRef==0 && p->owner==0 ); - assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); + if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){ + DeleteCriticalSection(&p->mutex); + sqlite3_free(p); + }else{ +#ifdef SQLITE_ENABLE_API_ARMOR + (void)SQLITE_MISUSE_BKPT; #endif - assert( winMutex_isInit==1 ); - DeleteCriticalSection(&p->mutex); - sqlite3_free(p); + } } /* @@ -20257,7 +20539,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ ** held by SQLite. An example of non-essential memory is memory used to ** cache database pages that are not currently in use. */ -SQLITE_API int sqlite3_release_memory(int n){ +SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int n){ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT return sqlite3PcacheReleaseMemory(n); #else @@ -20312,6 +20594,13 @@ static SQLITE_WSD struct Mem0Global { #define mem0 GLOBAL(struct Mem0Global, mem0) +/* +** Return the memory allocator mutex. sqlite3_status() needs it. +*/ +SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void){ + return mem0.mutex; +} + /* ** This routine runs when the memory allocator sees that the ** total memory allocation is about to exceed the soft heap @@ -20334,7 +20623,7 @@ static int sqlite3MemoryAlarm( void *pArg, sqlite3_int64 iThreshold ){ - int nUsed; + sqlite3_int64 nUsed; sqlite3_mutex_enter(mem0.mutex); mem0.alarmCallback = xCallback; mem0.alarmArg = pArg; @@ -20350,7 +20639,7 @@ static int sqlite3MemoryAlarm( ** Deprecated external interface. Internal/core SQLite code ** should call sqlite3MemoryAlarm. */ -SQLITE_API int sqlite3_memory_alarm( +SQLITE_API int SQLITE_STDCALL sqlite3_memory_alarm( void(*xCallback)(void *pArg, sqlite3_int64 used,int N), void *pArg, sqlite3_int64 iThreshold @@ -20363,7 +20652,7 @@ SQLITE_API int sqlite3_memory_alarm( ** Set the soft heap-size limit for the library. Passing a zero or ** negative value indicates no limit. */ -SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){ +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 n){ sqlite3_int64 priorLimit; sqlite3_int64 excess; #ifndef SQLITE_OMIT_AUTOINIT @@ -20383,7 +20672,7 @@ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){ if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff)); return priorLimit; } -SQLITE_API void sqlite3_soft_heap_limit(int n){ +SQLITE_API void SQLITE_STDCALL sqlite3_soft_heap_limit(int n){ if( n<0 ) n = 0; sqlite3_soft_heap_limit64(n); } @@ -20392,6 +20681,7 @@ SQLITE_API void sqlite3_soft_heap_limit(int n){ ** Initialize the memory allocation subsystem. */ SQLITE_PRIVATE int sqlite3MallocInit(void){ + int rc; if( sqlite3GlobalConfig.m.xMalloc==0 ){ sqlite3MemSetDefault(); } @@ -20427,7 +20717,9 @@ SQLITE_PRIVATE int sqlite3MallocInit(void){ sqlite3GlobalConfig.szPage = 0; sqlite3GlobalConfig.nPage = 0; } - return sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData); + rc = sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData); + if( rc!=SQLITE_OK ) memset(&mem0, 0, sizeof(mem0)); + return rc; } /* @@ -20452,7 +20744,7 @@ SQLITE_PRIVATE void sqlite3MallocEnd(void){ /* ** Return the amount of memory currently checked out. */ -SQLITE_API sqlite3_int64 sqlite3_memory_used(void){ +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void){ int n, mx; sqlite3_int64 res; sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0); @@ -20465,7 +20757,7 @@ SQLITE_API sqlite3_int64 sqlite3_memory_used(void){ ** checked out since either the beginning of this process ** or since the most recent reset. */ -SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){ +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag){ int n, mx; sqlite3_int64 res; sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag); @@ -20503,7 +20795,7 @@ static int mallocWithAlarm(int n, void **pp){ nFull = sqlite3GlobalConfig.m.xRoundup(n); sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n); if( mem0.alarmCallback!=0 ){ - int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); if( nUsed >= mem0.alarmThreshold - nFull ){ mem0.nearlyFull = 1; sqlite3MallocAlarm(nFull); @@ -20520,8 +20812,8 @@ static int mallocWithAlarm(int n, void **pp){ #endif if( p ){ nFull = sqlite3MallocSize(p); - sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull); - sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1); + sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull); + sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1); } *pp = p; return nFull; @@ -20556,13 +20848,13 @@ SQLITE_PRIVATE void *sqlite3Malloc(u64 n){ ** First make sure the memory subsystem is initialized, then do the ** allocation. */ -SQLITE_API void *sqlite3_malloc(int n){ +SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int n){ #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif return n<=0 ? 0 : sqlite3Malloc(n); } -SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){ +SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64 n){ #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif @@ -20598,14 +20890,14 @@ SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){ p = mem0.pScratchFree; mem0.pScratchFree = mem0.pScratchFree->pNext; mem0.nScratchFree--; - sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1); + sqlite3StatusUp(SQLITE_STATUS_SCRATCH_USED, 1); sqlite3_mutex_leave(mem0.mutex); }else{ sqlite3_mutex_leave(mem0.mutex); p = sqlite3Malloc(n); if( sqlite3GlobalConfig.bMemstat && p ){ sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p)); + sqlite3StatusUp(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p)); sqlite3_mutex_leave(mem0.mutex); } sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH); @@ -20646,19 +20938,19 @@ SQLITE_PRIVATE void sqlite3ScratchFree(void *p){ mem0.pScratchFree = pSlot; mem0.nScratchFree++; assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch ); - sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1); + sqlite3StatusDown(SQLITE_STATUS_SCRATCH_USED, 1); sqlite3_mutex_leave(mem0.mutex); }else{ /* Release memory back to the heap */ assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); - assert( sqlite3MemdebugNoType(p, ~MEMTYPE_SCRATCH) ); + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); if( sqlite3GlobalConfig.bMemstat ){ int iSize = sqlite3MallocSize(p); sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, -iSize); - sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize); - sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1); + sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize); + sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize); + sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); sqlite3GlobalConfig.m.xFree(p); sqlite3_mutex_leave(mem0.mutex); }else{ @@ -20689,7 +20981,7 @@ SQLITE_PRIVATE int sqlite3MallocSize(void *p){ } SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){ if( db==0 ){ - assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); return sqlite3MallocSize(p); }else{ @@ -20698,13 +20990,13 @@ SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){ return db->lookaside.sz; }else{ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); return sqlite3GlobalConfig.m.xSize(p); } } } -SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){ - assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) ); +SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void *p){ + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p); } @@ -20712,14 +21004,14 @@ SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){ /* ** Free memory previously obtained from sqlite3Malloc(). */ -SQLITE_API void sqlite3_free(void *p){ +SQLITE_API void SQLITE_STDCALL sqlite3_free(void *p){ if( p==0 ) return; /* IMP: R-49053-54554 */ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); - assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p)); - sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1); + sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p)); + sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); sqlite3GlobalConfig.m.xFree(p); sqlite3_mutex_leave(mem0.mutex); }else{ @@ -20760,7 +21052,7 @@ SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ } } assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); sqlite3_free(p); @@ -20773,7 +21065,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ int nOld, nNew, nDiff; void *pNew; assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); - assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(pOld, (u8)~MEMTYPE_HEAP) ); if( pOld==0 ){ return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */ } @@ -20807,7 +21099,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ } if( pNew ){ nNew = sqlite3MallocSize(pNew); - sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld); + sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld); } sqlite3_mutex_leave(mem0.mutex); }else{ @@ -20821,14 +21113,14 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ ** The public interface to sqlite3Realloc. Make sure that the memory ** subsystem is initialized prior to invoking sqliteRealloc. */ -SQLITE_API void *sqlite3_realloc(void *pOld, int n){ +SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void *pOld, int n){ #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif if( n<0 ) n = 0; /* IMP: R-26507-47431 */ return sqlite3Realloc(pOld, n); } -SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){ +SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void *pOld, sqlite3_uint64 n){ #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif @@ -20940,7 +21232,7 @@ SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ } }else{ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); pNew = sqlite3_realloc64(p, n); if( !pNew ){ @@ -21193,6 +21485,7 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ ** Set the StrAccum object to an error mode. */ static void setStrAccumError(StrAccum *p, u8 eError){ + assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG ); p->accError = eError; p->nAlloc = 0; } @@ -21267,13 +21560,6 @@ SQLITE_PRIVATE void sqlite3VXPrintf( PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */ char buf[etBUFSIZE]; /* Conversion buffer */ -#ifdef SQLITE_ENABLE_API_ARMOR - if( ap==0 ){ - (void)SQLITE_MISUSE_BKPT; - sqlite3StrAccumReset(pAccum); - return; - } -#endif bufpt = 0; if( bFlags ){ if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){ @@ -21314,7 +21600,6 @@ SQLITE_PRIVATE void sqlite3VXPrintf( } }while( !done && (c=(*++fmt))!=0 ); /* Get the field width */ - width = 0; if( c=='*' ){ if( bArgList ){ width = (int)getIntArg(pArgList); @@ -21323,18 +21608,21 @@ SQLITE_PRIVATE void sqlite3VXPrintf( } if( width<0 ){ flag_leftjustify = 1; - width = -width; + width = width >= -2147483647 ? -width : 0; } c = *++fmt; }else{ + unsigned wx = 0; while( c>='0' && c<='9' ){ - width = width*10 + c - '0'; + wx = wx*10 + c - '0'; c = *++fmt; } + testcase( wx>0x7fffffff ); + width = wx & 0x7fffffff; } + /* Get the precision */ if( c=='.' ){ - precision = 0; c = *++fmt; if( c=='*' ){ if( bArgList ){ @@ -21342,13 +21630,18 @@ SQLITE_PRIVATE void sqlite3VXPrintf( }else{ precision = va_arg(ap,int); } - if( precision<0 ) precision = -precision; c = *++fmt; + if( precision<0 ){ + precision = precision >= -2147483647 ? -precision : -1; + } }else{ + unsigned px = 0; while( c>='0' && c<='9' ){ - precision = precision*10 + c - '0'; + px = px*10 + c - '0'; c = *++fmt; } + testcase( px>0x7fffffff ); + precision = px & 0x7fffffff; } }else{ precision = -1; @@ -21512,7 +21805,8 @@ SQLITE_PRIVATE void sqlite3VXPrintf( else prefix = 0; } if( xtype==etGENERIC && precision>0 ) precision--; - for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){} + testcase( precision>0xfff ); + for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){} if( xtype==etFLOAT ) realvalue += rounder; /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ exp = 0; @@ -21567,8 +21861,9 @@ SQLITE_PRIVATE void sqlite3VXPrintf( }else{ e2 = exp; } - if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){ - bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 ); + if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){ + bufpt = zExtra + = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 ); if( bufpt==0 ){ setStrAccumError(pAccum, STRACCUM_NOMEM); return; @@ -21800,13 +22095,13 @@ SQLITE_PRIVATE void sqlite3VXPrintf( */ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ char *zNew; - assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */ + assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */ if( p->accError ){ testcase(p->accError==STRACCUM_TOOBIG); testcase(p->accError==STRACCUM_NOMEM); return 0; } - if( !p->useMalloc ){ + if( p->mxAlloc==0 ){ N = p->nAlloc - p->nChar - 1; setStrAccumError(p, STRACCUM_TOOBIG); return N; @@ -21826,10 +22121,10 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ }else{ p->nAlloc = (int)szNew; } - if( p->useMalloc==1 ){ + if( p->db ){ zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc); }else{ - zNew = sqlite3_realloc(zOld, p->nAlloc); + zNew = sqlite3_realloc64(zOld, p->nAlloc); } if( zNew ){ assert( p->zText!=0 || p->nChar==0 ); @@ -21849,7 +22144,10 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ ** Append N copies of character c to the given string buffer. */ SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){ - if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return; + testcase( p->nChar + (i64)N > 0x7fffffff ); + if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ + return; + } while( (N--)>0 ) p->zText[p->nChar++] = c; } @@ -21874,7 +22172,7 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ ** size of the memory allocation for StrAccum if necessary. */ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ - assert( z!=0 ); + assert( z!=0 || N==0 ); assert( p->zText!=0 || p->nChar==0 || p->accError ); assert( N>=0 ); assert( p->accError==0 || p->nAlloc==0 ); @@ -21903,12 +22201,8 @@ SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ if( p->zText ){ p->zText[p->nChar] = 0; - if( p->useMalloc && p->zText==p->zBase ){ - if( p->useMalloc==1 ){ - p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); - }else{ - p->zText = sqlite3_malloc(p->nChar+1); - } + if( p->mxAlloc>0 && p->zText==p->zBase ){ + p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); if( p->zText ){ memcpy(p->zText, p->zBase, p->nChar+1); }else{ @@ -21924,25 +22218,31 @@ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ */ SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){ if( p->zText!=p->zBase ){ - if( p->useMalloc==1 ){ - sqlite3DbFree(p->db, p->zText); - }else{ - sqlite3_free(p->zText); - } + sqlite3DbFree(p->db, p->zText); } p->zText = 0; } /* -** Initialize a string accumulator +** Initialize a string accumulator. +** +** p: The accumulator to be initialized. +** db: Pointer to a database connection. May be NULL. Lookaside +** memory is used if not NULL. db->mallocFailed is set appropriately +** when not NULL. +** zBase: An initial buffer. May be NULL in which case the initial buffer +** is malloced. +** n: Size of zBase in bytes. If total space requirements never exceed +** n then no memory allocations ever occur. +** mx: Maximum number of bytes to accumulate. If mx==0 then no memory +** allocations will ever occur. */ -SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){ +SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){ p->zText = p->zBase = zBase; - p->db = 0; + p->db = db; p->nChar = 0; p->nAlloc = n; p->mxAlloc = mx; - p->useMalloc = 1; p->accError = 0; } @@ -21955,9 +22255,8 @@ SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list a char zBase[SQLITE_PRINT_BUF_SIZE]; StrAccum acc; assert( db!=0 ); - sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), + sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase), db->aLimit[SQLITE_LIMIT_LENGTH]); - acc.db = db; sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap); z = sqlite3StrAccumFinish(&acc); if( acc.accError==STRACCUM_NOMEM ){ @@ -22001,7 +22300,7 @@ SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zForma ** Print into memory obtained from sqlite3_malloc(). Omit the internal ** %-conversion extensions. */ -SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){ +SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char *zFormat, va_list ap){ char *z; char zBase[SQLITE_PRINT_BUF_SIZE]; StrAccum acc; @@ -22015,8 +22314,7 @@ SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){ #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif - sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); - acc.useMalloc = 2; + sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); sqlite3VXPrintf(&acc, 0, zFormat, ap); z = sqlite3StrAccumFinish(&acc); return z; @@ -22026,7 +22324,7 @@ SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){ ** Print into memory obtained from sqlite3_malloc()(). Omit the internal ** %-conversion extensions. */ -SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){ +SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char *zFormat, ...){ va_list ap; char *z; #ifndef SQLITE_OMIT_AUTOINIT @@ -22051,22 +22349,21 @@ SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){ ** ** sqlite3_vsnprintf() is the varargs version. */ -SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ +SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ StrAccum acc; if( n<=0 ) return zBuf; #ifdef SQLITE_ENABLE_API_ARMOR if( zBuf==0 || zFormat==0 ) { (void)SQLITE_MISUSE_BKPT; - if( zBuf && n>0 ) zBuf[0] = 0; + if( zBuf ) zBuf[0] = 0; return zBuf; } #endif - sqlite3StrAccumInit(&acc, zBuf, n, 0); - acc.useMalloc = 0; + sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); sqlite3VXPrintf(&acc, 0, zFormat, ap); return sqlite3StrAccumFinish(&acc); } -SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ +SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ char *z; va_list ap; va_start(ap,zFormat); @@ -22088,8 +22385,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ StrAccum acc; /* String accumulator */ char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ - sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0); - acc.useMalloc = 0; + sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); sqlite3VXPrintf(&acc, 0, zFormat, ap); sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, sqlite3StrAccumFinish(&acc)); @@ -22098,7 +22394,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ /* ** Format and write a message to the log if logging is enabled. */ -SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){ +SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...){ va_list ap; /* Vararg list */ if( sqlite3GlobalConfig.xLog ){ va_start(ap, zFormat); @@ -22107,7 +22403,7 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){ } } -#if defined(SQLITE_DEBUG) +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) /* ** A version of printf() that understands %lld. Used for debugging. ** The printf() built into some versions of windows does not understand %lld @@ -22117,8 +22413,7 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){ va_list ap; StrAccum acc; char zBuf[500]; - sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0); - acc.useMalloc = 0; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); va_start(ap,zFormat); sqlite3VXPrintf(&acc, 0, zFormat, ap); va_end(ap); @@ -22145,7 +22440,7 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){ ** is not the last item in the tree. */ SQLITE_PRIVATE TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){ if( p==0 ){ - p = sqlite3_malloc( sizeof(*p) ); + p = sqlite3_malloc64( sizeof(*p) ); if( p==0 ) return 0; memset(p, 0, sizeof(*p)); }else{ @@ -22168,8 +22463,7 @@ SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ int i; StrAccum acc; char zBuf[500]; - sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0); - acc.useMalloc = 0; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); if( p ){ for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){ sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4); @@ -22234,7 +22528,7 @@ static SQLITE_WSD struct sqlite3PrngType { /* ** Return N random bytes. */ -SQLITE_API void sqlite3_randomness(int N, void *pBuf){ +SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *pBuf){ unsigned char t; unsigned char *zBuf = pBuf; @@ -22440,7 +22734,7 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ /********************************* Win32 Threads ****************************/ -#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0 +#if SQLITE_OS_WIN_THREADS #define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ #include <process.h> @@ -22533,7 +22827,7 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR; } -#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT */ +#endif /* SQLITE_OS_WIN_THREADS */ /******************************** End Win32 Threads *************************/ @@ -23386,7 +23680,7 @@ SQLITE_PRIVATE int sqlite3Dequote(char *z){ ** case-independent fashion, using the same definition of "case ** independence" that SQLite uses internally when comparing identifiers. */ -SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){ +SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *zLeft, const char *zRight){ register unsigned char *a, *b; if( zLeft==0 ){ return zRight ? -1 : 0; @@ -23398,7 +23692,7 @@ SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){ while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } return UpperToLower[*a] - UpperToLower[*b]; } -SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ +SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ register unsigned char *a, *b; if( zLeft==0 ){ return zRight ? -1 : 0; @@ -23792,6 +24086,7 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){ } } #endif + while( zNum[0]=='0' ) zNum++; for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ v = v*10 + c; } @@ -24929,23 +25224,25 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 136 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), /* 137 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), /* 138 */ "IfNeg" OpHelp("r[P1]+=P3, if r[P1]<0 goto P2"), - /* 139 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), - /* 140 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), - /* 141 */ "IncrVacuum" OpHelp(""), - /* 142 */ "Expire" OpHelp(""), - /* 143 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), - /* 144 */ "VBegin" OpHelp(""), - /* 145 */ "VCreate" OpHelp(""), - /* 146 */ "VDestroy" OpHelp(""), - /* 147 */ "VOpen" OpHelp(""), - /* 148 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), - /* 149 */ "VNext" OpHelp(""), - /* 150 */ "VRename" OpHelp(""), - /* 151 */ "Pagecount" OpHelp(""), - /* 152 */ "MaxPgcnt" OpHelp(""), - /* 153 */ "Init" OpHelp("Start at P2"), - /* 154 */ "Noop" OpHelp(""), - /* 155 */ "Explain" OpHelp(""), + /* 139 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]+=P3, goto P2"), + /* 140 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), + /* 141 */ "JumpZeroIncr" OpHelp("if (r[P1]++)==0 ) goto P2"), + /* 142 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 143 */ "IncrVacuum" OpHelp(""), + /* 144 */ "Expire" OpHelp(""), + /* 145 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), + /* 146 */ "VBegin" OpHelp(""), + /* 147 */ "VCreate" OpHelp(""), + /* 148 */ "VDestroy" OpHelp(""), + /* 149 */ "VOpen" OpHelp(""), + /* 150 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 151 */ "VNext" OpHelp(""), + /* 152 */ "VRename" OpHelp(""), + /* 153 */ "Pagecount" OpHelp(""), + /* 154 */ "MaxPgcnt" OpHelp(""), + /* 155 */ "Init" OpHelp("Start at P2"), + /* 156 */ "Noop" OpHelp(""), + /* 157 */ "Explain" OpHelp(""), }; return azName[i]; } @@ -25025,18 +25322,6 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ # endif #endif -/* -** Define the OS_VXWORKS pre-processor macro to 1 if building on -** vxworks, or 0 otherwise. -*/ -#ifndef OS_VXWORKS -# if defined(__RTP__) || defined(_WRS_KERNEL) -# define OS_VXWORKS 1 -# else -# define OS_VXWORKS 0 -# endif -#endif - /* ** standard include files. */ @@ -25051,18 +25336,30 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ # include <sys/mman.h> #endif -#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS +#if SQLITE_ENABLE_LOCKING_STYLE # include <sys/ioctl.h> -# if OS_VXWORKS -# include <semaphore.h> -# include <limits.h> -# else -# include <sys/file.h> -# include <sys/param.h> -# endif +# include <sys/file.h> +# include <sys/param.h> #endif /* SQLITE_ENABLE_LOCKING_STYLE */ -#if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS) +#if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \ + (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000)) +# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \ + && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0)) +# define HAVE_GETHOSTUUID 1 +# else +# warning "gethostuuid() is disabled." +# endif +#endif + + +#if OS_VXWORKS +/* # include <sys/ioctl.h> */ +# include <semaphore.h> +# include <limits.h> +#endif /* OS_VXWORKS */ + +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE # include <sys/mount.h> #endif @@ -25103,6 +25400,10 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ */ #define MAX_PATHNAME 512 +/* Always cast the getpid() return type for compatibility with +** kernel modules in VxWorks. */ +#define osGetpid(X) (pid_t)getpid() + /* ** Only set the lastErrno if the error code is a real error and not ** a normal expected return code of SQLITE_BUSY or SQLITE_OK @@ -25191,7 +25492,7 @@ struct unixFile { ** method was called. If xOpen() is called from a different process id, ** indicating that a fork() has occurred, the PRNG will be reset. */ -static int randomnessPid = 0; +static pid_t randomnessPid = 0; /* ** Allowed values for the unixFile.ctrlFlags bitmask: @@ -25208,7 +25509,8 @@ static int randomnessPid = 0; #define UNIXFILE_DELETE 0x20 /* Delete on close */ #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ -#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings have been issued */ +#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings issued */ +#define UNIXFILE_BLOCK 0x0200 /* Next SHM lock might block */ /* ** Include code that is common to all os_*.c files @@ -25246,16 +25548,6 @@ static int randomnessPid = 0; # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." #endif -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) -# ifndef SQLITE_DEBUG_OS_TRACE -# define SQLITE_DEBUG_OS_TRACE 0 -# endif - int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; -# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X -#else -# define OSTRACE(X) -#endif - /* ** Macros for performance tracing. Normally turned off. Only works ** on i486 hardware. @@ -25547,7 +25839,7 @@ static struct unix_syscall { { "read", (sqlite3_syscall_ptr)read, 0 }, #define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent) -#if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS) +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE { "pread", (sqlite3_syscall_ptr)pread, 0 }, #else { "pread", (sqlite3_syscall_ptr)0, 0 }, @@ -25564,7 +25856,7 @@ static struct unix_syscall { { "write", (sqlite3_syscall_ptr)write, 0 }, #define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent) -#if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS) +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 }, #else { "pwrite", (sqlite3_syscall_ptr)0, 0 }, @@ -25798,7 +26090,7 @@ static int unixMutexHeld(void) { #endif -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +#ifdef SQLITE_HAVE_OS_TRACE /* ** Helper function for printing out trace information from debugging ** binaries. This returns the string representation of the supplied @@ -25879,9 +26171,9 @@ static int lockTrace(int fd, int op, struct flock *p){ /* ** Retry ftruncate() calls that fail due to EINTR ** -** All calls to ftruncate() within this file should be made through this wrapper. -** On the Android platform, bypassing the logic below could lead to a corrupt -** database. +** All calls to ftruncate() within this file should be made through +** this wrapper. On the Android platform, bypassing the logic below +** could lead to a corrupt database. */ static int robust_ftruncate(int h, sqlite3_int64 sz){ int rc; @@ -26061,7 +26353,7 @@ static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){ assert( zAbsoluteName[0]=='/' ); n = (int)strlen(zAbsoluteName); - pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) ); + pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) ); if( pNew==0 ) return 0; pNew->zCanonicalName = (char*)&pNew[1]; memcpy(pNew->zCanonicalName, zAbsoluteName, n+1); @@ -26340,6 +26632,14 @@ static void robust_close(unixFile *pFile, int h, int lineno){ } } +/* +** Set the pFile->lastErrno. Do this in a subroutine as that provides +** a convenient place to set a breakpoint. +*/ +static void storeLastErrno(unixFile *pFile, int error){ + pFile->lastErrno = error; +} + /* ** Close all file descriptors accumuated in the unixInodeInfo->pUnused list. */ @@ -26413,7 +26713,7 @@ static int findInodeInfo( fd = pFile->h; rc = osFstat(fd, &statbuf); if( rc!=0 ){ - pFile->lastErrno = errno; + storeLastErrno(pFile, errno); #ifdef EOVERFLOW if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS; #endif @@ -26434,12 +26734,12 @@ static int findInodeInfo( if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){ do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR ); if( rc!=1 ){ - pFile->lastErrno = errno; + storeLastErrno(pFile, errno); return SQLITE_IOERR; } rc = osFstat(fd, &statbuf); if( rc!=0 ){ - pFile->lastErrno = errno; + storeLastErrno(pFile, errno); return SQLITE_IOERR; } } @@ -26457,7 +26757,7 @@ static int findInodeInfo( pInode = pInode->pNext; } if( pInode==0 ){ - pInode = sqlite3_malloc( sizeof(*pInode) ); + pInode = sqlite3_malloc64( sizeof(*pInode) ); if( pInode==0 ){ return SQLITE_NOMEM; } @@ -26562,7 +26862,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ lock.l_type = F_WRLCK; if( osFcntl(pFile->h, F_GETLK, &lock) ){ rc = SQLITE_IOERR_CHECKRESERVEDLOCK; - pFile->lastErrno = errno; + storeLastErrno(pFile, errno); } else if( lock.l_type!=F_UNLCK ){ reserved = 1; } @@ -26695,7 +26995,8 @@ static int unixLock(sqlite3_file *id, int eFileLock){ assert( pFile ); OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h, azFileLock(eFileLock), azFileLock(pFile->eFileLock), - azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared , getpid())); + azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared, + osGetpid(0))); /* If there is already a lock of this type or more restrictive on the ** unixFile, do nothing. Don't use the end_lock: exit path, as @@ -26762,7 +27063,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( rc!=SQLITE_BUSY ){ - pFile->lastErrno = tErrno; + storeLastErrno(pFile, tErrno); } goto end_lock; } @@ -26797,7 +27098,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ if( rc ){ if( rc!=SQLITE_BUSY ){ - pFile->lastErrno = tErrno; + storeLastErrno(pFile, tErrno); } goto end_lock; }else{ @@ -26830,7 +27131,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( rc!=SQLITE_BUSY ){ - pFile->lastErrno = tErrno; + storeLastErrno(pFile, tErrno); } } } @@ -26903,7 +27204,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ assert( pFile ); OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock, pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, - getpid())); + osGetpid(0))); assert( eFileLock<=SHARED_LOCK ); if( pFile->eFileLock<=eFileLock ){ @@ -26937,7 +27238,6 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ ** 4: [RRRR.] */ if( eFileLock==SHARED_LOCK ){ - #if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE (void)handleNFSUnlock; assert( handleNFSUnlock==0 ); @@ -26955,7 +27255,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ tErrno = errno; rc = SQLITE_IOERR_UNLOCK; if( IS_LOCK_ERROR(rc) ){ - pFile->lastErrno = tErrno; + storeLastErrno(pFile, tErrno); } goto end_unlock; } @@ -26967,7 +27267,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); if( IS_LOCK_ERROR(rc) ){ - pFile->lastErrno = tErrno; + storeLastErrno(pFile, tErrno); } goto end_unlock; } @@ -26979,7 +27279,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ tErrno = errno; rc = SQLITE_IOERR_UNLOCK; if( IS_LOCK_ERROR(rc) ){ - pFile->lastErrno = tErrno; + storeLastErrno(pFile, tErrno); } goto end_unlock; } @@ -26998,7 +27298,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ ** SQLITE_BUSY would confuse the upper layer (in practice it causes ** an assert to fail). */ rc = SQLITE_IOERR_RDLOCK; - pFile->lastErrno = errno; + storeLastErrno(pFile, errno); goto end_unlock; } } @@ -27011,7 +27311,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ pInode->eFileLock = SHARED_LOCK; }else{ rc = SQLITE_IOERR_UNLOCK; - pFile->lastErrno = errno; + storeLastErrno(pFile, errno); goto end_unlock; } } @@ -27029,7 +27329,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ pInode->eFileLock = NO_LOCK; }else{ rc = SQLITE_IOERR_UNLOCK; - pFile->lastErrno = errno; + storeLastErrno(pFile, errno); pInode->eFileLock = NO_LOCK; pFile->eFileLock = NO_LOCK; } @@ -27304,7 +27604,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) { } else { rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( IS_LOCK_ERROR(rc) ){ - pFile->lastErrno = tErrno; + storeLastErrno(pFile, tErrno); } } return rc; @@ -27331,7 +27631,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) { assert( pFile ); OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock, - pFile->eFileLock, getpid())); + pFile->eFileLock, osGetpid(0))); assert( eFileLock<=SHARED_LOCK ); /* no-op if possible */ @@ -27358,7 +27658,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) { rc = SQLITE_IOERR_UNLOCK; } if( IS_LOCK_ERROR(rc) ){ - pFile->lastErrno = tErrno; + storeLastErrno(pFile, tErrno); } return rc; } @@ -27394,10 +27694,9 @@ static int dotlockClose(sqlite3_file *id) { ** still works when you do this, but concurrency is reduced since ** only a single process can be reading the database at a time. ** -** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if -** compiling for VXWORKS. +** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off */ -#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS +#if SQLITE_ENABLE_LOCKING_STYLE /* ** Retry flock() calls that fail with EINTR @@ -27445,7 +27744,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ /* unlock failed with an error */ lrc = SQLITE_IOERR_UNLOCK; if( IS_LOCK_ERROR(lrc) ){ - pFile->lastErrno = tErrno; + storeLastErrno(pFile, tErrno); rc = lrc; } } @@ -27455,7 +27754,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ /* someone else might have it reserved */ lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( IS_LOCK_ERROR(lrc) ){ - pFile->lastErrno = tErrno; + storeLastErrno(pFile, tErrno); rc = lrc; } } @@ -27521,7 +27820,7 @@ static int flockLock(sqlite3_file *id, int eFileLock) { /* didn't get, must be busy */ rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( IS_LOCK_ERROR(rc) ){ - pFile->lastErrno = tErrno; + storeLastErrno(pFile, tErrno); } } else { /* got it, set the type and return ok */ @@ -27550,7 +27849,7 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) { assert( pFile ); OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock, - pFile->eFileLock, getpid())); + pFile->eFileLock, osGetpid(0))); assert( eFileLock<=SHARED_LOCK ); /* no-op if possible */ @@ -27611,7 +27910,7 @@ static int flockClose(sqlite3_file *id) { ** to a non-zero value otherwise *pResOut is set to zero. The return value ** is set to SQLITE_OK unless an I/O error occurs during lock checking. */ -static int semCheckReservedLock(sqlite3_file *id, int *pResOut) { +static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) { int rc = SQLITE_OK; int reserved = 0; unixFile *pFile = (unixFile*)id; @@ -27633,7 +27932,7 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) { int tErrno = errno; if( EAGAIN != tErrno ){ rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK); - pFile->lastErrno = tErrno; + storeLastErrno(pFile, tErrno); } else { /* someone else has the lock when we are in NO_LOCK */ reserved = (pFile->eFileLock < SHARED_LOCK); @@ -27678,7 +27977,7 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) { ** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. */ -static int semLock(sqlite3_file *id, int eFileLock) { +static int semXLock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; sem_t *pSem = pFile->pInode->pSem; int rc = SQLITE_OK; @@ -27711,14 +28010,14 @@ static int semLock(sqlite3_file *id, int eFileLock) { ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int semUnlock(sqlite3_file *id, int eFileLock) { +static int semXUnlock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; sem_t *pSem = pFile->pInode->pSem; assert( pFile ); assert( pSem ); OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock, - pFile->eFileLock, getpid())); + pFile->eFileLock, osGetpid(0))); assert( eFileLock<=SHARED_LOCK ); /* no-op if possible */ @@ -27737,7 +28036,7 @@ static int semUnlock(sqlite3_file *id, int eFileLock) { int rc, tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); if( IS_LOCK_ERROR(rc) ){ - pFile->lastErrno = tErrno; + storeLastErrno(pFile, tErrno); } return rc; } @@ -27748,10 +28047,10 @@ static int semUnlock(sqlite3_file *id, int eFileLock) { /* ** Close a file. */ -static int semClose(sqlite3_file *id) { +static int semXClose(sqlite3_file *id) { if( id ){ unixFile *pFile = (unixFile*)id; - semUnlock(id, NO_LOCK); + semXUnlock(id, NO_LOCK); assert( pFile ); unixEnterMutex(); releaseInodeInfo(pFile); @@ -27839,7 +28138,7 @@ static int afpSetLock( setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK); #endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */ if( IS_LOCK_ERROR(rc) ){ - pFile->lastErrno = tErrno; + storeLastErrno(pFile, tErrno); } return rc; } else { @@ -27932,7 +28231,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){ assert( pFile ); OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h, azFileLock(eFileLock), azFileLock(pFile->eFileLock), - azFileLock(pInode->eFileLock), pInode->nShared , getpid())); + azFileLock(pInode->eFileLock), pInode->nShared , osGetpid(0))); /* If there is already a lock of this type or more restrictive on the ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as @@ -28022,7 +28321,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){ lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); if( IS_LOCK_ERROR(lrc1) ) { - pFile->lastErrno = lrc1Errno; + storeLastErrno(pFile, lrc1Errno); rc = lrc1; goto afp_end_lock; } else if( IS_LOCK_ERROR(lrc2) ){ @@ -28118,7 +28417,7 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { assert( pFile ); OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock, pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, - getpid())); + osGetpid(0))); assert( eFileLock<=SHARED_LOCK ); if( pFile->eFileLock<=eFileLock ){ @@ -28309,9 +28608,9 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ SimulateIOError( newOffset-- ); if( newOffset!=offset ){ if( newOffset == -1 ){ - ((unixFile*)id)->lastErrno = errno; + storeLastErrno((unixFile*)id, errno); }else{ - ((unixFile*)id)->lastErrno = 0; + storeLastErrno((unixFile*)id, 0); } return -1; } @@ -28321,7 +28620,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ if( got<0 ){ if( errno==EINTR ){ got = 1; continue; } prior = 0; - ((unixFile*)id)->lastErrno = errno; + storeLastErrno((unixFile*)id, errno); break; }else if( got>0 ){ cnt -= got; @@ -28386,7 +28685,7 @@ static int unixRead( /* lastErrno set by seekAndRead */ return SQLITE_IOERR_READ; }else{ - pFile->lastErrno = 0; /* not a system error */ + storeLastErrno(pFile, 0); /* not a system error */ /* Unread parts of the buffer must be zero-filled */ memset(&((char*)pBuf)[got], 0, amt-got); return SQLITE_IOERR_SHORT_READ; @@ -28415,9 +28714,9 @@ static int seekAndWriteFd( TIMER_START; #if defined(USE_PREAD) - do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); + do{ rc = (int)osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); #elif defined(USE_PREAD64) - do{ rc = osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR); + do{ rc = (int)osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR); #else do{ i64 iSeek = lseek(fd, iOff, SEEK_SET); @@ -28527,7 +28826,7 @@ static int unixWrite( /* lastErrno set by seekAndWrite */ return SQLITE_IOERR_WRITE; }else{ - pFile->lastErrno = 0; /* not a system error */ + storeLastErrno(pFile, 0); /* not a system error */ return SQLITE_FULL; } } @@ -28736,7 +29035,7 @@ static int unixSync(sqlite3_file *id, int flags){ rc = full_fsync(pFile->h, isFullsync, isDataOnly); SimulateIOError( rc=1 ); if( rc ){ - pFile->lastErrno = errno; + storeLastErrno(pFile, errno); return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath); } @@ -28780,7 +29079,7 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){ rc = robust_ftruncate(pFile->h, nByte); if( rc ){ - pFile->lastErrno = errno; + storeLastErrno(pFile, errno); return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); }else{ #ifdef SQLITE_DEBUG @@ -28820,7 +29119,7 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){ rc = osFstat(((unixFile*)id)->h, &buf); SimulateIOError( rc=1 ); if( rc!=0 ){ - ((unixFile*)id)->lastErrno = errno; + storeLastErrno((unixFile*)id, errno); return SQLITE_IOERR_FSTAT; } *pSize = buf.st_size; @@ -28856,7 +29155,9 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){ i64 nSize; /* Required file size */ struct stat buf; /* Used to hold return values of fstat() */ - if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT; + if( osFstat(pFile->h, &buf) ){ + return SQLITE_IOERR_FSTAT; + } nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk; if( nSize>(i64)buf.st_size ){ @@ -28903,7 +29204,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){ int rc; if( pFile->szChunk<=0 ){ if( robust_ftruncate(pFile->h, nByte) ){ - pFile->lastErrno = errno; + storeLastErrno(pFile, errno); return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); } } @@ -28941,11 +29242,15 @@ static int unixGetTempname(int nBuf, char *zBuf); static int unixFileControl(sqlite3_file *id, int op, void *pArg){ unixFile *pFile = (unixFile*)id; switch( op ){ + case SQLITE_FCNTL_WAL_BLOCK: { + /* pFile->ctrlFlags |= UNIXFILE_BLOCK; // Deferred feature */ + return SQLITE_OK; + } case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = pFile->eFileLock; return SQLITE_OK; } - case SQLITE_LAST_ERRNO: { + case SQLITE_FCNTL_LAST_ERRNO: { *(int*)pArg = pFile->lastErrno; return SQLITE_OK; } @@ -28973,7 +29278,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ return SQLITE_OK; } case SQLITE_FCNTL_TEMPFILENAME: { - char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname ); + char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname ); if( zTFile ){ unixGetTempname(pFile->pVfs->mxPathname, zTFile); *(char**)pArg = zTFile; @@ -29014,8 +29319,8 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ } #endif #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) - case SQLITE_SET_LOCKPROXYFILE: - case SQLITE_GET_LOCKPROXYFILE: { + case SQLITE_FCNTL_SET_LOCKPROXYFILE: + case SQLITE_FCNTL_GET_LOCKPROXYFILE: { return proxyFileControl(id,op,pArg); } #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ @@ -29155,7 +29460,9 @@ static int unixDeviceCharacteristics(sqlite3_file *id){ ** Instead, it should be called via macro osGetpagesize(). */ static int unixGetpagesize(void){ -#if defined(_BSD_SOURCE) +#if OS_VXWORKS + return 1024; +#elif defined(_BSD_SOURCE) return getpagesize(); #else return (int)sysconf(_SC_PAGESIZE); @@ -29248,15 +29555,17 @@ struct unixShm { ** otherwise. */ static int unixShmSystemLock( - unixShmNode *pShmNode, /* Apply locks to this open shared-memory segment */ + unixFile *pFile, /* Open connection to the WAL file */ int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */ int ofst, /* First byte of the locking range */ int n /* Number of bytes to lock */ ){ - struct flock f; /* The posix advisory locking structure */ - int rc = SQLITE_OK; /* Result code form fcntl() */ + unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */ + struct flock f; /* The posix advisory locking structure */ + int rc = SQLITE_OK; /* Result code form fcntl() */ /* Access to the unixShmNode object is serialized by the caller */ + pShmNode = pFile->pInode->pShmNode; assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 ); /* Shared locks never span more than one byte */ @@ -29266,6 +29575,7 @@ static int unixShmSystemLock( assert( n>=1 && n<SQLITE_SHM_NLOCK ); if( pShmNode->h>=0 ){ + int lkType; /* Initialize the locking parameters */ memset(&f, 0, sizeof(f)); f.l_type = lockType; @@ -29273,8 +29583,10 @@ static int unixShmSystemLock( f.l_start = ofst; f.l_len = n; - rc = osFcntl(pShmNode->h, F_SETLK, &f); + lkType = (pFile->ctrlFlags & UNIXFILE_BLOCK)!=0 ? F_SETLKW : F_SETLK; + rc = osFcntl(pShmNode->h, lkType, &f); rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; + pFile->ctrlFlags &= ~UNIXFILE_BLOCK; } /* Update the global lock state and do debug tracing */ @@ -29407,7 +29719,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ int nShmFilename; /* Size of the SHM filename in bytes */ /* Allocate space for the new unixShm object. */ - p = sqlite3_malloc( sizeof(*p) ); + p = sqlite3_malloc64( sizeof(*p) ); if( p==0 ) return SQLITE_NOMEM; memset(p, 0, sizeof(*p)); assert( pDbFd->pShm==0 ); @@ -29420,6 +29732,9 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ pShmNode = pInode->pShmNode; if( pShmNode==0 ){ struct stat sStat; /* fstat() info for database file */ +#ifndef SQLITE_SHM_DIRECTORY + const char *zBasePath = pDbFd->zPath; +#endif /* Call fstat() to figure out the permissions on the database file. If ** a new *-shm file is created, an attempt will be made to create it @@ -29433,9 +29748,9 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ #ifdef SQLITE_SHM_DIRECTORY nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31; #else - nShmFilename = 6 + (int)strlen(pDbFd->zPath); + nShmFilename = 6 + (int)strlen(zBasePath); #endif - pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename ); + pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename ); if( pShmNode==0 ){ rc = SQLITE_NOMEM; goto shm_open_err; @@ -29447,7 +29762,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x", (u32)sStat.st_ino, (u32)sStat.st_dev); #else - sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath); + sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath); sqlite3FileSuffix3(pDbFd->zPath, zShmFilename); #endif pShmNode->h = -1; @@ -29481,13 +29796,13 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ ** If not, truncate the file to zero length. */ rc = SQLITE_OK; - if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ + if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ if( robust_ftruncate(pShmNode->h, 0) ){ rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); } } if( rc==SQLITE_OK ){ - rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); + rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1); } if( rc ) goto shm_open_err; } @@ -29645,7 +29960,7 @@ static int unixShmMap( goto shmpage_out; } }else{ - pMem = sqlite3_malloc(szRegion); + pMem = sqlite3_malloc64(szRegion); if( pMem==0 ){ rc = SQLITE_NOMEM; goto shmpage_out; @@ -29719,7 +30034,7 @@ static int unixShmLock( /* Unlock the system-level locks */ if( (mask & allMask)==0 ){ - rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n); + rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); }else{ rc = SQLITE_OK; } @@ -29747,7 +30062,7 @@ static int unixShmLock( /* Get shared locks at the system level, if necessary */ if( rc==SQLITE_OK ){ if( (allShared & mask)==0 ){ - rc = unixShmSystemLock(pShmNode, F_RDLCK, ofst+UNIX_SHM_BASE, n); + rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); }else{ rc = SQLITE_OK; } @@ -29772,7 +30087,7 @@ static int unixShmLock( ** also mark the local connection as being locked. */ if( rc==SQLITE_OK ){ - rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n); + rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n); if( rc==SQLITE_OK ){ assert( (p->sharedMask & mask)==0 ); p->exclMask |= mask; @@ -29781,7 +30096,7 @@ static int unixShmLock( } sqlite3_mutex_leave(pShmNode->mutex); OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", - p->id, getpid(), p->sharedMask, p->exclMask)); + p->id, osGetpid(0), p->sharedMask, p->exclMask)); return rc; } @@ -29840,7 +30155,9 @@ static int unixShmUnmap( assert( pShmNode->nRef>0 ); pShmNode->nRef--; if( pShmNode->nRef==0 ){ - if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename); + if( deleteFlag && pShmNode->h>=0 ){ + osUnlink(pShmNode->zFilename); + } unixShmPurge(pDbFd); } unixLeaveMutex(); @@ -30117,7 +30434,7 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ ** * An I/O method finder function called FINDER that returns a pointer ** to the METHOD object in the previous bullet. */ -#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK, SHMMAP) \ +#define IOMETHODS(FINDER,METHOD,VERSION,CLOSE,LOCK,UNLOCK,CKLOCK,SHMMAP) \ static const sqlite3_io_methods METHOD = { \ VERSION, /* iVersion */ \ CLOSE, /* xClose */ \ @@ -30182,7 +30499,7 @@ IOMETHODS( 0 /* xShmMap method */ ) -#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS +#if SQLITE_ENABLE_LOCKING_STYLE IOMETHODS( flockIoFinder, /* Finder function name */ flockIoMethods, /* sqlite3_io_methods object name */ @@ -30200,10 +30517,10 @@ IOMETHODS( semIoFinder, /* Finder function name */ semIoMethods, /* sqlite3_io_methods object name */ 1, /* shared memory is disabled */ - semClose, /* xClose method */ - semLock, /* xLock method */ - semUnlock, /* xUnlock method */ - semCheckReservedLock, /* xCheckReservedLock method */ + semXClose, /* xClose method */ + semXLock, /* xLock method */ + semXUnlock, /* xUnlock method */ + semXCheckReservedLock, /* xCheckReservedLock method */ 0 /* xShmMap method */ ) #endif @@ -30327,15 +30644,13 @@ static const sqlite3_io_methods #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ -#if OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE -/* -** This "finder" function attempts to determine the best locking strategy -** for the database file "filePath". It then returns the sqlite3_io_methods -** object that implements that strategy. -** -** This is for VXWorks only. +#if OS_VXWORKS +/* +** This "finder" function for VxWorks checks to see if posix advisory +** locking works. If it does, then that is what is used. If it does not +** work, then fallback to named semaphore locking. */ -static const sqlite3_io_methods *autolockIoFinderImpl( +static const sqlite3_io_methods *vxworksIoFinderImpl( const char *filePath, /* name of the database file */ unixFile *pNew /* the open file object */ ){ @@ -30361,9 +30676,9 @@ static const sqlite3_io_methods *autolockIoFinderImpl( } } static const sqlite3_io_methods - *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; + *(*const vxworksIoFinder)(const char*,unixFile*) = vxworksIoFinderImpl; -#endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */ +#endif /* OS_VXWORKS */ /* ** An abstract type for a pointer to an IO method finder function: @@ -30482,7 +30797,7 @@ static int fillInUnixFile( ** the afpLockingContext. */ afpLockingContext *pCtx; - pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) ); + pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) ); if( pCtx==0 ){ rc = SQLITE_NOMEM; }else{ @@ -30512,7 +30827,7 @@ static int fillInUnixFile( int nFilename; assert( zFilename!=0 ); nFilename = (int)strlen(zFilename) + 6; - zLockFile = (char *)sqlite3_malloc(nFilename); + zLockFile = (char *)sqlite3_malloc64(nFilename); if( zLockFile==0 ){ rc = SQLITE_NOMEM; }else{ @@ -30545,7 +30860,7 @@ static int fillInUnixFile( } #endif - pNew->lastErrno = 0; + storeLastErrno(pNew, 0); #if OS_VXWORKS if( rc!=SQLITE_OK ){ if( h>=0 ) robust_close(pNew, h, __LINE__); @@ -30876,8 +31191,8 @@ static int unixOpen( ** the same instant might all reset the PRNG. But multiple resets ** are harmless. */ - if( randomnessPid!=getpid() ){ - randomnessPid = getpid(); + if( randomnessPid!=osGetpid(0) ){ + randomnessPid = osGetpid(0); sqlite3_randomness(0,0); } @@ -30889,7 +31204,7 @@ static int unixOpen( if( pUnused ){ fd = pUnused->fd; }else{ - pUnused = sqlite3_malloc(sizeof(*pUnused)); + pUnused = sqlite3_malloc64(sizeof(*pUnused)); if( !pUnused ){ return SQLITE_NOMEM; } @@ -30993,13 +31308,16 @@ static int unixOpen( #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE if( fstatfs(fd, &fsInfo) == -1 ){ - ((unixFile*)pFile)->lastErrno = errno; + storeLastErrno(p, errno); robust_close(p, fd, __LINE__); return SQLITE_IOERR_ACCESS; } if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) { ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; } + if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) { + ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; + } #endif /* Set up appropriate ctrlFlags */ @@ -31022,19 +31340,6 @@ static int unixOpen( if( envforce!=NULL ){ useProxy = atoi(envforce)>0; }else{ - if( statfs(zPath, &fsInfo) == -1 ){ - /* In theory, the close(fd) call is sub-optimal. If the file opened - ** with fd is a database file, and there are other connections open - ** on that file that are currently holding advisory locks on it, - ** then the call to close() will cancel those locks. In practice, - ** we're assuming that statfs() doesn't fail very often. At least - ** not while other file descriptors opened by the same process on - ** the same file are working. */ - p->lastErrno = errno; - robust_close(p, fd, __LINE__); - rc = SQLITE_IOERR_ACCESS; - goto open_finished; - } useProxy = !(fsInfo.f_flags&MNT_LOCAL); } if( useProxy ){ @@ -31278,8 +31583,8 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ ** tests repeatable. */ memset(zBuf, 0, nBuf); - randomnessPid = getpid(); -#if !defined(SQLITE_TEST) + randomnessPid = osGetpid(0); +#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) { int fd, got; fd = robust_open("/dev/urandom", O_RDONLY, 0); @@ -31460,9 +31765,10 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ ** ** C APIs ** -** sqlite3_file_control(db, dbname, SQLITE_SET_LOCKPROXYFILE, +** sqlite3_file_control(db, dbname, SQLITE_FCNTL_SET_LOCKPROXYFILE, ** <proxy_path> | ":auto:"); -** sqlite3_file_control(db, dbname, SQLITE_GET_LOCKPROXYFILE, &<proxy_path>); +** sqlite3_file_control(db, dbname, SQLITE_FCNTL_GET_LOCKPROXYFILE, +** &<proxy_path>); ** ** ** SQL pragmas @@ -31555,7 +31861,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ ** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will ** force proxy locking to be used for every database file opened, and 0 ** will force automatic proxy locking to be disabled for all database -** files (explicitly calling the SQLITE_SET_LOCKPROXYFILE pragma or +** files (explicitly calling the SQLITE_FCNTL_SET_LOCKPROXYFILE pragma or ** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING). */ @@ -31576,6 +31882,7 @@ struct proxyLockingContext { char *lockProxyPath; /* Name of the proxy lock file */ char *dbPath; /* Name of the open file */ int conchHeld; /* 1 if the conch is held, -1 if lockless */ + int nFails; /* Number of conch taking failures */ void *oldLockingContext; /* Original lockingcontext to restore on close */ sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */ }; @@ -31597,7 +31904,7 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ { if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){ OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n", - lPath, errno, getpid())); + lPath, errno, osGetpid(0))); return SQLITE_IOERR_LOCK; } len = strlcat(lPath, "sqliteplocks", maxLen); @@ -31619,7 +31926,7 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ } lPath[i+len]='\0'; strlcat(lPath, ":auto:", maxLen); - OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, getpid())); + OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, osGetpid(0))); return SQLITE_OK; } @@ -31646,7 +31953,7 @@ static int proxyCreateLockPath(const char *lockPath){ if( err!=EEXIST ) { OSTRACE(("CREATELOCKPATH FAILED creating %s, " "'%s' proxy lock path=%s pid=%d\n", - buf, strerror(err), lockPath, getpid())); + buf, strerror(err), lockPath, osGetpid(0))); return err; } } @@ -31655,7 +31962,7 @@ static int proxyCreateLockPath(const char *lockPath){ } buf[i] = lockPath[i]; } - OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, getpid())); + OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, osGetpid(0))); return 0; } @@ -31689,7 +31996,7 @@ static int proxyCreateUnixFile( if( pUnused ){ fd = pUnused->fd; }else{ - pUnused = sqlite3_malloc(sizeof(*pUnused)); + pUnused = sqlite3_malloc64(sizeof(*pUnused)); if( !pUnused ){ return SQLITE_NOMEM; } @@ -31722,7 +32029,7 @@ static int proxyCreateUnixFile( } } - pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew)); + pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew)); if( pNew==NULL ){ rc = SQLITE_NOMEM; goto end_create_proxy; @@ -31755,8 +32062,10 @@ SQLITE_API int sqlite3_hostid_num = 0; #define PROXY_HOSTIDLEN 16 /* conch file host id length */ +#ifdef HAVE_GETHOSTUUID /* Not always defined in the headers as it ought to be */ extern int gethostuuid(uuid_t id, const struct timespec *wait); +#endif /* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN ** bytes of writable memory. @@ -31764,10 +32073,9 @@ extern int gethostuuid(uuid_t id, const struct timespec *wait); static int proxyGetHostID(unsigned char *pHostID, int *pError){ assert(PROXY_HOSTIDLEN == sizeof(uuid_t)); memset(pHostID, 0, PROXY_HOSTIDLEN); -#if defined(__MAX_OS_X_VERSION_MIN_REQUIRED)\ - && __MAC_OS_X_VERSION_MIN_REQUIRED<1050 +#ifdef HAVE_GETHOSTUUID { - static const struct timespec timeout = {1, 0}; /* 1 sec timeout */ + struct timespec timeout = {1, 0}; /* 1 sec timeout */ if( gethostuuid(pHostID, &timeout) ){ int err = errno; if( pError ){ @@ -31882,7 +32190,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ */ struct stat buf; if( osFstat(conchFile->h, &buf) ){ - pFile->lastErrno = errno; + storeLastErrno(pFile, errno); return SQLITE_IOERR_LOCK; } @@ -31902,7 +32210,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ char tBuf[PROXY_MAXCONCHLEN]; int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0); if( len<0 ){ - pFile->lastErrno = errno; + storeLastErrno(pFile, errno); return SQLITE_IOERR_LOCK; } if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){ @@ -31922,7 +32230,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ if( 0==proxyBreakConchLock(pFile, myHostID) ){ rc = SQLITE_OK; if( lockType==EXCLUSIVE_LOCK ){ - rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK); + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK); } if( !rc ){ rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); @@ -31960,11 +32268,12 @@ static int proxyTakeConch(unixFile *pFile){ int forceNewLockPath = 0; OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h, - (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid())); + (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), + osGetpid(0))); rc = proxyGetHostID(myHostID, &pError); if( (rc&0xff)==SQLITE_IOERR ){ - pFile->lastErrno = pError; + storeLastErrno(pFile, pError); goto end_takeconch; } rc = proxyConchLock(pFile, myHostID, SHARED_LOCK); @@ -31975,7 +32284,7 @@ static int proxyTakeConch(unixFile *pFile){ readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN); if( readLen<0 ){ /* I/O error: lastErrno set by seekAndRead */ - pFile->lastErrno = conchFile->lastErrno; + storeLastErrno(pFile, conchFile->lastErrno); rc = SQLITE_IOERR_READ; goto end_takeconch; }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || @@ -32048,7 +32357,7 @@ static int proxyTakeConch(unixFile *pFile){ rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); } }else{ - rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK); + rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); } if( rc==SQLITE_OK ){ char writeBuffer[PROXY_MAXCONCHLEN]; @@ -32057,7 +32366,8 @@ static int proxyTakeConch(unixFile *pFile){ writeBuffer[0] = (char)PROXY_CONCHVERSION; memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN); if( pCtx->lockProxyPath!=NULL ){ - strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, MAXPATHLEN); + strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, + MAXPATHLEN); }else{ strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN); } @@ -32169,7 +32479,7 @@ static int proxyReleaseConch(unixFile *pFile){ conchFile = pCtx->conchFile; OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h, (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), - getpid())); + osGetpid(0))); if( pCtx->conchHeld>0 ){ rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); } @@ -32181,7 +32491,7 @@ static int proxyReleaseConch(unixFile *pFile){ /* ** Given the name of a database file, compute the name of its conch file. -** Store the conch filename in memory obtained from sqlite3_malloc(). +** Store the conch filename in memory obtained from sqlite3_malloc64(). ** Make *pConchPath point to the new name. Return SQLITE_OK on success ** or SQLITE_NOMEM if unable to obtain memory. ** @@ -32197,7 +32507,7 @@ static int proxyCreateConchPathname(char *dbPath, char **pConchPath){ /* Allocate space for the conch filename and initialize the name to ** the name of the original database file. */ - *pConchPath = conchPath = (char *)sqlite3_malloc(len + 8); + *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8); if( conchPath==0 ){ return SQLITE_NOMEM; } @@ -32269,7 +32579,8 @@ static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){ /* afp style keeps a reference to the db path in the filePath field ** of the struct */ assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); - strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, MAXPATHLEN); + strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, + MAXPATHLEN); } else #endif if( pFile->pMethod == &dotlockIoMethods ){ @@ -32310,9 +32621,9 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { } OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h, - (lockPath ? lockPath : ":auto:"), getpid())); + (lockPath ? lockPath : ":auto:"), osGetpid(0))); - pCtx = sqlite3_malloc( sizeof(*pCtx) ); + pCtx = sqlite3_malloc64( sizeof(*pCtx) ); if( pCtx==0 ){ return SQLITE_NOMEM; } @@ -32382,7 +32693,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { */ static int proxyFileControl(sqlite3_file *id, int op, void *pArg){ switch( op ){ - case SQLITE_GET_LOCKPROXYFILE: { + case SQLITE_FCNTL_GET_LOCKPROXYFILE: { unixFile *pFile = (unixFile*)id; if( pFile->pMethod == &proxyIoMethods ){ proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext; @@ -32397,13 +32708,16 @@ static int proxyFileControl(sqlite3_file *id, int op, void *pArg){ } return SQLITE_OK; } - case SQLITE_SET_LOCKPROXYFILE: { + case SQLITE_FCNTL_SET_LOCKPROXYFILE: { unixFile *pFile = (unixFile*)id; int rc = SQLITE_OK; int isProxyStyle = (pFile->pMethod == &proxyIoMethods); if( pArg==NULL || (const char *)pArg==0 ){ if( isProxyStyle ){ - /* turn off proxy locking - not supported */ + /* turn off proxy locking - not supported. If support is added for + ** switching proxy locking mode off then it will need to fail if + ** the journal mode is WAL mode. + */ rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/; }else{ /* turn off proxy locking - already off - NOOP */ @@ -32594,7 +32908,7 @@ static int proxyClose(sqlite3_file *id) { ** necessarily been initialized when this routine is called, and so they ** should not be used. */ -SQLITE_API int sqlite3_os_init(void){ +SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){ /* ** The following macro defines an initializer for an sqlite3_vfs object. ** The name of the VFS is NAME. The pAppData is a pointer to a pointer @@ -32648,8 +32962,10 @@ SQLITE_API int sqlite3_os_init(void){ ** array cannot be const. */ static sqlite3_vfs aVfs[] = { -#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__)) +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) UNIXVFS("unix", autolockIoFinder ), +#elif OS_VXWORKS + UNIXVFS("unix", vxworksIoFinder ), #else UNIXVFS("unix", posixIoFinder ), #endif @@ -32659,11 +32975,11 @@ SQLITE_API int sqlite3_os_init(void){ #if OS_VXWORKS UNIXVFS("unix-namedsem", semIoFinder ), #endif -#if SQLITE_ENABLE_LOCKING_STYLE +#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS UNIXVFS("unix-posix", posixIoFinder ), -#if !OS_VXWORKS - UNIXVFS("unix-flock", flockIoFinder ), #endif +#if SQLITE_ENABLE_LOCKING_STYLE + UNIXVFS("unix-flock", flockIoFinder ), #endif #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) UNIXVFS("unix-afp", afpIoFinder ), @@ -32691,7 +33007,7 @@ SQLITE_API int sqlite3_os_init(void){ ** to release dynamically allocated objects. But not on unix. ** This routine is a no-op for unix. */ -SQLITE_API int sqlite3_os_end(void){ +SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){ return SQLITE_OK; } @@ -32751,16 +33067,6 @@ SQLITE_API int sqlite3_os_end(void){ # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." #endif -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) -# ifndef SQLITE_DEBUG_OS_TRACE -# define SQLITE_DEBUG_OS_TRACE 0 -# endif - int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; -# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X -#else -# define OSTRACE(X) -#endif - /* ** Macros for performance tracing. Normally turned off. Only works ** on i486 hardware. @@ -33104,8 +33410,10 @@ WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif /* SQLITE_OS_WINRT */ /* -** This file mapping API is common to both Win32 and WinRT. +** These file mapping APIs are common to both Win32 and WinRT. */ + +WINBASEAPI BOOL WINAPI FlushViewOfFile(LPCVOID, SIZE_T); WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID); #endif /* SQLITE_WIN32_FILEMAPPING_API */ @@ -33973,6 +34281,32 @@ static struct win_syscall { SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent) #endif /* defined(InterlockedCompareExchange) */ +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID + { "UuidCreate", (SYSCALL)UuidCreate, 0 }, +#else + { "UuidCreate", (SYSCALL)0, 0 }, +#endif + +#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent) + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID + { "UuidCreateSequential", (SYSCALL)UuidCreateSequential, 0 }, +#else + { "UuidCreateSequential", (SYSCALL)0, 0 }, +#endif + +#define osUuidCreateSequential \ + ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent) + +#if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0 + { "FlushViewOfFile", (SYSCALL)FlushViewOfFile, 0 }, +#else + { "FlushViewOfFile", (SYSCALL)0, 0 }, +#endif + +#define osFlushViewOfFile \ + ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent) + }; /* End of the overrideable system calls */ /* @@ -34066,7 +34400,7 @@ static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){ ** "pnLargest" argument, if non-zero, will be used to return the size of the ** largest committed free block in the heap, in bytes. */ -SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){ +SQLITE_API int SQLITE_STDCALL sqlite3_win32_compact_heap(LPUINT pnLargest){ int rc = SQLITE_OK; UINT nLargest = 0; HANDLE hHeap; @@ -34106,7 +34440,7 @@ SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){ ** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will ** be returned and no changes will be made to the Win32 native heap. */ -SQLITE_API int sqlite3_win32_reset_heap(){ +SQLITE_API int SQLITE_STDCALL sqlite3_win32_reset_heap(){ int rc; MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */ MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */ @@ -34151,7 +34485,7 @@ SQLITE_API int sqlite3_win32_reset_heap(){ ** (if available). */ -SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ +SQLITE_API void SQLITE_STDCALL sqlite3_win32_write_debug(const char *zBuf, int nBuf){ char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE]; int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */ if( nMin<-1 ) nMin = -1; /* all negative values become -1. */ @@ -34191,7 +34525,7 @@ SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ static HANDLE sleepObj = NULL; #endif -SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){ +SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds){ #if SQLITE_OS_WINRT if ( sleepObj==NULL ){ sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET, @@ -34240,7 +34574,7 @@ SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ ** This function determines if the machine is running a version of Windows ** based on the NT kernel. */ -SQLITE_API int sqlite3_win32_is_nt(void){ +SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void){ #if SQLITE_OS_WINRT /* ** NOTE: The WinRT sub-platform is always assumed to be based on the NT @@ -34594,7 +34928,7 @@ static char *winUnicodeToMbcs(LPCWSTR zWideFilename){ ** Convert multibyte character string to UTF-8. Space to hold the ** returned string is obtained from sqlite3_malloc(). */ -SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ +SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zFilename){ char *zFilenameUtf8; LPWSTR zTmpWide; @@ -34611,7 +34945,7 @@ SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ ** Convert UTF-8 to multibyte character string. Space to hold the ** returned string is obtained from sqlite3_malloc(). */ -SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ +SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zFilename){ char *zFilenameMbcs; LPWSTR zTmpWide; @@ -34631,7 +34965,7 @@ SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ ** argument is the name of the directory to use. The return value will be ** SQLITE_OK if successful. */ -SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){ +SQLITE_API int SQLITE_STDCALL sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){ char **ppDirectory = 0; #ifndef SQLITE_OMIT_AUTOINIT int rc = sqlite3_initialize(); @@ -34856,11 +35190,11 @@ static int winRetryIoerr(int *pnRetry, DWORD *pError){ /* ** Log a I/O error retry episode. */ -static void winLogIoerr(int nRetry){ +static void winLogIoerr(int nRetry, int lineno){ if( nRetry ){ - sqlite3_log(SQLITE_IOERR, - "delayed %dms for lock/sharing conflict", - winIoerrRetryDelay*nRetry*(nRetry+1)/2 + sqlite3_log(SQLITE_NOTICE, + "delayed %dms for lock/sharing conflict at line %d", + winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno ); } } @@ -35342,7 +35676,8 @@ static int winClose(sqlite3_file *id){ assert( pFile->pShm==0 ); #endif assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE ); - OSTRACE(("CLOSE file=%p\n", pFile->h)); + OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n", + osGetCurrentProcessId(), pFile, pFile->h)); #if SQLITE_MAX_MMAP_SIZE>0 winUnmapfile(pFile); @@ -35371,7 +35706,8 @@ static int winClose(sqlite3_file *id){ pFile->h = NULL; } OpenCounter(-1); - OSTRACE(("CLOSE file=%p, rc=%s\n", pFile->h, rc ? "ok" : "failed")); + OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n", + osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed")); return rc ? SQLITE_OK : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(), "winClose", pFile->zPath); @@ -35399,7 +35735,8 @@ static int winRead( assert( amt>0 ); assert( offset>=0 ); SimulateIOError(return SQLITE_IOERR_READ); - OSTRACE(("READ file=%p, buffer=%p, amount=%d, offset=%lld, lock=%d\n", + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " + "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, pFile->h, pBuf, amt, offset, pFile->locktype)); #if SQLITE_MAX_MMAP_SIZE>0 @@ -35408,7 +35745,8 @@ static int winRead( if( offset<pFile->mmapSize ){ if( offset+amt <= pFile->mmapSize ){ memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); - OSTRACE(("READ-MMAP file=%p, rc=SQLITE_OK\n", pFile->h)); + OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); return SQLITE_OK; }else{ int nCopy = (int)(pFile->mmapSize - offset); @@ -35422,7 +35760,8 @@ static int winRead( #if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) if( winSeekFile(pFile, offset) ){ - OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h)); + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n", + osGetCurrentProcessId(), pFile, pFile->h)); return SQLITE_FULL; } while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ @@ -35436,19 +35775,22 @@ static int winRead( DWORD lastErrno; if( winRetryIoerr(&nRetry, &lastErrno) ) continue; pFile->lastErrno = lastErrno; - OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h)); + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n", + osGetCurrentProcessId(), pFile, pFile->h)); return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, "winRead", pFile->zPath); } - winLogIoerr(nRetry); + winLogIoerr(nRetry, __LINE__); if( nRead<(DWORD)amt ){ /* Unread parts of the buffer must be zero-filled */ memset(&((char*)pBuf)[nRead], 0, amt-nRead); - OSTRACE(("READ file=%p, rc=SQLITE_IOERR_SHORT_READ\n", pFile->h)); + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n", + osGetCurrentProcessId(), pFile, pFile->h)); return SQLITE_IOERR_SHORT_READ; } - OSTRACE(("READ file=%p, rc=SQLITE_OK\n", pFile->h)); + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); return SQLITE_OK; } @@ -35471,7 +35813,8 @@ static int winWrite( SimulateIOError(return SQLITE_IOERR_WRITE); SimulateDiskfullError(return SQLITE_FULL); - OSTRACE(("WRITE file=%p, buffer=%p, amount=%d, offset=%lld, lock=%d\n", + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " + "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, pFile->h, pBuf, amt, offset, pFile->locktype)); #if SQLITE_MAX_MMAP_SIZE>0 @@ -35480,7 +35823,8 @@ static int winWrite( if( offset<pFile->mmapSize ){ if( offset+amt <= pFile->mmapSize ){ memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); - OSTRACE(("WRITE-MMAP file=%p, rc=SQLITE_OK\n", pFile->h)); + OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); return SQLITE_OK; }else{ int nCopy = (int)(pFile->mmapSize - offset); @@ -35543,17 +35887,20 @@ static int winWrite( if( rc ){ if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) || ( pFile->lastErrno==ERROR_DISK_FULL )){ - OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h)); + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n", + osGetCurrentProcessId(), pFile, pFile->h)); return winLogError(SQLITE_FULL, pFile->lastErrno, "winWrite1", pFile->zPath); } - OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h)); + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n", + osGetCurrentProcessId(), pFile, pFile->h)); return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, "winWrite2", pFile->zPath); }else{ - winLogIoerr(nRetry); + winLogIoerr(nRetry, __LINE__); } - OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h)); + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); return SQLITE_OK; } @@ -35567,8 +35914,8 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ assert( pFile ); SimulateIOError(return SQLITE_IOERR_TRUNCATE); - OSTRACE(("TRUNCATE file=%p, size=%lld, lock=%d\n", - pFile->h, nByte, pFile->locktype)); + OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n", + osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype)); /* If the user has configured a chunk-size for this file, truncate the ** file so that it consists of an integer number of chunks (i.e. the @@ -35600,7 +35947,8 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ } #endif - OSTRACE(("TRUNCATE file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); + OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n", + osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc))); return rc; } @@ -35624,7 +35972,7 @@ static int winSync(sqlite3_file *id, int flags){ BOOL rc; #endif #if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \ - (defined(SQLITE_TEST) && defined(SQLITE_DEBUG)) + defined(SQLITE_HAVE_OS_TRACE) /* ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or ** OSTRACE() macros. @@ -35645,8 +35993,9 @@ static int winSync(sqlite3_file *id, int flags){ */ SimulateDiskfullError( return SQLITE_FULL ); - OSTRACE(("SYNC file=%p, flags=%x, lock=%d\n", - pFile->h, flags, pFile->locktype)); + OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n", + osGetCurrentProcessId(), pFile, pFile->h, flags, + pFile->locktype)); #ifndef SQLITE_TEST UNUSED_PARAMETER(flags); @@ -35661,19 +36010,38 @@ static int winSync(sqlite3_file *id, int flags){ ** no-op */ #ifdef SQLITE_NO_SYNC - OSTRACE(("SYNC-NOP file=%p, rc=SQLITE_OK\n", pFile->h)); + OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); return SQLITE_OK; #else +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFile->pMapRegion ){ + if( osFlushViewOfFile(pFile->pMapRegion, 0) ){ + OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, " + "rc=SQLITE_OK\n", osGetCurrentProcessId(), + pFile, pFile->pMapRegion)); + }else{ + pFile->lastErrno = osGetLastError(); + OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, " + "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), + pFile, pFile->pMapRegion)); + return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, + "winSync1", pFile->zPath); + } + } +#endif rc = osFlushFileBuffers(pFile->h); SimulateIOError( rc=FALSE ); if( rc ){ - OSTRACE(("SYNC file=%p, rc=SQLITE_OK\n", pFile->h)); + OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); return SQLITE_OK; }else{ pFile->lastErrno = osGetLastError(); - OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h)); + OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n", + osGetCurrentProcessId(), pFile, pFile->h)); return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, - "winSync", pFile->zPath); + "winSync2", pFile->zPath); } #endif } @@ -36281,7 +36649,7 @@ struct winShmNode { int nRef; /* Number of winShm objects pointing to this */ winShm *pFirst; /* All winShm objects pointing to this */ winShmNode *pNext; /* Next in list of all winShmNode objects */ -#ifdef SQLITE_DEBUG +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) u8 nextShmId; /* Next available winShm.id value */ #endif }; @@ -36312,7 +36680,7 @@ struct winShm { u8 hasMutex; /* True if holding the winShmNode mutex */ u16 sharedMask; /* Mask of shared locks held */ u16 exclMask; /* Mask of exclusive locks held */ -#ifdef SQLITE_DEBUG +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) u8 id; /* Id of this connection with its winShmNode */ #endif }; @@ -36503,7 +36871,7 @@ static int winOpenSharedMemory(winFile *pDbFd){ /* Make the new connection a child of the winShmNode */ p->pShmNode = pShmNode; -#ifdef SQLITE_DEBUG +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) p->id = pShmNode->nextShmId++; #endif pShmNode->nRef++; @@ -36723,16 +37091,16 @@ static int winShmMap( void volatile **pp /* OUT: Mapped memory */ ){ winFile *pDbFd = (winFile*)fd; - winShm *p = pDbFd->pShm; + winShm *pShm = pDbFd->pShm; winShmNode *pShmNode; int rc = SQLITE_OK; - if( !p ){ + if( !pShm ){ rc = winOpenSharedMemory(pDbFd); if( rc!=SQLITE_OK ) return rc; - p = pDbFd->pShm; + pShm = pDbFd->pShm; } - pShmNode = p->pShmNode; + pShmNode = pShm->pShmNode; sqlite3_mutex_enter(pShmNode->mutex); assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); @@ -36772,7 +37140,7 @@ static int winShmMap( } /* Map the requested memory region into this processes address space. */ - apNew = (struct ShmRegion *)sqlite3_realloc( + apNew = (struct ShmRegion *)sqlite3_realloc64( pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) ); if( !apNew ){ @@ -37644,7 +38012,7 @@ static int winOpen( } } #endif - winLogIoerr(cnt); + winLogIoerr(cnt, __LINE__); OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); @@ -37828,7 +38196,7 @@ static int winDelete( if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename); }else{ - winLogIoerr(cnt); + winLogIoerr(cnt, __LINE__); } sqlite3_free(zConverted); OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); @@ -37878,7 +38246,7 @@ static int winAccess( attr = sAttrData.dwFileAttributes; } }else{ - winLogIoerr(cnt); + winLogIoerr(cnt, __LINE__); if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ sqlite3_free(zConverted); return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", @@ -38219,7 +38587,7 @@ static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ int n = 0; UNUSED_PARAMETER(pVfs); -#if defined(SQLITE_TEST) +#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) n = nBuf; memset(zBuf, 0, nBuf); #else @@ -38253,7 +38621,23 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ memcpy(&zBuf[n], &i, sizeof(i)); n += sizeof(i); } +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID + if( sizeof(UUID)<=nBuf-n ){ + UUID id; + memset(&id, 0, sizeof(UUID)); + osUuidCreate(&id); + memcpy(zBuf, &id, sizeof(UUID)); + n += sizeof(UUID); + } + if( sizeof(UUID)<=nBuf-n ){ + UUID id; + memset(&id, 0, sizeof(UUID)); + osUuidCreateSequential(&id); + memcpy(zBuf, &id, sizeof(UUID)); + n += sizeof(UUID); + } #endif +#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */ return n; } @@ -38377,7 +38761,7 @@ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ /* ** Initialize and deinitialize the operating system interface. */ -SQLITE_API int sqlite3_os_init(void){ +SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){ static sqlite3_vfs winVfs = { 3, /* iVersion */ sizeof(winFile), /* szOsFile */ @@ -38431,7 +38815,7 @@ SQLITE_API int sqlite3_os_init(void){ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==77 ); + assert( ArraySize(aSyscall)==80 ); /* get memory map allocation granularity */ memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); @@ -38452,7 +38836,7 @@ SQLITE_API int sqlite3_os_init(void){ return SQLITE_OK; } -SQLITE_API int sqlite3_os_end(void){ +SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){ #if SQLITE_OS_WINRT if( sleepObj!=NULL ){ osCloseHandle(sleepObj); @@ -38808,7 +39192,7 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ ** bits to act as the reference */ pBitvec = sqlite3BitvecCreate( sz ); pV = sqlite3MallocZero( (sz+7)/8 + 1 ); - pTmpSpace = sqlite3_malloc(BITVEC_SZ); + pTmpSpace = sqlite3_malloc64(BITVEC_SZ); if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; /* NULL pBitvec tests */ @@ -38990,12 +39374,20 @@ static void pcacheUnpin(PgHdr *p){ } /* -** Compute the number of pages of cache requested. +** Compute the number of pages of cache requested. p->szCache is the +** cache size requested by the "PRAGMA cache_size" statement. +** +** */ static int numberOfCachePages(PCache *p){ if( p->szCache>=0 ){ + /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the + ** suggested cache size is set to N. */ return p->szCache; }else{ + /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then + ** the number of cache pages is adjusted to use approximately abs(N*1024) + ** bytes of memory. */ return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); } } @@ -39735,7 +40127,6 @@ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ static void *pcache1Alloc(int nByte){ void *p = 0; assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); - sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte); if( nByte<=pcache1.szSlot ){ sqlite3_mutex_enter(pcache1.mutex); p = (PgHdr1 *)pcache1.pFree; @@ -39744,7 +40135,8 @@ static void *pcache1Alloc(int nByte){ pcache1.nFreeSlot--; pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve; assert( pcache1.nFreeSlot>=0 ); - sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1); + sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte); + sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1); } sqlite3_mutex_leave(pcache1.mutex); } @@ -39757,7 +40149,8 @@ static void *pcache1Alloc(int nByte){ if( p ){ int sz = sqlite3MallocSize(p); sqlite3_mutex_enter(pcache1.mutex); - sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); + sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte); + sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); sqlite3_mutex_leave(pcache1.mutex); } #endif @@ -39775,7 +40168,7 @@ static int pcache1Free(void *p){ if( p>=pcache1.pStart && p<pcache1.pEnd ){ PgFreeslot *pSlot; sqlite3_mutex_enter(pcache1.mutex); - sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1); + sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1); pSlot = (PgFreeslot*)p; pSlot->pNext = pcache1.pFree; pcache1.pFree = pSlot; @@ -39789,7 +40182,7 @@ static int pcache1Free(void *p){ nFreed = sqlite3MallocSize(p); #ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS sqlite3_mutex_enter(pcache1.mutex); - sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed); + sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed); sqlite3_mutex_leave(pcache1.mutex); #endif sqlite3_free(p); @@ -40526,6 +40919,14 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){ */ SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); } +/* +** Return the global mutex used by this PCACHE implementation. The +** sqlite3_status() routine needs access to this mutex. +*/ +SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void){ + return pcache1.mutex; +} + #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* ** This function is called to free superfluous dynamically allocated memory @@ -44280,9 +44681,7 @@ static int pagerWalFrames( ){ int rc; /* Return code */ int nList; /* Number of pages in pList */ -#if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES) PgHdr *p; /* For looping over pages */ -#endif assert( pPager->pWal ); assert( pList ); @@ -44299,7 +44698,6 @@ static int pagerWalFrames( ** any pages with page numbers greater than nTruncate into the WAL file. ** They will never be read by any client. So remove them from the pDirty ** list here. */ - PgHdr *p; PgHdr **ppNext = &pList; nList = 0; for(p=pList; (*ppNext = p)!=0; p=p->pDirty){ @@ -44319,7 +44717,6 @@ static int pagerWalFrames( pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags ); if( rc==SQLITE_OK && pPager->pBackup ){ - PgHdr *p; for(p=pList; p; p=p->pDirty){ sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData); } @@ -48250,6 +48647,8 @@ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ } assert( state==pPager->eState ); } + }else if( eMode==PAGER_JOURNALMODE_OFF ){ + sqlite3OsClose(pPager->jfd); } } @@ -49032,7 +49431,7 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){ if( pWal->nWiData<=iPage ){ int nByte = sizeof(u32*)*(iPage+1); volatile u32 **apNew; - apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte); + apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte); if( !apNew ){ *ppPage = 0; return SQLITE_NOMEM; @@ -49298,9 +49697,10 @@ static void walUnlockShared(Wal *pWal, int lockIdx){ SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); } -static int walLockExclusive(Wal *pWal, int lockIdx, int n){ +static int walLockExclusive(Wal *pWal, int lockIdx, int n, int fBlock){ int rc; if( pWal->exclusiveMode ) return SQLITE_OK; + if( fBlock ) sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_WAL_BLOCK, 0); rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, @@ -49586,7 +49986,7 @@ static int walIndexRecover(Wal *pWal){ assert( pWal->writeLock ); iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; nLock = SQLITE_SHM_NLOCK - iLock; - rc = walLockExclusive(pWal, iLock, nLock); + rc = walLockExclusive(pWal, iLock, nLock, 0); if( rc ){ return rc; } @@ -49656,7 +50056,7 @@ static int walIndexRecover(Wal *pWal){ /* Malloc a buffer to read frames into. */ szFrame = szPage + WAL_FRAME_HDRSIZE; - aFrame = (u8 *)sqlite3_malloc(szFrame); + aFrame = (u8 *)sqlite3_malloc64(szFrame); if( !aFrame ){ rc = SQLITE_NOMEM; goto recovery_error; @@ -50049,7 +50449,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){ nByte = sizeof(WalIterator) + (nSegment-1)*sizeof(struct WalSegment) + iLast*sizeof(ht_slot); - p = (WalIterator *)sqlite3_malloc(nByte); + p = (WalIterator *)sqlite3_malloc64(nByte); if( !p ){ return SQLITE_NOMEM; } @@ -50059,7 +50459,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){ /* Allocate temporary space used by the merge-sort routine. This block ** of memory will be freed before this function returns. */ - aTmp = (ht_slot *)sqlite3_malloc( + aTmp = (ht_slot *)sqlite3_malloc64( sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) ); if( !aTmp ){ @@ -50120,7 +50520,7 @@ static int walBusyLock( ){ int rc; do { - rc = walLockExclusive(pWal, lockIdx, n); + rc = walLockExclusive(pWal, lockIdx, n, 0); }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) ); return rc; } @@ -50239,6 +50639,14 @@ static int walCheckpoint( mxSafeFrame = pWal->hdr.mxFrame; mxPage = pWal->hdr.nPage; for(i=1; i<WAL_NREADER; i++){ + /* Thread-sanitizer reports that the following is an unsafe read, + ** as some other thread may be in the process of updating the value + ** of the aReadMark[] slot. The assumption here is that if that is + ** happening, the other client may only be increasing the value, + ** not decreasing it. So assuming either that either the "old" or + ** "new" version of the value is read, and not some arbitrary value + ** that would never be written by a real client, things are still + ** safe. */ u32 y = pInfo->aReadMark[i]; if( mxSafeFrame>y ){ assert( y<=pWal->hdr.mxFrame ); @@ -50553,7 +50961,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ walUnlockShared(pWal, WAL_WRITE_LOCK); rc = SQLITE_READONLY_RECOVERY; } - }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ + }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 1)) ){ pWal->writeLock = 1; if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ badHdr = walIndexTryHdr(pWal, pChanged); @@ -50759,7 +51167,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ && (mxReadMark<pWal->hdr.mxFrame || mxI==0) ){ for(i=1; i<WAL_NREADER; i++){ - rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); + rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1, 0); if( rc==SQLITE_OK ){ mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame; mxI = i; @@ -51015,7 +51423,7 @@ SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){ /* Only one writer allowed at a time. Get the write lock. Return ** SQLITE_BUSY if unable. */ - rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); + rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 0); if( rc ){ return rc; } @@ -51160,7 +51568,7 @@ static int walRestartLog(Wal *pWal){ if( pInfo->nBackfill>0 ){ u32 salt1; sqlite3_randomness(4, &salt1); - rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); + rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1, 0); if( rc==SQLITE_OK ){ /* If all readers are using WAL_READ_LOCK(0) (in other words if no ** readers are currently using the WAL), then the transactions @@ -51485,7 +51893,7 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive ** "checkpoint" lock on the database file. */ - rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); + rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1, 0); if( rc ){ /* EVIDENCE-OF: R-10421-19736 If any other process is running a ** checkpoint operation at the same time, the lock cannot be obtained and @@ -51960,6 +52368,7 @@ struct MemPage { u8 hdrOffset; /* 100 for page 1. 0 otherwise */ u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */ u8 max1bytePayload; /* min(maxLocal,127) */ + u8 bBusy; /* Prevent endless loops on corrupt database files */ u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */ u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */ u16 cellOffset; /* Index in aData of first cell pointer */ @@ -52098,6 +52507,9 @@ struct BtShared { #endif u8 inTransaction; /* Transaction state */ u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */ +#ifdef SQLITE_HAS_CODEC + u8 optimalReserve; /* Desired amount of reserved space per page */ +#endif u16 btsFlags; /* Boolean parameters. See BTS_* macros below */ u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */ u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */ @@ -52484,6 +52896,7 @@ static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){ ** Exit the recursive mutex on a Btree. */ SQLITE_PRIVATE void sqlite3BtreeLeave(Btree *p){ + assert( sqlite3_mutex_held(p->db->mutex) ); if( p->sharable ){ assert( p->wantToLock>0 ); p->wantToLock--; @@ -52731,7 +53144,7 @@ static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0; ** The shared cache setting effects only future calls to ** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2(). */ -SQLITE_API int sqlite3_enable_shared_cache(int enable){ +SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int enable){ sqlite3GlobalConfig.sharedCacheEnabled = enable; return SQLITE_OK; } @@ -52820,6 +53233,12 @@ static int hasSharedCacheTableLock( for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){ Index *pIdx = (Index *)sqliteHashData(p); if( pIdx->tnum==(int)iRoot ){ + if( iTab ){ + /* Two or more indexes share the same root page. There must + ** be imposter tables. So just return true. The assert is not + ** useful in that case. */ + return 1; + } iTab = pIdx->pTable->tnum; } } @@ -53239,10 +53658,15 @@ static void btreeReleaseAllCursorPages(BtCursor *pCur){ static int saveCursorPosition(BtCursor *pCur){ int rc; - assert( CURSOR_VALID==pCur->eState ); + assert( CURSOR_VALID==pCur->eState || CURSOR_SKIPNEXT==pCur->eState ); assert( 0==pCur->pKey ); assert( cursorHoldsMutex(pCur) ); + if( pCur->eState==CURSOR_SKIPNEXT ){ + pCur->eState = CURSOR_VALID; + }else{ + pCur->skipNext = 0; + } rc = sqlite3BtreeKeySize(pCur, &pCur->nKey); assert( rc==SQLITE_OK ); /* KeySize() cannot fail */ @@ -53313,7 +53737,7 @@ static int SQLITE_NOINLINE saveCursorsOnList( ){ do{ if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){ - if( p->eState==CURSOR_VALID ){ + if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){ int rc = saveCursorPosition(p); if( SQLITE_OK!=rc ){ return rc; @@ -53385,17 +53809,19 @@ static int btreeMoveto( */ static int btreeRestoreCursorPosition(BtCursor *pCur){ int rc; + int skipNext; assert( cursorHoldsMutex(pCur) ); assert( pCur->eState>=CURSOR_REQUIRESEEK ); if( pCur->eState==CURSOR_FAULT ){ return pCur->skipNext; } pCur->eState = CURSOR_INVALID; - rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skipNext); + rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext); if( rc==SQLITE_OK ){ sqlite3_free(pCur->pKey); pCur->pKey = 0; assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID ); + pCur->skipNext |= skipNext; if( pCur->skipNext && pCur->eState==CURSOR_VALID ){ pCur->eState = CURSOR_SKIPNEXT; } @@ -53447,9 +53873,10 @@ SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow) *pDifferentRow = 1; return rc; } - if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){ + if( pCur->eState!=CURSOR_VALID ){ *pDifferentRow = 1; }else{ + assert( pCur->skipNext==0 ); *pDifferentRow = 0; } return SQLITE_OK; @@ -54590,16 +55017,18 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( */ if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){ if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){ + int nFilename = sqlite3Strlen30(zFilename)+1; int nFullPathname = pVfs->mxPathname+1; - char *zFullPathname = sqlite3Malloc(nFullPathname); + char *zFullPathname = sqlite3Malloc(MAX(nFullPathname,nFilename)); MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) + p->sharable = 1; if( !zFullPathname ){ sqlite3_free(p); return SQLITE_NOMEM; } if( isMemdb ){ - memcpy(zFullPathname, zFilename, sqlite3Strlen30(zFilename)+1); + memcpy(zFullPathname, zFilename, nFilename); }else{ rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); @@ -54656,8 +55085,8 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( ** the right size. This is to guard against size changes that result ** when compiling on a different architecture. */ - assert( sizeof(i64)==8 || sizeof(i64)==4 ); - assert( sizeof(u64)==8 || sizeof(u64)==4 ); + assert( sizeof(i64)==8 ); + assert( sizeof(u64)==8 ); assert( sizeof(u32)==4 ); assert( sizeof(u16)==2 ); assert( sizeof(Pgno)==4 ); @@ -55044,6 +55473,9 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, BtShared *pBt = p->pBt; assert( nReserve>=-1 && nReserve<=255 ); sqlite3BtreeEnter(p); +#if SQLITE_HAS_CODEC + if( nReserve>pBt->optimalReserve ) pBt->optimalReserve = (u8)nReserve; +#endif if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){ sqlite3BtreeLeave(p); return SQLITE_READONLY; @@ -55055,7 +55487,7 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE && ((pageSize-1)&pageSize)==0 ){ assert( (pageSize & 7)==0 ); - assert( !pBt->pPage1 && !pBt->pCursor ); + assert( !pBt->pCursor ); pBt->pageSize = (u32)pageSize; freeTempSpace(pBt); } @@ -55073,7 +55505,6 @@ SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){ return p->pBt->pageSize; } -#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG) /* ** This function is similar to sqlite3BtreeGetReserve(), except that it ** may only be called if it is guaranteed that the b-tree mutex is already @@ -55086,25 +55517,33 @@ SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){ ** database handle that owns *p, causing undefined behavior. */ SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){ + int n; assert( sqlite3_mutex_held(p->pBt->mutex) ); - return p->pBt->pageSize - p->pBt->usableSize; + n = p->pBt->pageSize - p->pBt->usableSize; + return n; } -#endif /* SQLITE_HAS_CODEC || SQLITE_DEBUG */ -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) /* ** Return the number of bytes of space at the end of every page that ** are intentually left unused. This is the "reserved" space that is ** sometimes used by extensions. +** +** If SQLITE_HAS_MUTEX is defined then the number returned is the +** greater of the current reserved space and the maximum requested +** reserve space. */ -SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree *p){ int n; sqlite3BtreeEnter(p); - n = p->pBt->pageSize - p->pBt->usableSize; + n = sqlite3BtreeGetReserveNoMutex(p); +#ifdef SQLITE_HAS_CODEC + if( n<p->pBt->optimalReserve ) n = p->pBt->optimalReserve; +#endif sqlite3BtreeLeave(p); return n; } + /* ** Set the maximum page count for a database if mxPage is positive. ** No changes are made if mxPage is 0 or negative. @@ -55135,7 +55574,6 @@ SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ sqlite3BtreeLeave(p); return b; } -#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */ /* ** Change the 'auto-vacuum' property of the database. If the 'autoVacuum' @@ -56255,7 +56693,7 @@ SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int wr for(p=pBtree->pBt->pCursor; p; p=p->pNext){ int i; if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){ - if( p->eState==CURSOR_VALID ){ + if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){ rc = saveCursorPosition(p); if( rc!=SQLITE_OK ){ (void)sqlite3BtreeTripAllCursors(pBtree, rc, 0); @@ -56661,6 +57099,8 @@ SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){ SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){ assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPage>=0 ); + assert( pCur->iPage<BTCURSOR_MAX_DEPTH ); assert( pCur->apPage[pCur->iPage]->intKeyLeaf==1 ); getCellInfo(pCur); *pSize = pCur->info.nPayload; @@ -57069,13 +57509,18 @@ static const void *fetchPayload( BtCursor *pCur, /* Cursor pointing to entry to read from */ u32 *pAmt /* Write the number of available bytes here */ ){ + u32 amt; assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); assert( pCur->eState==CURSOR_VALID ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( cursorHoldsMutex(pCur) ); assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell ); assert( pCur->info.nSize>0 ); - *pAmt = pCur->info.nLocal; + assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB ); + assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB); + amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload); + if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal; + *pAmt = amt; return (void*)pCur->info.pPayload; } @@ -57139,7 +57584,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ return SQLITE_OK; } -#if 0 +#if SQLITE_DEBUG /* ** Page pParent is an internal (non-leaf) tree page. This function ** asserts that page number iChild is the left-child if the iIdx'th @@ -57148,6 +57593,8 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ ** the page. */ static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){ + if( CORRUPT_DB ) return; /* The conditions tested below might not be true + ** in a corrupt database */ assert( iIdx<=pParent->nCell ); if( iIdx==pParent->nCell ){ assert( get4byte(&pParent->aData[pParent->hdrOffset+8])==iChild ); @@ -57172,19 +57619,11 @@ static void moveToParent(BtCursor *pCur){ assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPage>0 ); assert( pCur->apPage[pCur->iPage] ); - - /* UPDATE: It is actually possible for the condition tested by the assert - ** below to be untrue if the database file is corrupt. This can occur if - ** one cursor has modified page pParent while a reference to it is held - ** by a second cursor. Which can only happen if a single page is linked - ** into more than one b-tree structure in a corrupt database. */ -#if 0 assertParentIndex( pCur->apPage[pCur->iPage-1], pCur->aiIdx[pCur->iPage-1], pCur->apPage[pCur->iPage]->pgno ); -#endif testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); releasePage(pCur->apPage[pCur->iPage]); @@ -59359,7 +59798,6 @@ static int balance_nonroot( }else if( iParentIdx==i ){ nxDiv = i-2+bBulk; }else{ - assert( bBulk==0 ); nxDiv = iParentIdx-1; } i = 2-bBulk; @@ -60110,7 +60548,8 @@ static int balance(BtCursor *pCur){ ** pSpace buffer passed to the latter call to balance_nonroot(). */ u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); - rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, pCur->hints); + rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, + pCur->hints&BTREE_BULKLOAD); if( pFree ){ /* If pFree is not NULL, it points to the pSpace buffer used ** by a previous call to balance_nonroot(). Its contents are @@ -60131,6 +60570,7 @@ static int balance(BtCursor *pCur){ /* The next iteration of the do-loop balances the parent page. */ releasePage(pPage); pCur->iPage--; + assert( pCur->iPage>=0 ); } }while( rc==SQLITE_OK ); @@ -60607,9 +61047,13 @@ static int clearDatabasePage( if( pgno>btreePagecount(pBt) ){ return SQLITE_CORRUPT_BKPT; } - rc = getAndInitPage(pBt, pgno, &pPage, 0); if( rc ) return rc; + if( pPage->bBusy ){ + rc = SQLITE_CORRUPT_BKPT; + goto cleardatabasepage_out; + } + pPage->bBusy = 1; hdr = pPage->hdrOffset; for(i=0; i<pPage->nCell; i++){ pCell = findCell(pPage, i); @@ -60634,6 +61078,7 @@ static int clearDatabasePage( } cleardatabasepage_out: + pPage->bBusy = 0; releasePage(pPage); return rc; } @@ -61141,6 +61586,57 @@ static void checkList( } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ +/* +** An implementation of a min-heap. +** +** aHeap[0] is the number of elements on the heap. aHeap[1] is the +** root element. The daughter nodes of aHeap[N] are aHeap[N*2] +** and aHeap[N*2+1]. +** +** The heap property is this: Every node is less than or equal to both +** of its daughter nodes. A consequence of the heap property is that the +** root node aHeap[1] is always the minimum value currently in the heap. +** +** The btreeHeapInsert() routine inserts an unsigned 32-bit number onto +** the heap, preserving the heap property. The btreeHeapPull() routine +** removes the root element from the heap (the minimum value in the heap) +** and then moves other nodes around as necessary to preserve the heap +** property. +** +** This heap is used for cell overlap and coverage testing. Each u32 +** entry represents the span of a cell or freeblock on a btree page. +** The upper 16 bits are the index of the first byte of a range and the +** lower 16 bits are the index of the last byte of that range. +*/ +static void btreeHeapInsert(u32 *aHeap, u32 x){ + u32 j, i = ++aHeap[0]; + aHeap[i] = x; + while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){ + x = aHeap[j]; + aHeap[j] = aHeap[i]; + aHeap[i] = x; + i = j; + } +} +static int btreeHeapPull(u32 *aHeap, u32 *pOut){ + u32 j, i, x; + if( (x = aHeap[0])==0 ) return 0; + *pOut = aHeap[1]; + aHeap[1] = aHeap[x]; + aHeap[x] = 0xffffffff; + aHeap[0]--; + i = 1; + while( (j = i*2)<=aHeap[0] ){ + if( aHeap[j]>aHeap[j+1] ) j++; + if( aHeap[i]<aHeap[j] ) break; + x = aHeap[i]; + aHeap[i] = aHeap[j]; + aHeap[j] = x; + i = j; + } + return 1; +} + #ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Do various sanity checks on a single page of a tree. Return @@ -61173,7 +61669,8 @@ static int checkTreePage( u8 *data; BtShared *pBt; int usableSize; - char *hit = 0; + u32 *heap = 0; + u32 x, prev = 0; i64 nMinKey = 0; i64 nMaxKey = 0; const char *saved_zPfx = pCheck->zPfx; @@ -61318,15 +61815,15 @@ static int checkTreePage( */ data = pPage->aData; hdr = pPage->hdrOffset; - hit = sqlite3PageMalloc( pBt->pageSize ); + heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); pCheck->zPfx = 0; - if( hit==0 ){ + if( heap==0 ){ pCheck->mallocFailed = 1; }else{ int contentOffset = get2byteNotZero(&data[hdr+5]); assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ - memset(hit+contentOffset, 0, usableSize-contentOffset); - memset(hit, 1, contentOffset); + heap[0] = 0; + btreeHeapInsert(heap, contentOffset-1); /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the ** number of cells on the page. */ nCell = get2byte(&data[hdr+3]); @@ -61338,7 +61835,6 @@ static int checkTreePage( for(i=0; i<nCell; i++){ int pc = get2byte(&data[cellStart+i*2]); u32 size = 65536; - int j; if( pc<=usableSize-4 ){ size = cellSizePtr(pPage, &data[pc]); } @@ -61347,7 +61843,7 @@ static int checkTreePage( checkAppendMsg(pCheck, "Corruption detected in cell %d on page %d",i,iPage); }else{ - for(j=pc+size-1; j>=pc; j--) hit[j]++; + btreeHeapInsert(heap, (pc<<16)|(pc+size-1)); } } /* EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header @@ -61359,7 +61855,7 @@ static int checkTreePage( assert( i<=usableSize-4 ); /* Enforced by btreeInitPage() */ size = get2byte(&data[i+2]); assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */ - for(j=i+size-1; j>=i; j--) hit[j]++; + btreeHeapInsert(heap, (i<<16)|(i+size-1)); /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a ** big-endian integer which is the offset in the b-tree page of the next ** freeblock in the chain, or zero if the freeblock is the last on the @@ -61371,27 +61867,33 @@ static int checkTreePage( assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */ i = j; } - for(i=cnt=0; i<usableSize; i++){ - if( hit[i]==0 ){ - cnt++; - }else if( hit[i]>1 ){ + cnt = 0; + assert( heap[0]>0 ); + assert( (heap[1]>>16)==0 ); + btreeHeapPull(heap,&prev); + while( btreeHeapPull(heap,&x) ){ + if( (prev&0xffff)+1>(x>>16) ){ checkAppendMsg(pCheck, - "Multiple uses for byte %d of page %d", i, iPage); + "Multiple uses for byte %u of page %d", x>>16, iPage); break; + }else{ + cnt += (x>>16) - (prev&0xffff) - 1; + prev = x; } } + cnt += usableSize - (prev&0xffff) - 1; /* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments ** is stored in the fifth field of the b-tree page header. ** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the ** number of fragmented free bytes within the cell content area. */ - if( cnt!=data[hdr+7] ){ + if( heap[0]==0 && cnt!=data[hdr+7] ){ checkAppendMsg(pCheck, "Fragmentation of %d bytes reported as %d on page %d", cnt, data[hdr+7], iPage); } } - sqlite3PageFree(hit); + sqlite3PageFree(heap); releasePage(pPage); end_of_check: @@ -61455,8 +61957,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( } i = PENDING_BYTE_PAGE(pBt); if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i); - sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); - sCheck.errMsg.useMalloc = 2; + sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); /* Check the integrity of the freelist */ @@ -61773,14 +62274,23 @@ SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ } /* -** set the mask of hint flags for cursor pCsr. Currently the only valid -** values are 0 and BTREE_BULKLOAD. +** set the mask of hint flags for cursor pCsr. */ SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){ - assert( mask==BTREE_BULKLOAD || mask==0 ); + assert( mask==BTREE_BULKLOAD || mask==BTREE_SEEK_EQ || mask==0 ); pCsr->hints = mask; } +#ifdef SQLITE_DEBUG +/* +** Return true if the cursor has a hint specified. This routine is +** only used from within assert() statements +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){ + return (pCsr->hints & mask)!=0; +} +#endif + /* ** Return true if the given Btree is read-only. */ @@ -61939,7 +62449,7 @@ static int checkReadTransaction(sqlite3 *db, Btree *p){ ** If an error occurs, NULL is returned and an error code and error message ** stored in database handle pDestDb. */ -SQLITE_API sqlite3_backup *sqlite3_backup_init( +SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init( sqlite3* pDestDb, /* Database to write to */ const char *zDestDb, /* Name of database within pDestDb */ sqlite3* pSrcDb, /* Database connection to read from */ @@ -62042,7 +62552,7 @@ static int backupOnePage( ** guaranteed that the shared-mutex is held by this thread, handle ** p->pSrc may not actually be the owner. */ int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc); - int nDestReserve = sqlite3BtreeGetReserve(p->pDest); + int nDestReserve = sqlite3BtreeGetOptimalReserve(p->pDest); #endif int rc = SQLITE_OK; i64 iOff; @@ -62147,7 +62657,7 @@ static void attachBackupObject(sqlite3_backup *p){ /* ** Copy nPage pages from the source b-tree to the destination. */ -SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ +SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage){ int rc; int destMode; /* Destination journal mode */ int pgszSrc = 0; /* Source page size */ @@ -62392,7 +62902,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ /* ** Release all resources associated with an sqlite3_backup* handle. */ -SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){ +SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p){ sqlite3_backup **pp; /* Ptr to head of pagers backup list */ sqlite3 *pSrcDb; /* Source database connection */ int rc; /* Value to return */ @@ -62444,7 +62954,7 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){ ** Return the number of pages still to be backed up as of the most recent ** call to sqlite3_backup_step(). */ -SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){ +SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p){ #ifdef SQLITE_ENABLE_API_ARMOR if( p==0 ){ (void)SQLITE_MISUSE_BKPT; @@ -62458,7 +62968,7 @@ SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){ ** Return the total number of pages in the source database as of the most ** recent call to sqlite3_backup_step(). */ -SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){ +SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p){ #ifdef SQLITE_ENABLE_API_ARMOR if( p==0 ){ (void)SQLITE_MISUSE_BKPT; @@ -62783,10 +63293,11 @@ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){ pMem->z[pMem->n] = 0; pMem->z[pMem->n+1] = 0; pMem->flags |= MEM_Term; + } + pMem->flags &= ~MEM_Ephem; #ifdef SQLITE_DEBUG - pMem->pScopyFrom = 0; + pMem->pScopyFrom = 0; #endif - } return SQLITE_OK; } @@ -63673,7 +64184,7 @@ struct ValueNewStat4Ctx { ** Otherwise, if the second argument is non-zero, then this function is ** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not ** already been allocated, allocate the UnpackedRecord structure that -** that function will return to its caller here. Then return a pointer +** that function will return to its caller here. Then return a pointer to ** an sqlite3_value within the UnpackedRecord.a[] array. */ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ @@ -63717,6 +64228,113 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ return sqlite3ValueNew(db); } +/* +** The expression object indicated by the second argument is guaranteed +** to be a scalar SQL function. If +** +** * all function arguments are SQL literals, +** * the SQLITE_FUNC_CONSTANT function flag is set, and +** * the SQLITE_FUNC_NEEDCOLL function flag is not set, +** +** then this routine attempts to invoke the SQL function. Assuming no +** error occurs, output parameter (*ppVal) is set to point to a value +** object containing the result before returning SQLITE_OK. +** +** Affinity aff is applied to the result of the function before returning. +** If the result is a text value, the sqlite3_value object uses encoding +** enc. +** +** If the conditions above are not met, this function returns SQLITE_OK +** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to +** NULL and an SQLite error code returned. +*/ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +static int valueFromFunction( + sqlite3 *db, /* The database connection */ + Expr *p, /* The expression to evaluate */ + u8 enc, /* Encoding to use */ + u8 aff, /* Affinity to use */ + sqlite3_value **ppVal, /* Write the new value here */ + struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */ +){ + sqlite3_context ctx; /* Context object for function invocation */ + sqlite3_value **apVal = 0; /* Function arguments */ + int nVal = 0; /* Size of apVal[] array */ + FuncDef *pFunc = 0; /* Function definition */ + sqlite3_value *pVal = 0; /* New value */ + int rc = SQLITE_OK; /* Return code */ + int nName; /* Size of function name in bytes */ + ExprList *pList = 0; /* Function arguments */ + int i; /* Iterator variable */ + + assert( pCtx!=0 ); + assert( (p->flags & EP_TokenOnly)==0 ); + pList = p->x.pList; + if( pList ) nVal = pList->nExpr; + nName = sqlite3Strlen30(p->u.zToken); + pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0); + assert( pFunc ); + if( (pFunc->funcFlags & SQLITE_FUNC_CONSTANT)==0 + || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) + ){ + return SQLITE_OK; + } + + if( pList ){ + apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal); + if( apVal==0 ){ + rc = SQLITE_NOMEM; + goto value_from_function_out; + } + for(i=0; i<nVal; i++){ + rc = sqlite3ValueFromExpr(db, pList->a[i].pExpr, enc, aff, &apVal[i]); + if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out; + } + } + + pVal = valueNew(db, pCtx); + if( pVal==0 ){ + rc = SQLITE_NOMEM; + goto value_from_function_out; + } + + assert( pCtx->pParse->rc==SQLITE_OK ); + memset(&ctx, 0, sizeof(ctx)); + ctx.pOut = pVal; + ctx.pFunc = pFunc; + pFunc->xFunc(&ctx, nVal, apVal); + if( ctx.isError ){ + rc = ctx.isError; + sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); + }else{ + sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); + assert( rc==SQLITE_OK ); + rc = sqlite3VdbeChangeEncoding(pVal, enc); + if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){ + rc = SQLITE_TOOBIG; + pCtx->pParse->nErr++; + } + } + pCtx->pParse->rc = rc; + + value_from_function_out: + if( rc!=SQLITE_OK ){ + pVal = 0; + } + if( apVal ){ + for(i=0; i<nVal; i++){ + sqlite3ValueFree(apVal[i]); + } + sqlite3DbFree(db, apVal); + } + + *ppVal = pVal; + return rc; +} +#else +# define valueFromFunction(a,b,c,d,e,f) SQLITE_OK +#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */ + /* ** Extract a value from the supplied expression in the manner described ** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object @@ -63749,6 +64367,12 @@ static int valueFromExpr( while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft; if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; + /* Compressed expressions only appear when parsing the DEFAULT clause + ** on a table column definition, and hence only when pCtx==0. This + ** check ensures that an EP_TokenOnly expression is never passed down + ** into valueFromFunction(). */ + assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 ); + if( op==TK_CAST ){ u8 aff = sqlite3AffinityType(pExpr->u.zToken,0); rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx); @@ -63825,6 +64449,12 @@ static int valueFromExpr( } #endif +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + else if( op==TK_FUNCTION && pCtx!=0 ){ + rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx); + } +#endif + *ppVal = pVal; return rc; @@ -64111,7 +64741,7 @@ SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){ Mem *aMem = pRec->aMem; sqlite3 *db = aMem[0].db; for(i=0; i<nCol; i++){ - if( aMem[i].szMalloc ) sqlite3DbFree(db, aMem[i].zMalloc); + sqlite3VdbeMemRelease(&aMem[i]); } sqlite3KeyInfoUnref(pRec->pKeyInfo); sqlite3DbFree(db, pRec); @@ -64214,7 +64844,7 @@ SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepa /* ** Return the SQL associated with a prepared statement */ -SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){ +SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe *)pStmt; return (p && p->isPrepareV2) ? p->zSql : 0; } @@ -65277,7 +65907,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ #ifndef SQLITE_OMIT_VIRTUALTABLE case P4_VTAB: { sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab; - sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule); + sqlite3_snprintf(nTemp, zTemp, "vtab:%p", pVtab); break; } #endif @@ -65941,13 +66571,29 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ else if( pCx->pVtabCursor ){ sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor; const sqlite3_module *pModule = pVtabCursor->pVtab->pModule; - p->inVtabMethod = 1; + assert( pVtabCursor->pVtab->nRef>0 ); + pVtabCursor->pVtab->nRef--; pModule->xClose(pVtabCursor); - p->inVtabMethod = 0; } #endif } +/* +** Close all cursors in the current frame. +*/ +static void closeCursorsInFrame(Vdbe *p){ + if( p->apCsr ){ + int i; + for(i=0; i<p->nCursor; i++){ + VdbeCursor *pC = p->apCsr[i]; + if( pC ){ + sqlite3VdbeFreeCursor(p, pC); + p->apCsr[i] = 0; + } + } + } +} + /* ** Copy the values stored in the VdbeFrame structure to its Vdbe. This ** is used, for example, when a trigger sub-program is halted to restore @@ -65955,6 +66601,7 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ */ SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ Vdbe *v = pFrame->v; + closeCursorsInFrame(v); #ifdef SQLITE_ENABLE_STMT_SCANSTATUS v->anExec = pFrame->anExec; #endif @@ -65989,17 +66636,7 @@ static void closeAllCursors(Vdbe *p){ p->nFrame = 0; } assert( p->nFrame==0 ); - - if( p->apCsr ){ - int i; - for(i=0; i<p->nCursor; i++){ - VdbeCursor *pC = p->apCsr[i]; - if( pC ){ - sqlite3VdbeFreeCursor(p, pC); - p->apCsr[i] = 0; - } - } - } + closeCursorsInFrame(p); if( p->aMem ){ releaseMemArray(&p->aMem[1], p->nMem); } @@ -66302,7 +66939,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ ** doing this the directory is synced again before any individual ** transaction files are deleted. */ - rc = sqlite3OsDelete(pVfs, zMaster, 1); + rc = sqlite3OsDelete(pVfs, zMaster, needSync); sqlite3DbFree(db, zMaster); zMaster = 0; if( rc ){ @@ -67532,7 +68169,8 @@ static void vdbeAssertFieldCountWithinLimits( if( CORRUPT_DB ) return; idx = getVarint32(aKey, szHdr); - assert( szHdr<=nKey ); + assert( nKey>=0 ); + assert( szHdr<=(u32)nKey ); while( idx<szHdr ){ idx += getVarint32(aKey+idx, notUsed); nField++; @@ -67743,7 +68381,7 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){ ** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the ** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db). */ -static int vdbeRecordCompareWithSkip( +SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( int nKey1, const void *pKey1, /* Left key */ UnpackedRecord *pPKey2, /* Right key */ int bSkip /* If true, skip the first field */ @@ -67929,7 +68567,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare( int nKey1, const void *pKey1, /* Left key */ UnpackedRecord *pPKey2 /* Right key */ ){ - return vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0); + return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0); } @@ -68017,7 +68655,7 @@ static int vdbeRecordCompareInt( }else if( pPKey2->nField>1 ){ /* The first fields of the two keys are equal. Compare the trailing ** fields. */ - res = vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); + res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); }else{ /* The first fields of the two keys are equal and there are no trailing ** fields. Return pPKey2->default_rc in this case. */ @@ -68065,7 +68703,7 @@ static int vdbeRecordCompareString( res = nStr - pPKey2->aMem[0].n; if( res==0 ){ if( pPKey2->nField>1 ){ - res = vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); + res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); }else{ res = pPKey2->default_rc; } @@ -68369,7 +69007,7 @@ SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){ ** collating sequences are registered or if an authorizer function is ** added or changed. */ -SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){ +SQLITE_API int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; return p==0 || p->expired; } @@ -68406,7 +69044,7 @@ static int vdbeSafetyNotNull(Vdbe *p){ ** This routine sets the error code and string returned by ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). */ -SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){ +SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL @@ -68432,7 +69070,7 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){ ** This routine sets the error code and string returned by ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). */ -SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){ +SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ rc = SQLITE_OK; @@ -68451,7 +69089,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){ /* ** Set all the parameters in the compiled SQL statement to NULL. */ -SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ +SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt *pStmt){ int i; int rc = SQLITE_OK; Vdbe *p = (Vdbe*)pStmt; @@ -68475,7 +69113,7 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ ** The following routines extract information from a Mem or sqlite3_value ** structure. */ -SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){ +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value *pVal){ Mem *p = (Mem*)pVal; if( p->flags & (MEM_Blob|MEM_Str) ){ sqlite3VdbeMemExpandBlob(p); @@ -68485,36 +69123,40 @@ SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){ return sqlite3_value_text(pVal); } } -SQLITE_API int sqlite3_value_bytes(sqlite3_value *pVal){ +SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value *pVal){ return sqlite3ValueBytes(pVal, SQLITE_UTF8); } -SQLITE_API int sqlite3_value_bytes16(sqlite3_value *pVal){ +SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value *pVal){ return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE); } -SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){ +SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value *pVal){ return sqlite3VdbeRealValue((Mem*)pVal); } -SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){ +SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value *pVal){ return (int)sqlite3VdbeIntValue((Mem*)pVal); } -SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){ +SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value *pVal){ return sqlite3VdbeIntValue((Mem*)pVal); } -SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ +SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value *pVal){ return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *sqlite3_value_text16(sqlite3_value* pVal){ +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value* pVal){ return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); } -SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *pVal){ +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value *pVal){ return sqlite3ValueText(pVal, SQLITE_UTF16BE); } -SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){ +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value *pVal){ return sqlite3ValueText(pVal, SQLITE_UTF16LE); } #endif /* SQLITE_OMIT_UTF16 */ -SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){ +/* EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five +** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating +** point number string BLOB NULL +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value* pVal){ static const u8 aType[] = { SQLITE_BLOB, /* 0x00 */ SQLITE_NULL, /* 0x01 */ @@ -68590,7 +69232,7 @@ static int invokeValueDestructor( if( pCtx ) sqlite3_result_error_toobig(pCtx); return SQLITE_TOOBIG; } -SQLITE_API void sqlite3_result_blob( +SQLITE_API void SQLITE_STDCALL sqlite3_result_blob( sqlite3_context *pCtx, const void *z, int n, @@ -68600,7 +69242,7 @@ SQLITE_API void sqlite3_result_blob( assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, 0, xDel); } -SQLITE_API void sqlite3_result_blob64( +SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64( sqlite3_context *pCtx, const void *z, sqlite3_uint64 n, @@ -68614,37 +69256,37 @@ SQLITE_API void sqlite3_result_blob64( setResultStrOrError(pCtx, z, (int)n, 0, xDel); } } -SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ +SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context *pCtx, double rVal){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetDouble(pCtx->pOut, rVal); } -SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ +SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; pCtx->fErrorOrAux = 1; sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ +SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; pCtx->fErrorOrAux = 1; sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); } #endif -SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){ +SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context *pCtx, int iVal){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal); } -SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ +SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); } -SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){ +SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); } -SQLITE_API void sqlite3_result_text( +SQLITE_API void SQLITE_STDCALL sqlite3_result_text( sqlite3_context *pCtx, const char *z, int n, @@ -68653,7 +69295,7 @@ SQLITE_API void sqlite3_result_text( assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); } -SQLITE_API void sqlite3_result_text64( +SQLITE_API void SQLITE_STDCALL sqlite3_result_text64( sqlite3_context *pCtx, const char *z, sqlite3_uint64 n, @@ -68670,7 +69312,7 @@ SQLITE_API void sqlite3_result_text64( } } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API void sqlite3_result_text16( +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16( sqlite3_context *pCtx, const void *z, int n, @@ -68679,7 +69321,7 @@ SQLITE_API void sqlite3_result_text16( assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel); } -SQLITE_API void sqlite3_result_text16be( +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be( sqlite3_context *pCtx, const void *z, int n, @@ -68688,7 +69330,7 @@ SQLITE_API void sqlite3_result_text16be( assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel); } -SQLITE_API void sqlite3_result_text16le( +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le( sqlite3_context *pCtx, const void *z, int n, @@ -68698,17 +69340,20 @@ SQLITE_API void sqlite3_result_text16le( setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel); } #endif /* SQLITE_OMIT_UTF16 */ -SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ +SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemCopy(pCtx->pOut, pValue); } -SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ +SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n); } -SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ pCtx->isError = errCode; pCtx->fErrorOrAux = 1; +#ifdef SQLITE_DEBUG + if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; +#endif if( pCtx->pOut->flags & MEM_Null ){ sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1, SQLITE_UTF8, SQLITE_STATIC); @@ -68716,7 +69361,7 @@ SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ } /* Force an SQLITE_TOOBIG error. */ -SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_TOOBIG; pCtx->fErrorOrAux = 1; @@ -68725,7 +69370,7 @@ SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ } /* An SQLITE_NOMEM error. */ -SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){ +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); pCtx->isError = SQLITE_NOMEM; @@ -68789,7 +69434,7 @@ static int sqlite3Step(Vdbe *p){ ** or SQLITE_BUSY error. */ #ifdef SQLITE_OMIT_AUTORESET - if( p->rc==SQLITE_BUSY || p->rc==SQLITE_LOCKED ){ + if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){ sqlite3_reset((sqlite3_stmt*)p); }else{ return SQLITE_MISUSE_BKPT; @@ -68835,6 +69480,9 @@ static int sqlite3Step(Vdbe *p){ if( p->bIsReader ) db->nVdbeRead++; p->pc = 0; } +#ifdef SQLITE_DEBUG + p->rcApp = SQLITE_OK; +#endif #ifndef SQLITE_OMIT_EXPLAIN if( p->explain ){ rc = sqlite3VdbeList(p); @@ -68879,7 +69527,7 @@ end_of_step: assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR || rc==SQLITE_BUSY || rc==SQLITE_MISUSE ); - assert( p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE ); + assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp ); if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){ /* If this statement was prepared using sqlite3_prepare_v2(), and an ** error has occurred, then return the error code in p->rc to the @@ -68895,7 +69543,7 @@ end_of_step: ** sqlite3Step() to do most of the work. If a schema error occurs, ** call sqlite3Reprepare() and try again. */ -SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ +SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt *pStmt){ int rc = SQLITE_OK; /* Result from sqlite3Step() */ int rc2 = SQLITE_OK; /* Result from sqlite3Reprepare() */ Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */ @@ -68946,7 +69594,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ ** Extract the user data from a sqlite3_context structure and return a ** pointer to it. */ -SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ +SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context *p){ assert( p && p->pFunc ); return p->pFunc->pUserData; } @@ -68961,22 +69609,32 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ ** sqlite3_create_function16() routines that originally registered the ** application defined function. */ -SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ +SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context *p){ assert( p && p->pFunc ); return p->pOut->db; } /* -** Return the current time for a statement +** Return the current time for a statement. If the current time +** is requested more than once within the same run of a single prepared +** statement, the exact same time is returned for each invocation regardless +** of the amount of time that elapses between invocations. In other words, +** the time returned is always the time of the first call. */ SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ - Vdbe *v = p->pVdbe; int rc; - if( v->iCurrentTime==0 ){ - rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, &v->iCurrentTime); - if( rc ) v->iCurrentTime = 0; +#ifndef SQLITE_ENABLE_STAT3_OR_STAT4 + sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime; + assert( p->pVdbe!=0 ); +#else + sqlite3_int64 iTime = 0; + sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime; +#endif + if( *piTime==0 ){ + rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime); + if( rc ) *piTime = 0; } - return v->iCurrentTime; + return *piTime; } /* @@ -69027,7 +69685,7 @@ static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){ ** context is allocated on the first call. Subsequent calls return the ** same context that was returned on prior calls. */ -SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ +SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context *p, int nByte){ assert( p && p->pFunc && p->pFunc->xStep ); assert( sqlite3_mutex_held(p->pOut->db->mutex) ); testcase( nByte<0 ); @@ -69042,10 +69700,15 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ ** Return the auxiliary data pointer, if any, for the iArg'th argument to ** the user-function defined by pCtx. */ -SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ +SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ AuxData *pAuxData; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); +#if SQLITE_ENABLE_STAT3_OR_STAT4 + if( pCtx->pVdbe==0 ) return 0; +#else + assert( pCtx->pVdbe!=0 ); +#endif for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; } @@ -69058,7 +69721,7 @@ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ ** argument to the user-function defined by pCtx. Any previous value is ** deleted by calling the delete function specified when it was set. */ -SQLITE_API void sqlite3_set_auxdata( +SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata( sqlite3_context *pCtx, int iArg, void *pAux, @@ -69069,6 +69732,11 @@ SQLITE_API void sqlite3_set_auxdata( assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); if( iArg<0 ) goto failed; +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + if( pVdbe==0 ) goto failed; +#else + assert( pVdbe!=0 ); +#endif for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; @@ -69108,7 +69776,7 @@ failed: ** implementations should keep their own counts within their aggregate ** context. */ -SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){ +SQLITE_API int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context *p){ assert( p && p->pMem && p->pFunc && p->pFunc->xStep ); return p->pMem->n; } @@ -69117,7 +69785,7 @@ SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){ /* ** Return the number of columns in the result set for the statement pStmt. */ -SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){ +SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt){ Vdbe *pVm = (Vdbe *)pStmt; return pVm ? pVm->nResColumn : 0; } @@ -69126,7 +69794,7 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){ ** Return the number of values available from the current row of the ** currently executing statement pStmt. */ -SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){ +SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt){ Vdbe *pVm = (Vdbe *)pStmt; if( pVm==0 || pVm->pResultSet==0 ) return 0; return pVm->nResColumn; @@ -69228,7 +69896,7 @@ static void columnMallocFailure(sqlite3_stmt *pStmt) ** The following routines are used to access elements of the current row ** in the result set. */ -SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){ +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt *pStmt, int i){ const void *val; val = sqlite3_value_blob( columnMem(pStmt,i) ); /* Even though there is no encoding conversion, value_blob() might @@ -69238,37 +69906,37 @@ SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){ columnMallocFailure(pStmt); return val; } -SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){ +SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){ int val = sqlite3_value_bytes( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } -SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){ +SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){ int val = sqlite3_value_bytes16( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } -SQLITE_API double sqlite3_column_double(sqlite3_stmt *pStmt, int i){ +SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt *pStmt, int i){ double val = sqlite3_value_double( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } -SQLITE_API int sqlite3_column_int(sqlite3_stmt *pStmt, int i){ +SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt *pStmt, int i){ int val = sqlite3_value_int( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } -SQLITE_API sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){ +SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt *pStmt, int i){ sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } -SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){ +SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt *pStmt, int i){ const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } -SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){ +SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt *pStmt, int i){ Mem *pOut = columnMem(pStmt, i); if( pOut->flags&MEM_Static ){ pOut->flags &= ~MEM_Static; @@ -69278,13 +69946,13 @@ SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){ return (sqlite3_value *)pOut; } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){ +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt *pStmt, int i){ const void *val = sqlite3_value_text16( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } #endif /* SQLITE_OMIT_UTF16 */ -SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){ +SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt *pStmt, int i){ int iType = sqlite3_value_type( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return iType; @@ -69348,12 +70016,12 @@ static const void *columnName( ** Return the name of the Nth column of the result set returned by SQL ** statement pStmt. */ -SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt *pStmt, int N){ return columnName( pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME); } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){ +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt *pStmt, int N){ return columnName( pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME); } @@ -69373,12 +70041,12 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){ ** Return the column declaration type (if applicable) of the 'i'th column ** of the result set of SQL statement pStmt. */ -SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){ return columnName( pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE); } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){ +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){ return columnName( pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE); } @@ -69391,12 +70059,12 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){ ** NULL is returned if the result column is an expression or constant or ** anything else which is not an unambiguous reference to a database column. */ -SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){ return columnName( pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE); } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){ +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){ return columnName( pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE); } @@ -69407,12 +70075,12 @@ SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N ** NULL is returned if the result column is an expression or constant or ** anything else which is not an unambiguous reference to a database column. */ -SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){ return columnName( pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE); } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){ +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){ return columnName( pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE); } @@ -69423,12 +70091,12 @@ SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){ ** NULL is returned if the result column is an expression or constant or ** anything else which is not an unambiguous reference to a database column. */ -SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){ return columnName( pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN); } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ return columnName( pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN); } @@ -69529,7 +70197,7 @@ static int bindText( /* ** Bind a blob value to an SQL statement variable. */ -SQLITE_API int sqlite3_bind_blob( +SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob( sqlite3_stmt *pStmt, int i, const void *zData, @@ -69538,7 +70206,7 @@ SQLITE_API int sqlite3_bind_blob( ){ return bindText(pStmt, i, zData, nData, xDel, 0); } -SQLITE_API int sqlite3_bind_blob64( +SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64( sqlite3_stmt *pStmt, int i, const void *zData, @@ -69552,7 +70220,7 @@ SQLITE_API int sqlite3_bind_blob64( return bindText(pStmt, i, zData, (int)nData, xDel, 0); } } -SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ int rc; Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, i); @@ -69562,10 +70230,10 @@ SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ } return rc; } -SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){ return sqlite3_bind_int64(p, i, (i64)iValue); } -SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ int rc; Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, i); @@ -69575,7 +70243,7 @@ SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValu } return rc; } -SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ int rc; Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, i); @@ -69584,7 +70252,7 @@ SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ } return rc; } -SQLITE_API int sqlite3_bind_text( +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text( sqlite3_stmt *pStmt, int i, const char *zData, @@ -69593,7 +70261,7 @@ SQLITE_API int sqlite3_bind_text( ){ return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8); } -SQLITE_API int sqlite3_bind_text64( +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64( sqlite3_stmt *pStmt, int i, const char *zData, @@ -69610,7 +70278,7 @@ SQLITE_API int sqlite3_bind_text64( } } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API int sqlite3_bind_text16( +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16( sqlite3_stmt *pStmt, int i, const void *zData, @@ -69620,7 +70288,7 @@ SQLITE_API int sqlite3_bind_text16( return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE); } #endif /* SQLITE_OMIT_UTF16 */ -SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ int rc; switch( sqlite3_value_type((sqlite3_value*)pValue) ){ case SQLITE_INTEGER: { @@ -69651,7 +70319,7 @@ SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_valu } return rc; } -SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ int rc; Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, i); @@ -69666,7 +70334,7 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ ** Return the number of wildcards that can be potentially bound to. ** This routine is added to support DBD::SQLite. */ -SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; return p ? p->nVar : 0; } @@ -69677,7 +70345,7 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ ** ** The result is always UTF-8. */ -SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ +SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ Vdbe *p = (Vdbe*)pStmt; if( p==0 || i<1 || i>p->nzVar ){ return 0; @@ -69705,7 +70373,7 @@ SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nNa } return 0; } -SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){ return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName)); } @@ -69739,7 +70407,7 @@ SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt ** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise ** SQLITE_OK is returned. */ -SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ +SQLITE_API int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ Vdbe *pFrom = (Vdbe*)pFromStmt; Vdbe *pTo = (Vdbe*)pToStmt; if( pFrom->nVar!=pTo->nVar ){ @@ -69761,7 +70429,7 @@ SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt * ** the first argument to the sqlite3_prepare() that was used to create ** the statement in the first place. */ -SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){ +SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt *pStmt){ return pStmt ? ((Vdbe*)pStmt)->db : 0; } @@ -69769,14 +70437,14 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){ ** Return true if the prepared statement is guaranteed to not modify the ** database. */ -SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){ +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt){ return pStmt ? ((Vdbe*)pStmt)->readOnly : 1; } /* ** Return true if the prepared statement is in need of being reset. */ -SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt *pStmt){ Vdbe *v = (Vdbe*)pStmt; return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN; } @@ -69787,7 +70455,7 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ ** prepared statement for the database connection. Return NULL if there ** are no more. */ -SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){ +SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){ sqlite3_stmt *pNext; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(pDb) ){ @@ -69808,7 +70476,7 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){ /* ** Return the value of a status counter for a prepared statement */ -SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ Vdbe *pVdbe = (Vdbe*)pStmt; u32 v; #ifdef SQLITE_ENABLE_API_ARMOR @@ -69826,7 +70494,7 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ /* ** Return status data for a single loop within query pStmt. */ -SQLITE_API int sqlite3_stmt_scanstatus( +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement being queried */ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Which metric to return */ @@ -69885,7 +70553,7 @@ SQLITE_API int sqlite3_stmt_scanstatus( /* ** Zero all counters associated with the sqlite3_stmt_scanstatus() data. */ -SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ +SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; memset(p->anExec, 0, p->nOp * sizeof(i64)); } @@ -69977,9 +70645,8 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( char zBase[100]; /* Initial working space */ db = p->db; - sqlite3StrAccumInit(&out, zBase, sizeof(zBase), + sqlite3StrAccumInit(&out, db, zBase, sizeof(zBase), db->aLimit[SQLITE_LIMIT_LENGTH]); - out.db = db; if( db->nVdbeExec>1 ){ while( *zRawSql ){ const char *zStart = zRawSql; @@ -69988,6 +70655,8 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( assert( (zRawSql - zStart) > 0 ); sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); } + }else if( p->nVar==0 ){ + sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql)); }else{ while( zRawSql[0] ){ n = findNextHostParameter(zRawSql, &nToken); @@ -70004,10 +70673,12 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( idx = nextIndex; } }else{ - assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' ); + assert( zRawSql[0]==':' || zRawSql[0]=='$' || + zRawSql[0]=='@' || zRawSql[0]=='#' ); testcase( zRawSql[0]==':' ); testcase( zRawSql[0]=='$' ); testcase( zRawSql[0]=='@' ); + testcase( zRawSql[0]=='#' ); idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken); assert( idx>0 ); } @@ -70375,6 +71046,7 @@ static void applyAffinity( if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){ sqlite3VdbeMemStringify(pRec, enc, 1); } + pRec->flags &= ~(MEM_Real|MEM_Int); } } @@ -70384,7 +71056,7 @@ static void applyAffinity( ** is appropriate. But only do the conversion if it is possible without ** loss of information and return the revised type of the argument. */ -SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){ +SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value *pVal){ int eType = sqlite3_value_type(pVal); if( eType==SQLITE_TEXT ){ Mem *pMem = (Mem*)pVal; @@ -70682,6 +71354,21 @@ static int checkSavepointCount(sqlite3 *db){ } #endif +/* +** Return the register of pOp->p2 after first preparing it to be +** overwritten with an integer value. +*/ +static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ + Mem *pOut; + assert( pOp->p2>0 ); + assert( pOp->p2<=(p->nMem-p->nCursor) ); + pOut = &p->aMem[pOp->p2]; + memAboutToChange(p, pOut); + if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut); + pOut->flags = MEM_Int; + return pOut; +} + /* ** Execute as much of a VDBE program as we can. @@ -70690,9 +71377,11 @@ static int checkSavepointCount(sqlite3 *db){ SQLITE_PRIVATE int sqlite3VdbeExec( Vdbe *p /* The VDBE */ ){ - int pc=0; /* The program counter */ Op *aOp = p->aOp; /* Copy of p->aOp */ - Op *pOp; /* Current operation */ + Op *pOp = aOp; /* Current operation */ +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) + Op *pOrigOp; /* Value of pOp at the top of the loop */ +#endif int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ @@ -70768,23 +71457,22 @@ SQLITE_PRIVATE int sqlite3VdbeExec( } sqlite3EndBenignMalloc(); #endif - for(pc=p->pc; rc==SQLITE_OK; pc++){ - assert( pc>=0 && pc<p->nOp ); + for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){ + assert( pOp>=aOp && pOp<&aOp[p->nOp]); if( db->mallocFailed ) goto no_mem; #ifdef VDBE_PROFILE start = sqlite3Hwtime(); #endif nVmStep++; - pOp = &aOp[pc]; #ifdef SQLITE_ENABLE_STMT_SCANSTATUS - if( p->anExec ) p->anExec[pc]++; + if( p->anExec ) p->anExec[(int)(pOp-aOp)]++; #endif /* Only allow tracing if SQLITE_DEBUG is defined. */ #ifdef SQLITE_DEBUG if( db->flags & SQLITE_VdbeTrace ){ - sqlite3VdbePrintOp(stdout, pc, pOp); + sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp); } #endif @@ -70801,23 +71489,9 @@ SQLITE_PRIVATE int sqlite3VdbeExec( } #endif - /* On any opcode with the "out2-prerelease" tag, free any - ** external allocations out of mem[p2] and set mem[p2] to be - ** an undefined integer. Opcodes will either fill in the integer - ** value or convert mem[p2] to a different type. - */ - assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); - if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){ - assert( pOp->p2>0 ); - assert( pOp->p2<=(p->nMem-p->nCursor) ); - pOut = &aMem[pOp->p2]; - memAboutToChange(p, pOut); - if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut); - pOut->flags = MEM_Int; - } - /* Sanity checking on other operands */ #ifdef SQLITE_DEBUG + assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); if( (pOp->opflags & OPFLG_IN1)!=0 ){ assert( pOp->p1>0 ); assert( pOp->p1<=(p->nMem-p->nCursor) ); @@ -70850,6 +71524,9 @@ SQLITE_PRIVATE int sqlite3VdbeExec( memAboutToChange(p, &aMem[pOp->p3]); } #endif +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) + pOrigOp = pOp; +#endif switch( pOp->opcode ){ @@ -70873,7 +71550,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec( ** ** Other keywords in the comment that follows each case are used to ** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[]. -** Keywords include: in1, in2, in3, out2_prerelease, out2, out3. See +** Keywords include: in1, in2, in3, out2, out3. See ** the mkopcodeh.awk script for additional information. ** ** Documentation about VDBE opcodes is generated by scanning this file @@ -70901,7 +71578,8 @@ SQLITE_PRIVATE int sqlite3VdbeExec( ** to the current line should be indented for EXPLAIN output. */ case OP_Goto: { /* jump */ - pc = pOp->p2 - 1; +jump_to_p2_and_check_for_interrupt: + pOp = &aOp[pOp->p2 - 1]; /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev, ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon @@ -70946,9 +71624,13 @@ case OP_Gosub: { /* jump */ assert( VdbeMemDynamic(pIn1)==0 ); memAboutToChange(p, pIn1); pIn1->flags = MEM_Int; - pIn1->u.i = pc; + pIn1->u.i = (int)(pOp-aOp); REGISTER_TRACE(pOp->p1, pIn1); - pc = pOp->p2 - 1; + + /* Most jump operations do a goto to this spot in order to update + ** the pOp pointer. */ +jump_to_p2: + pOp = &aOp[pOp->p2 - 1]; break; } @@ -70960,7 +71642,7 @@ case OP_Gosub: { /* jump */ case OP_Return: { /* in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags==MEM_Int ); - pc = (int)pIn1->u.i; + pOp = &aOp[pIn1->u.i]; pIn1->flags = MEM_Undefined; break; } @@ -70984,7 +71666,7 @@ case OP_InitCoroutine: { /* jump */ assert( !VdbeMemDynamic(pOut) ); pOut->u.i = pOp->p3 - 1; pOut->flags = MEM_Int; - if( pOp->p2 ) pc = pOp->p2 - 1; + if( pOp->p2 ) goto jump_to_p2; break; } @@ -71004,7 +71686,7 @@ case OP_EndCoroutine: { /* in1 */ pCaller = &aOp[pIn1->u.i]; assert( pCaller->opcode==OP_Yield ); assert( pCaller->p2>=0 && pCaller->p2<p->nOp ); - pc = pCaller->p2 - 1; + pOp = &aOp[pCaller->p2 - 1]; pIn1->flags = MEM_Undefined; break; } @@ -71028,9 +71710,9 @@ case OP_Yield: { /* in1, jump */ assert( VdbeMemDynamic(pIn1)==0 ); pIn1->flags = MEM_Int; pcDest = (int)pIn1->u.i; - pIn1->u.i = pc; + pIn1->u.i = (int)(pOp - aOp); REGISTER_TRACE(pOp->p1, pIn1); - pc = pcDest; + pOp = &aOp[pcDest]; break; } @@ -71081,30 +71763,34 @@ case OP_HaltIfNull: { /* in3 */ case OP_Halt: { const char *zType; const char *zLogFmt; + VdbeFrame *pFrame; + int pcx; + pcx = (int)(pOp - aOp); if( pOp->p1==SQLITE_OK && p->pFrame ){ /* Halt the sub-program. Return control to the parent frame. */ - VdbeFrame *pFrame = p->pFrame; + pFrame = p->pFrame; p->pFrame = pFrame->pParent; p->nFrame--; sqlite3VdbeSetChanges(db, p->nChange); - pc = sqlite3VdbeFrameRestore(pFrame); + pcx = sqlite3VdbeFrameRestore(pFrame); lastRowid = db->lastRowid; if( pOp->p2==OE_Ignore ){ - /* Instruction pc is the OP_Program that invoked the sub-program + /* Instruction pcx is the OP_Program that invoked the sub-program ** currently being halted. If the p2 instruction of this OP_Halt ** instruction is set to OE_Ignore, then the sub-program is throwing ** an IGNORE exception. In this case jump to the address specified ** as the p2 of the calling OP_Program. */ - pc = p->aOp[pc].p2-1; + pcx = p->aOp[pcx].p2-1; } aOp = p->aOp; aMem = p->aMem; + pOp = &aOp[pcx]; break; } p->rc = pOp->p1; p->errorAction = (u8)pOp->p2; - p->pc = pc; + p->pc = pcx; if( p->rc ){ if( pOp->p5 ){ static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", @@ -71128,7 +71814,7 @@ case OP_Halt: { }else{ sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType); } - sqlite3_log(pOp->p1, zLogFmt, pc, p->zSql, p->zErrMsg); + sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg); } rc = sqlite3VdbeHalt(p); assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); @@ -71147,7 +71833,8 @@ case OP_Halt: { ** ** The 32-bit integer value P1 is written into register P2. */ -case OP_Integer: { /* out2-prerelease */ +case OP_Integer: { /* out2 */ + pOut = out2Prerelease(p, pOp); pOut->u.i = pOp->p1; break; } @@ -71158,7 +71845,8 @@ case OP_Integer: { /* out2-prerelease */ ** P4 is a pointer to a 64-bit integer value. ** Write that value into register P2. */ -case OP_Int64: { /* out2-prerelease */ +case OP_Int64: { /* out2 */ + pOut = out2Prerelease(p, pOp); assert( pOp->p4.pI64!=0 ); pOut->u.i = *pOp->p4.pI64; break; @@ -71171,7 +71859,8 @@ case OP_Int64: { /* out2-prerelease */ ** P4 is a pointer to a 64-bit floating point value. ** Write that value into register P2. */ -case OP_Real: { /* same as TK_FLOAT, out2-prerelease */ +case OP_Real: { /* same as TK_FLOAT, out2 */ + pOut = out2Prerelease(p, pOp); pOut->flags = MEM_Real; assert( !sqlite3IsNaN(*pOp->p4.pReal) ); pOut->u.r = *pOp->p4.pReal; @@ -71183,12 +71872,13 @@ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */ ** Synopsis: r[P2]='P4' ** ** P4 points to a nul terminated UTF-8 string. This opcode is transformed -** into a String before it is executed for the first time. During +** into a String opcode before it is executed for the first time. During ** this transformation, the length of string P4 is computed and stored ** as the P1 parameter. */ -case OP_String8: { /* same as TK_STRING, out2-prerelease */ +case OP_String8: { /* same as TK_STRING, out2 */ assert( pOp->p4.z!=0 ); + pOut = out2Prerelease(p, pOp); pOp->opcode = OP_String; pOp->p1 = sqlite3Strlen30(pOp->p4.z); @@ -71215,18 +71905,31 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */ /* Fall through to the next case, OP_String */ } -/* Opcode: String P1 P2 * P4 * +/* Opcode: String P1 P2 P3 P4 P5 ** Synopsis: r[P2]='P4' (len=P1) ** ** The string value P4 of length P1 (bytes) is stored in register P2. +** +** If P5!=0 and the content of register P3 is greater than zero, then +** the datatype of the register P2 is converted to BLOB. The content is +** the same sequence of bytes, it is merely interpreted as a BLOB instead +** of a string, as if it had been CAST. */ -case OP_String: { /* out2-prerelease */ +case OP_String: { /* out2 */ assert( pOp->p4.z!=0 ); + pOut = out2Prerelease(p, pOp); pOut->flags = MEM_Str|MEM_Static|MEM_Term; pOut->z = pOp->p4.z; pOut->n = pOp->p1; pOut->enc = encoding; UPDATE_MAX_BLOBSIZE(pOut); + if( pOp->p5 ){ + assert( pOp->p3>0 ); + assert( pOp->p3<=(p->nMem-p->nCursor) ); + pIn3 = &aMem[pOp->p3]; + assert( pIn3->flags & MEM_Int ); + if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term; + } break; } @@ -71242,9 +71945,10 @@ case OP_String: { /* out2-prerelease */ ** NULL values will not compare equal even if SQLITE_NULLEQ is set on ** OP_Ne or OP_Eq. */ -case OP_Null: { /* out2-prerelease */ +case OP_Null: { /* out2 */ int cnt; u16 nullFlag; + pOut = out2Prerelease(p, pOp); cnt = pOp->p3-pOp->p2; assert( pOp->p3<=(p->nMem-p->nCursor) ); pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; @@ -71279,8 +71983,9 @@ case OP_SoftNull: { ** P4 points to a blob of data P1 bytes long. Store this ** blob in register P2. */ -case OP_Blob: { /* out2-prerelease */ +case OP_Blob: { /* out2 */ assert( pOp->p1 <= SQLITE_MAX_LENGTH ); + pOut = out2Prerelease(p, pOp); sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); pOut->enc = encoding; UPDATE_MAX_BLOBSIZE(pOut); @@ -71295,7 +72000,7 @@ case OP_Blob: { /* out2-prerelease */ ** If the parameter is named, then its name appears in P4. ** The P4 value is used by sqlite3_bind_parameter_name(). */ -case OP_Variable: { /* out2-prerelease */ +case OP_Variable: { /* out2 */ Mem *pVar; /* Value being transferred */ assert( pOp->p1>0 && pOp->p1<=p->nVar ); @@ -71304,6 +72009,7 @@ case OP_Variable: { /* out2-prerelease */ if( sqlite3VdbeMemTooBig(pVar) ){ goto too_big; } + pOut = out2Prerelease(p, pOp); sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static); UPDATE_MAX_BLOBSIZE(pOut); break; @@ -71338,10 +72044,11 @@ case OP_Move: { memAboutToChange(p, pOut); sqlite3VdbeMemMove(pOut, pIn1); #ifdef SQLITE_DEBUG - if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){ - pOut->pScopyFrom += p1 - pOp->p2; + if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<pOut ){ + pOut->pScopyFrom += pOp->p2 - p1; } #endif + Deephemeralize(pOut); REGISTER_TRACE(p2++, pOut); pIn1++; pOut++; @@ -71480,7 +72187,7 @@ case OP_ResultRow: { /* Return SQLITE_ROW */ - p->pc = pc + 1; + p->pc = (int)(pOp - aOp) + 1; rc = SQLITE_ROW; goto vdbe_return; } @@ -71673,7 +72380,7 @@ arithmetic_result_is_null: ** ** The interface used by the implementation of the aforementioned functions ** to retrieve the collation sequence set by this opcode is not available -** publicly, only to user functions defined in func.c. +** publicly. Only built-in functions have access to this feature. */ case OP_CollSeq: { assert( pOp->p4type==P4_COLLSEQ ); @@ -71726,7 +72433,7 @@ case OP_Function: { assert( pOp->p4type==P4_FUNCDEF ); ctx.pFunc = pOp->p4.pFunc; - ctx.iOp = pc; + ctx.iOp = (int)(pOp - aOp); ctx.pVdbe = p; MemSetTypeFlag(ctx.pOut, MEM_Null); ctx.fErrorOrAux = 0; @@ -71740,7 +72447,7 @@ case OP_Function: { sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut)); rc = ctx.isError; } - sqlite3VdbeDeleteAuxData(p, pc, pOp->p1); + sqlite3VdbeDeleteAuxData(p, (int)(pOp - aOp), pOp->p1); } /* Copy the result of the function into register P3 */ @@ -71869,8 +72576,7 @@ case OP_MustBeInt: { /* jump, in1 */ rc = SQLITE_MISMATCH; goto abort_due_to_error; }else{ - pc = pOp->p2 - 1; - break; + goto jump_to_p2; } } } @@ -72056,7 +72762,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ }else{ VdbeBranchTaken(2,3); if( pOp->p5 & SQLITE_JUMPIFNULL ){ - pc = pOp->p2-1; + goto jump_to_p2; } } break; @@ -72076,11 +72782,15 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ testcase( pIn1->flags & MEM_Int ); testcase( pIn1->flags & MEM_Real ); sqlite3VdbeMemStringify(pIn1, encoding, 1); + testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); + flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); } if( (pIn3->flags & MEM_Str)==0 && (pIn3->flags & (MEM_Int|MEM_Real))!=0 ){ testcase( pIn3->flags & MEM_Int ); testcase( pIn3->flags & MEM_Real ); sqlite3VdbeMemStringify(pIn3, encoding, 1); + testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) ); + flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask); } } assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); @@ -72104,6 +72814,12 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ default: res = res>=0; break; } + /* Undo any changes made by applyAffinity() to the input registers. */ + assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); + pIn1->flags = flags1; + assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) ); + pIn3->flags = flags3; + if( pOp->p5 & SQLITE_STOREP2 ){ pOut = &aMem[pOp->p2]; memAboutToChange(p, pOut); @@ -72113,12 +72829,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ }else{ VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3); if( res ){ - pc = pOp->p2-1; + goto jump_to_p2; } } - /* Undo any changes made by applyAffinity() to the input registers. */ - pIn1->flags = flags1; - pIn3->flags = flags3; break; } @@ -72213,11 +72926,11 @@ case OP_Compare: { */ case OP_Jump: { /* jump */ if( iCompare<0 ){ - pc = pOp->p1 - 1; VdbeBranchTaken(0,3); + VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1]; }else if( iCompare==0 ){ - pc = pOp->p2 - 1; VdbeBranchTaken(1,3); + VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1]; }else{ - pc = pOp->p3 - 1; VdbeBranchTaken(2,3); + VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1]; } break; } @@ -72327,7 +73040,7 @@ case OP_Once: { /* jump */ assert( pOp->p1<p->nOnceFlag ); VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2); if( p->aOnceFlag[pOp->p1] ){ - pc = pOp->p2-1; + goto jump_to_p2; }else{ p->aOnceFlag[pOp->p1] = 1; } @@ -72362,7 +73075,7 @@ case OP_IfNot: { /* jump, in1 */ } VdbeBranchTaken(c!=0, 2); if( c ){ - pc = pOp->p2-1; + goto jump_to_p2; } break; } @@ -72376,7 +73089,7 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ pIn1 = &aMem[pOp->p1]; VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2); if( (pIn1->flags & MEM_Null)!=0 ){ - pc = pOp->p2 - 1; + goto jump_to_p2; } break; } @@ -72390,7 +73103,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ pIn1 = &aMem[pOp->p1]; VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2); if( (pIn1->flags & MEM_Null)==0 ){ - pc = pOp->p2 - 1; + goto jump_to_p2; } break; } @@ -72604,7 +73317,7 @@ case OP_Column: { } } - /* If after trying to extra new entries from the header, nHdrParsed is + /* If after trying to extract new entries from the header, nHdrParsed is ** still not up to p2, that means that the record has fewer than p2 ** columns. So the result will be either the default value or a NULL. */ @@ -72728,7 +73441,7 @@ case OP_MakeRecord: { u64 nData; /* Number of bytes of data space */ int nHdr; /* Number of bytes of header space */ i64 nByte; /* Data space required for this record */ - int nZero; /* Number of zero bytes at the end of the record */ + i64 nZero; /* Number of zero bytes at the end of the record */ int nVarint; /* Number of bytes in a varint */ u32 serial_type; /* Type field */ Mem *pData0; /* First field to be combined into the record */ @@ -72820,7 +73533,7 @@ case OP_MakeRecord: { if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++; } nByte = nHdr+nData; - if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } @@ -72871,7 +73584,7 @@ case OP_MakeRecord: { ** opened by cursor P1 in register P2 */ #ifndef SQLITE_OMIT_BTREECOUNT -case OP_Count: { /* out2-prerelease */ +case OP_Count: { /* out2 */ i64 nEntry; BtCursor *pCrsr; @@ -72879,6 +73592,7 @@ case OP_Count: { /* out2-prerelease */ assert( pCrsr ); nEntry = 0; /* Not needed. Only used to silence a warning. */ rc = sqlite3BtreeCount(pCrsr, &nEntry); + pOut = out2Prerelease(p, pOp); pOut->u.i = nEntry; break; } @@ -72992,7 +73706,7 @@ case OP_Savepoint: { } db->autoCommit = 1; if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ - p->pc = pc; + p->pc = (int)(pOp - aOp); db->autoCommit = 0; p->rc = rc = SQLITE_BUSY; goto vdbe_return; @@ -73051,7 +73765,7 @@ case OP_Savepoint: { db->nDeferredImmCons = pSavepoint->nDeferredImmCons; } - if( !isTransaction ){ + if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){ rc = sqlite3VtabSavepoint(db, p1, iSavepoint); if( rc!=SQLITE_OK ) goto abort_due_to_error; } @@ -73111,7 +73825,7 @@ case OP_AutoCommit: { }else{ db->autoCommit = (u8)desiredAutoCommit; if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ - p->pc = pc; + p->pc = (int)(pOp - aOp); db->autoCommit = (u8)(1-desiredAutoCommit); p->rc = rc = SQLITE_BUSY; goto vdbe_return; @@ -73188,7 +73902,7 @@ case OP_Transaction: { if( pBt ){ rc = sqlite3BtreeBeginTrans(pBt, pOp->p2); if( rc==SQLITE_BUSY ){ - p->pc = pc; + p->pc = (int)(pOp - aOp); p->rc = rc = SQLITE_BUSY; goto vdbe_return; } @@ -73218,7 +73932,12 @@ case OP_Transaction: { p->nStmtDefImmCons = db->nDeferredImmCons; } - /* Gather the schema version number for checking */ + /* Gather the schema version number for checking: + ** IMPLEMENTATION-OF: R-32195-19465 The schema version is used by SQLite + ** each time a query is executed to ensure that the internal cache of the + ** schema used when compiling the SQL query matches the schema of the + ** database against which the compiled query is actually executed. + */ sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); iGen = db->aDb[pOp->p1].pSchema->iGeneration; }else{ @@ -73262,7 +73981,7 @@ case OP_Transaction: { ** must be started or there must be an open cursor) before ** executing this instruction. */ -case OP_ReadCookie: { /* out2-prerelease */ +case OP_ReadCookie: { /* out2 */ int iMeta; int iDb; int iCookie; @@ -73276,6 +73995,7 @@ case OP_ReadCookie: { /* out2-prerelease */ assert( DbMaskTest(p->btreeMask, iDb) ); sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); + pOut = out2Prerelease(p, pOp); pOut->u.i = iMeta; break; } @@ -73386,31 +74106,29 @@ case OP_SetCookie: { /* in3 */ ** See also OpenRead. */ case OP_ReopenIdx: { + int nField; + KeyInfo *pKeyInfo; + int p2; + int iDb; + int wrFlag; + Btree *pX; VdbeCursor *pCur; + Db *pDb; - assert( pOp->p5==0 ); + assert( pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); assert( pOp->p4type==P4_KEYINFO ); pCur = p->apCsr[pOp->p1]; if( pCur && pCur->pgnoRoot==(u32)pOp->p2 ){ assert( pCur->iDb==pOp->p3 ); /* Guaranteed by the code generator */ - break; + goto open_cursor_set_hints; } /* If the cursor is not currently open or is open on a different ** index, then fall through into OP_OpenRead to force a reopen */ -} case OP_OpenRead: -case OP_OpenWrite: { - int nField; - KeyInfo *pKeyInfo; - int p2; - int iDb; - int wrFlag; - Btree *pX; - VdbeCursor *pCur; - Db *pDb; +case OP_OpenWrite: - assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); - assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); + assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR|OPFLAG_SEEKEQ))==pOp->p5 ); + assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); assert( p->bIsReader ); assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx || p->readOnly==0 ); @@ -73473,14 +74191,17 @@ case OP_OpenWrite: { pCur->pgnoRoot = p2; rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor); pCur->pKeyInfo = pKeyInfo; - assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); - sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); - /* Set the VdbeCursor.isTable variable. Previous versions of ** SQLite used to check if the root-page flags were sane at this point ** and report database corruption if they were not, but this check has ** since moved into the btree layer. */ pCur->isTable = pOp->p4type!=P4_KEYINFO; + +open_cursor_set_hints: + assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); + assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ ); + sqlite3BtreeCursorHints(pCur->pCursor, + (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); break; } @@ -73596,7 +74317,7 @@ case OP_SequenceTest: { pC = p->apCsr[pOp->p1]; assert( pC->pSorter ); if( (pC->seqCount++)==0 ){ - pc = pOp->p2 - 1; + goto jump_to_p2; } break; } @@ -73741,6 +74462,22 @@ case OP_SeekGT: { /* jump, in3 */ #ifdef SQLITE_DEBUG pC->seekOp = pOp->opcode; #endif + + /* For a cursor with the BTREE_SEEK_EQ hint, only the OP_SeekGE and + ** OP_SeekLE opcodes are allowed, and these must be immediately followed + ** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key. + */ +#ifdef SQLITE_DEBUG + if( sqlite3BtreeCursorHasHint(pC->pCursor, BTREE_SEEK_EQ) ){ + assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE ); + assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT ); + assert( pOp[1].p1==pOp[0].p1 ); + assert( pOp[1].p2==pOp[0].p2 ); + assert( pOp[1].p3==pOp[0].p3 ); + assert( pOp[1].p4.i==pOp[0].p4.i ); + } +#endif + if( pC->isTable ){ /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do @@ -73757,7 +74494,7 @@ case OP_SeekGT: { /* jump, in3 */ if( (pIn3->flags & MEM_Real)==0 ){ /* If the P3 value cannot be converted into any kind of a number, ** then the seek is not possible, so jump to P2 */ - pc = pOp->p2 - 1; VdbeBranchTaken(1,2); + VdbeBranchTaken(1,2); goto jump_to_p2; break; } @@ -73848,7 +74585,7 @@ case OP_SeekGT: { /* jump, in3 */ assert( pOp->p2>0 ); VdbeBranchTaken(res!=0,2); if( res ){ - pc = pOp->p2 - 1; + goto jump_to_p2; } break; } @@ -73942,6 +74679,7 @@ case OP_NoConflict: /* jump, in3 */ case OP_NotFound: /* jump, in3 */ case OP_Found: { /* jump, in3 */ int alreadyExists; + int takeJump; int ii; VdbeCursor *pC; int res; @@ -73964,7 +74702,7 @@ case OP_Found: { /* jump, in3 */ pIn3 = &aMem[pOp->p3]; assert( pC->pCursor!=0 ); assert( pC->isTable==0 ); - pFree = 0; /* Not needed. Only used to suppress a compiler warning. */ + pFree = 0; if( pOp->p4.i>0 ){ r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p4.i; @@ -73987,21 +74725,20 @@ case OP_Found: { /* jump, in3 */ sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); } pIdxKey->default_rc = 0; + takeJump = 0; if( pOp->opcode==OP_NoConflict ){ /* For the OP_NoConflict opcode, take the jump if any of the ** input fields are NULL, since any key with a NULL will not ** conflict */ for(ii=0; ii<pIdxKey->nField; ii++){ if( pIdxKey->aMem[ii].flags & MEM_Null ){ - pc = pOp->p2 - 1; VdbeBranchTaken(1,2); + takeJump = 1; break; } } } rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res); - if( pOp->p4.i==0 ){ - sqlite3DbFree(db, pFree); - } + sqlite3DbFree(db, pFree); if( rc!=SQLITE_OK ){ break; } @@ -74012,10 +74749,10 @@ case OP_Found: { /* jump, in3 */ pC->cacheStatus = CACHE_STALE; if( pOp->opcode==OP_Found ){ VdbeBranchTaken(alreadyExists!=0,2); - if( alreadyExists ) pc = pOp->p2 - 1; + if( alreadyExists ) goto jump_to_p2; }else{ - VdbeBranchTaken(alreadyExists==0,2); - if( !alreadyExists ) pc = pOp->p2 - 1; + VdbeBranchTaken(takeJump||alreadyExists==0,2); + if( takeJump || !alreadyExists ) goto jump_to_p2; } break; } @@ -74064,10 +74801,8 @@ case OP_NotExists: { /* jump, in3 */ pC->cacheStatus = CACHE_STALE; pC->deferredMoveto = 0; VdbeBranchTaken(res!=0,2); - if( res!=0 ){ - pc = pOp->p2 - 1; - } pC->seekResult = res; + if( res!=0 ) goto jump_to_p2; break; } @@ -74079,9 +74814,10 @@ case OP_NotExists: { /* jump, in3 */ ** The sequence number on the cursor is incremented after this ** instruction. */ -case OP_Sequence: { /* out2-prerelease */ +case OP_Sequence: { /* out2 */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( p->apCsr[pOp->p1]!=0 ); + pOut = out2Prerelease(p, pOp); pOut->u.i = p->apCsr[pOp->p1]->seqCount++; break; } @@ -74102,7 +74838,7 @@ case OP_Sequence: { /* out2-prerelease */ ** generated record number. This P3 mechanism is used to help implement the ** AUTOINCREMENT feature. */ -case OP_NewRowid: { /* out2-prerelease */ +case OP_NewRowid: { /* out2 */ i64 v; /* The new rowid */ VdbeCursor *pC; /* Cursor of table to get the new rowid */ int res; /* Result of an sqlite3BtreeLast() */ @@ -74112,6 +74848,7 @@ case OP_NewRowid: { /* out2-prerelease */ v = 0; res = 0; + pOut = out2Prerelease(p, pOp); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); @@ -74425,9 +75162,7 @@ case OP_SorterCompare: { res = 0; rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); VdbeBranchTaken(res!=0,2); - if( res ){ - pc = pOp->p2-1; - } + if( res ) goto jump_to_p2; break; }; @@ -74556,12 +75291,13 @@ case OP_RowData: { ** be a separate OP_VRowid opcode for use with virtual tables, but this ** one opcode now works for both table types. */ -case OP_Rowid: { /* out2-prerelease */ +case OP_Rowid: { /* out2 */ VdbeCursor *pC; i64 v; sqlite3_vtab *pVtab; const sqlite3_module *pModule; + pOut = out2Prerelease(p, pOp); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); @@ -74614,7 +75350,7 @@ case OP_NullRow: { break; } -/* Opcode: Last P1 P2 * * * +/* Opcode: Last P1 P2 P3 * * ** ** The next use of the Rowid or Column or Prev instruction for P1 ** will refer to the last entry in the database table or index. @@ -74641,12 +75377,13 @@ case OP_Last: { /* jump */ pC->nullRow = (u8)res; pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; + pC->seekResult = pOp->p3; #ifdef SQLITE_DEBUG pC->seekOp = OP_Last; #endif if( pOp->p2>0 ){ VdbeBranchTaken(res!=0,2); - if( res ) pc = pOp->p2 - 1; + if( res ) goto jump_to_p2; } break; } @@ -74710,9 +75447,7 @@ case OP_Rewind: { /* jump */ pC->nullRow = (u8)res; assert( pOp->p2>0 && pOp->p2<p->nOp ); VdbeBranchTaken(res!=0,2); - if( res ){ - pc = pOp->p2 - 1; - } + if( res ) goto jump_to_p2; break; } @@ -74823,11 +75558,11 @@ next_tail: VdbeBranchTaken(res==0,2); if( res==0 ){ pC->nullRow = 0; - pc = pOp->p2 - 1; p->aCounter[pOp->p5]++; #ifdef SQLITE_TEST sqlite3_search_count++; #endif + goto jump_to_p2_and_check_for_interrupt; }else{ pC->nullRow = 1; } @@ -74935,11 +75670,12 @@ case OP_IdxDelete: { ** ** See also: Rowid, MakeRecord. */ -case OP_IdxRowid: { /* out2-prerelease */ +case OP_IdxRowid: { /* out2 */ BtCursor *pCrsr; VdbeCursor *pC; i64 rowid; + pOut = out2Prerelease(p, pOp); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); @@ -75052,9 +75788,7 @@ case OP_IdxGE: { /* jump */ res++; } VdbeBranchTaken(res>0,2); - if( res>0 ){ - pc = pOp->p2 - 1 ; - } + if( res>0 ) goto jump_to_p2; break; } @@ -75078,32 +75812,18 @@ case OP_IdxGE: { /* jump */ ** ** See also: Clear */ -case OP_Destroy: { /* out2-prerelease */ +case OP_Destroy: { /* out2 */ int iMoved; - int iCnt; - Vdbe *pVdbe; int iDb; assert( p->readOnly==0 ); -#ifndef SQLITE_OMIT_VIRTUALTABLE - iCnt = 0; - for(pVdbe=db->pVdbe; pVdbe; pVdbe = pVdbe->pNext){ - if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->bIsReader - && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 - ){ - iCnt++; - } - } -#else - iCnt = db->nVdbeRead; -#endif + pOut = out2Prerelease(p, pOp); pOut->flags = MEM_Null; - if( iCnt>1 ){ + if( db->nVdbeRead > db->nVDestroy+1 ){ rc = SQLITE_LOCKED; p->errorAction = OE_Abort; }else{ iDb = pOp->p3; - assert( iCnt==1 ); assert( DbMaskTest(p->btreeMask, iDb) ); iMoved = 0; /* Not needed. Only to silence a warning. */ rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); @@ -75206,12 +75926,13 @@ case OP_ResetSorter: { ** ** See documentation on OP_CreateTable for additional information. */ -case OP_CreateIndex: /* out2-prerelease */ -case OP_CreateTable: { /* out2-prerelease */ +case OP_CreateIndex: /* out2 */ +case OP_CreateTable: { /* out2 */ int pgno; int flags; Db *pDb; + pOut = out2Prerelease(p, pOp); pgno = 0; assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( DbMaskTest(p->btreeMask, pOp->p1) ); @@ -75437,12 +76158,12 @@ case OP_RowSetRead: { /* jump, in1, out3 */ ){ /* The boolean index is empty */ sqlite3VdbeMemSetNull(pIn1); - pc = pOp->p2 - 1; VdbeBranchTaken(1,2); + goto jump_to_p2_and_check_for_interrupt; }else{ /* A value was pulled from the index */ - sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val); VdbeBranchTaken(0,2); + sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val); } goto check_for_interrupt; } @@ -75493,10 +76214,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */ if( iSet ){ exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i); VdbeBranchTaken(exists!=0,2); - if( exists ){ - pc = pOp->p2 - 1; - break; - } + if( exists ) goto jump_to_p2; } if( iSet>=0 ){ sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); @@ -75585,7 +76303,7 @@ case OP_Program: { /* jump */ pFrame->v = p; pFrame->nChildMem = nMem; pFrame->nChildCsr = pProgram->nCsr; - pFrame->pc = pc; + pFrame->pc = (int)(pOp - aOp); pFrame->aMem = p->aMem; pFrame->nMem = p->nMem; pFrame->apCsr = p->apCsr; @@ -75608,7 +76326,7 @@ case OP_Program: { /* jump */ pFrame = pRt->u.pFrame; assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem ); assert( pProgram->nCsr==pFrame->nChildCsr ); - assert( pc==pFrame->pc ); + assert( (int)(pOp - aOp)==pFrame->pc ); } p->nFrame++; @@ -75629,7 +76347,7 @@ case OP_Program: { /* jump */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS p->anExec = 0; #endif - pc = -1; + pOp = &aOp[-1]; memset(p->aOnceFlag, 0, p->nOnceFlag); break; @@ -75647,9 +76365,10 @@ case OP_Program: { /* jump */ ** the value of the P1 argument to the value of the P1 argument to the ** calling OP_Program instruction. */ -case OP_Param: { /* out2-prerelease */ +case OP_Param: { /* out2 */ VdbeFrame *pFrame; Mem *pIn; + pOut = out2Prerelease(p, pOp); pFrame = p->pFrame; pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1]; sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem); @@ -75693,10 +76412,10 @@ case OP_FkCounter: { case OP_FkIfZero: { /* jump */ if( pOp->p1 ){ VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2); - if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1; + if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) goto jump_to_p2; }else{ VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2); - if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1; + if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) goto jump_to_p2; } break; } @@ -75736,18 +76455,18 @@ case OP_MemMax: { /* in2 */ /* Opcode: IfPos P1 P2 * * * ** Synopsis: if r[P1]>0 goto P2 ** -** If the value of register P1 is 1 or greater, jump to P2. +** Register P1 must contain an integer. +** If the value of register P1 is 1 or greater, jump to P2 and +** add the literal value P3 to register P1. ** -** It is illegal to use this instruction on a register that does -** not contain an integer. An assertion fault will result if you try. +** If the initial value of register P1 is less than 1, then the +** value is unchanged and control passes through to the next instruction. */ case OP_IfPos: { /* jump, in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags&MEM_Int ); VdbeBranchTaken( pIn1->u.i>0, 2); - if( pIn1->u.i>0 ){ - pc = pOp->p2 - 1; - } + if( pIn1->u.i>0 ) goto jump_to_p2; break; } @@ -75762,26 +76481,56 @@ case OP_IfNeg: { /* jump, in1 */ assert( pIn1->flags&MEM_Int ); pIn1->u.i += pOp->p3; VdbeBranchTaken(pIn1->u.i<0, 2); - if( pIn1->u.i<0 ){ - pc = pOp->p2 - 1; + if( pIn1->u.i<0 ) goto jump_to_p2; + break; +} + +/* Opcode: IfNotZero P1 P2 P3 * * +** Synopsis: if r[P1]!=0 then r[P1]+=P3, goto P2 +** +** Register P1 must contain an integer. If the content of register P1 is +** initially nonzero, then add P3 to P1 and jump to P2. If register P1 is +** initially zero, leave it unchanged and fall through. +*/ +case OP_IfNotZero: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + VdbeBranchTaken(pIn1->u.i<0, 2); + if( pIn1->u.i ){ + pIn1->u.i += pOp->p3; + goto jump_to_p2; } break; } -/* Opcode: IfZero P1 P2 P3 * * -** Synopsis: r[P1]+=P3, if r[P1]==0 goto P2 +/* Opcode: DecrJumpZero P1 P2 * * * +** Synopsis: if (--r[P1])==0 goto P2 ** -** The register P1 must contain an integer. Add literal P3 to the -** value in register P1. If the result is exactly 0, jump to P2. +** Register P1 must hold an integer. Decrement the value in register P1 +** then jump to P2 if the new value is exactly zero. */ -case OP_IfZero: { /* jump, in1 */ +case OP_DecrJumpZero: { /* jump, in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags&MEM_Int ); - pIn1->u.i += pOp->p3; + pIn1->u.i--; VdbeBranchTaken(pIn1->u.i==0, 2); - if( pIn1->u.i==0 ){ - pc = pOp->p2 - 1; - } + if( pIn1->u.i==0 ) goto jump_to_p2; + break; +} + + +/* Opcode: JumpZeroIncr P1 P2 * * * +** Synopsis: if (r[P1]++)==0 ) goto P2 +** +** The register P1 must contain an integer. If register P1 is initially +** zero, then jump to P2. Increment register P1 regardless of whether or +** not the jump is taken. +*/ +case OP_JumpZeroIncr: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + VdbeBranchTaken(pIn1->u.i==0, 2); + if( (pIn1->u.i++)==0 ) goto jump_to_p2; break; } @@ -75823,7 +76572,7 @@ case OP_AggStep: { ctx.pOut = &t; ctx.isError = 0; ctx.pVdbe = p; - ctx.iOp = pc; + ctx.iOp = (int)(pOp - aOp); ctx.skipFlag = 0; (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */ if( ctx.isError ){ @@ -75918,7 +76667,7 @@ case OP_Checkpoint: { ** ** Write a string containing the final journal-mode to register P2. */ -case OP_JournalMode: { /* out2-prerelease */ +case OP_JournalMode: { /* out2 */ Btree *pBt; /* Btree to change journal mode of */ Pager *pPager; /* Pager associated with pBt */ int eNew; /* New journal mode */ @@ -75927,6 +76676,7 @@ case OP_JournalMode: { /* out2-prerelease */ const char *zFilename; /* Name of database file for pPager */ #endif + pOut = out2Prerelease(p, pOp); eNew = pOp->p3; assert( eNew==PAGER_JOURNALMODE_DELETE || eNew==PAGER_JOURNALMODE_TRUNCATE @@ -76002,7 +76752,6 @@ case OP_JournalMode: { /* out2-prerelease */ } eNew = sqlite3PagerSetJournalMode(pPager, eNew); - pOut = &aMem[pOp->p2]; pOut->flags = MEM_Str|MEM_Static|MEM_Term; pOut->z = (char *)sqlite3JournalModename(eNew); pOut->n = sqlite3Strlen30(pOut->z); @@ -76043,8 +76792,8 @@ case OP_IncrVacuum: { /* jump */ rc = sqlite3BtreeIncrVacuum(pBt); VdbeBranchTaken(rc==SQLITE_DONE,2); if( rc==SQLITE_DONE ){ - pc = pOp->p2 - 1; rc = SQLITE_OK; + goto jump_to_p2; } break; } @@ -76122,13 +76871,29 @@ case OP_VBegin: { #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VCreate P1 * * P4 * +/* Opcode: VCreate P1 P2 * * * ** -** P4 is the name of a virtual table in database P1. Call the xCreate method -** for that table. +** P2 is a register that holds the name of a virtual table in database +** P1. Call the xCreate method for that table. */ case OP_VCreate: { - rc = sqlite3VtabCallCreate(db, pOp->p1, pOp->p4.z, &p->zErrMsg); + Mem sMem; /* For storing the record being decoded */ + const char *zTab; /* Name of the virtual table */ + + memset(&sMem, 0, sizeof(sMem)); + sMem.db = db; + /* Because P2 is always a static string, it is impossible for the + ** sqlite3VdbeMemCopy() to fail */ + assert( (aMem[pOp->p2].flags & MEM_Str)!=0 ); + assert( (aMem[pOp->p2].flags & MEM_Static)!=0 ); + rc = sqlite3VdbeMemCopy(&sMem, &aMem[pOp->p2]); + assert( rc==SQLITE_OK ); + zTab = (const char*)sqlite3_value_text(&sMem); + assert( zTab || db->mallocFailed ); + if( zTab ){ + rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg); + } + sqlite3VdbeMemRelease(&sMem); break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -76140,9 +76905,9 @@ case OP_VCreate: { ** of that table. */ case OP_VDestroy: { - p->inVtabMethod = 2; + db->nVDestroy++; rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z); - p->inVtabMethod = 0; + db->nVDestroy--; break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -76158,14 +76923,17 @@ case OP_VOpen: { VdbeCursor *pCur; sqlite3_vtab_cursor *pVtabCursor; sqlite3_vtab *pVtab; - sqlite3_module *pModule; + const sqlite3_module *pModule; assert( p->bIsReader ); pCur = 0; pVtabCursor = 0; pVtab = pOp->p4.pVtab->pVtab; - pModule = (sqlite3_module *)pVtab->pModule; - assert(pVtab && pModule); + if( pVtab==0 || NEVER(pVtab->pModule==0) ){ + rc = SQLITE_LOCKED; + break; + } + pModule = pVtab->pModule; rc = pModule->xOpen(pVtab, &pVtabCursor); sqlite3VtabImportErrmsg(p, pVtab); if( SQLITE_OK==rc ){ @@ -76176,9 +76944,11 @@ case OP_VOpen: { pCur = allocateCursor(p, pOp->p1, 0, -1, 0); if( pCur ){ pCur->pVtabCursor = pVtabCursor; + pVtab->nRef++; }else{ - db->mallocFailed = 1; + assert( db->mallocFailed ); pModule->xClose(pVtabCursor); + goto no_mem; } } break; @@ -76234,27 +77004,19 @@ case OP_VFilter: { /* jump */ iQuery = (int)pQuery->u.i; /* Invoke the xFilter method */ - { - res = 0; - apArg = p->apArg; - for(i = 0; i<nArg; i++){ - apArg[i] = &pArgc[i+1]; - } - - p->inVtabMethod = 1; - rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg); - p->inVtabMethod = 0; - sqlite3VtabImportErrmsg(p, pVtab); - if( rc==SQLITE_OK ){ - res = pModule->xEof(pVtabCursor); - } - VdbeBranchTaken(res!=0,2); - if( res ){ - pc = pOp->p2 - 1; - } + res = 0; + apArg = p->apArg; + for(i = 0; i<nArg; i++){ + apArg[i] = &pArgc[i+1]; + } + rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg); + sqlite3VtabImportErrmsg(p, pVtab); + if( rc==SQLITE_OK ){ + res = pModule->xEof(pVtabCursor); } pCur->nullRow = 0; - + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -76333,9 +77095,7 @@ case OP_VNext: { /* jump */ ** data is available) and the error code returned when xColumn or ** some other method is next invoked on the save virtual table cursor. */ - p->inVtabMethod = 1; rc = pModule->xNext(pCur->pVtabCursor); - p->inVtabMethod = 0; sqlite3VtabImportErrmsg(p, pVtab); if( rc==SQLITE_OK ){ res = pModule->xEof(pCur->pVtabCursor); @@ -76343,7 +77103,7 @@ case OP_VNext: { /* jump */ VdbeBranchTaken(!res,2); if( !res ){ /* If there is data, jump to P2 */ - pc = pOp->p2 - 1; + goto jump_to_p2_and_check_for_interrupt; } goto check_for_interrupt; } @@ -76410,7 +77170,7 @@ case OP_VRename: { */ case OP_VUpdate: { sqlite3_vtab *pVtab; - sqlite3_module *pModule; + const sqlite3_module *pModule; int nArg; int i; sqlite_int64 rowid; @@ -76422,7 +77182,11 @@ case OP_VUpdate: { ); assert( p->readOnly==0 ); pVtab = pOp->p4.pVtab->pVtab; - pModule = (sqlite3_module *)pVtab->pModule; + if( pVtab==0 || NEVER(pVtab->pModule==0) ){ + rc = SQLITE_LOCKED; + break; + } + pModule = pVtab->pModule; nArg = pOp->p2; assert( pOp->p4type==P4_VTAB ); if( ALWAYS(pModule->xUpdate) ){ @@ -76462,7 +77226,8 @@ case OP_VUpdate: { ** ** Write the current number of pages in database P1 to memory cell P2. */ -case OP_Pagecount: { /* out2-prerelease */ +case OP_Pagecount: { /* out2 */ + pOut = out2Prerelease(p, pOp); pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt); break; } @@ -76478,10 +77243,11 @@ case OP_Pagecount: { /* out2-prerelease */ ** ** Store the maximum page count after the change in register P2. */ -case OP_MaxPgcnt: { /* out2-prerelease */ +case OP_MaxPgcnt: { /* out2 */ unsigned int newMax; Btree *pBt; + pOut = out2Prerelease(p, pOp); pBt = db->aDb[pOp->p1].pBt; newMax = 0; if( pOp->p3 ){ @@ -76510,9 +77276,6 @@ case OP_Init: { /* jump */ char *zTrace; char *z; - if( pOp->p2 ){ - pc = pOp->p2 - 1; - } #ifndef SQLITE_OMIT_TRACE if( db->xTrace && !p->doingRerun @@ -76540,6 +77303,7 @@ case OP_Init: { /* jump */ } #endif /* SQLITE_DEBUG */ #endif /* SQLITE_OMIT_TRACE */ + if( pOp->p2 ) goto jump_to_p2; break; } @@ -76571,8 +77335,8 @@ default: { /* This is really OP_Noop and OP_Explain */ #ifdef VDBE_PROFILE { u64 endTime = sqlite3Hwtime(); - if( endTime>start ) pOp->cycles += endTime - start; - pOp->cnt++; + if( endTime>start ) pOrigOp->cycles += endTime - start; + pOrigOp->cnt++; } #endif @@ -76582,16 +77346,16 @@ default: { /* This is really OP_Noop and OP_Explain */ ** the evaluator loop. So we can leave it out when NDEBUG is defined. */ #ifndef NDEBUG - assert( pc>=-1 && pc<p->nOp ); + assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] ); #ifdef SQLITE_DEBUG if( db->flags & SQLITE_VdbeTrace ){ if( rc!=0 ) printf("rc=%d\n",rc); - if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){ - registerTrace(pOp->p2, &aMem[pOp->p2]); + if( pOrigOp->opflags & (OPFLG_OUT2) ){ + registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]); } - if( pOp->opflags & OPFLG_OUT3 ){ - registerTrace(pOp->p3, &aMem[pOp->p3]); + if( pOrigOp->opflags & OPFLG_OUT3 ){ + registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]); } } #endif /* SQLITE_DEBUG */ @@ -76606,7 +77370,7 @@ vdbe_error_halt: p->rc = rc; testcase( sqlite3GlobalConfig.xLog!=0 ); sqlite3_log(rc, "statement aborts at %d: [%s] %s", - pc, p->zSql, p->zErrMsg); + (int)(pOp - aOp), p->zSql, p->zErrMsg); sqlite3VdbeHalt(p); if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1; rc = SQLITE_ERROR; @@ -76769,7 +77533,7 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ /* ** Open a blob handle. */ -SQLITE_API int sqlite3_blob_open( +SQLITE_API int SQLITE_STDCALL sqlite3_blob_open( sqlite3* db, /* The database connection */ const char *zDb, /* The attached database containing the blob */ const char *zTable, /* The table containing the blob */ @@ -76819,12 +77583,17 @@ SQLITE_API int sqlite3_blob_open( Incrblob *pBlob = 0; #ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || ppBlob==0 || zTable==0 ){ + if( ppBlob==0 ){ return SQLITE_MISUSE_BKPT; } #endif - flags = !!flags; /* flags = (flags ? 1 : 0); */ *ppBlob = 0; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zTable==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + flags = !!flags; /* flags = (flags ? 1 : 0); */ sqlite3_mutex_enter(db->mutex); @@ -77001,7 +77770,7 @@ blob_open_out: ** Close a blob handle that was previously created using ** sqlite3_blob_open(). */ -SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *pBlob){ Incrblob *p = (Incrblob *)pBlob; int rc; sqlite3 *db; @@ -77038,7 +77807,7 @@ static int blobReadWrite( sqlite3_mutex_enter(db->mutex); v = (Vdbe*)p->pStmt; - if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){ + if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){ /* Request is out of range. Return a transient error. */ rc = SQLITE_ERROR; }else if( v==0 ){ @@ -77070,14 +77839,14 @@ static int blobReadWrite( /* ** Read data from a blob handle. */ -SQLITE_API int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){ return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData); } /* ** Write data to a blob handle. */ -SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){ return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData); } @@ -77087,7 +77856,7 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int ** The Incrblob.nByte field is fixed for the lifetime of the Incrblob ** so no mutex is required for access. */ -SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *pBlob){ Incrblob *p = (Incrblob *)pBlob; return (p && p->pStmt) ? p->nByte : 0; } @@ -77102,7 +77871,7 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){ ** subsequent calls to sqlite3_blob_xxx() functions (except blob_close()) ** immediately return SQLITE_ABORT. */ -SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ int rc; Incrblob *p = (Incrblob *)pBlob; sqlite3 *db; @@ -77427,6 +78196,7 @@ struct MergeEngine { ** after the thread has finished are not dire. So we don't worry about ** memory barriers and such here. */ +typedef int (*SorterCompare)(SortSubtask*,int*,const void*,int,const void*,int); struct SortSubtask { SQLiteThread *pThread; /* Background thread, if any */ int bDone; /* Set if thread is finished but not joined */ @@ -77434,10 +78204,12 @@ struct SortSubtask { UnpackedRecord *pUnpacked; /* Space to unpack a record */ SorterList list; /* List for thread to write to a PMA */ int nPMA; /* Number of PMAs currently in file */ + SorterCompare xCompare; /* Compare function to use */ SorterFile file; /* Temp file for level-0 PMAs */ SorterFile file2; /* Space for other PMAs */ }; + /* ** Main sorter structure. A single instance of this is allocated for each ** sorter cursor created by the VDBE. @@ -77464,9 +78236,13 @@ struct VdbeSorter { u8 bUseThreads; /* True to use background threads */ u8 iPrev; /* Previous thread used to flush PMA */ u8 nTask; /* Size of aTask[] array */ + u8 typeMask; SortSubtask aTask[1]; /* One or more subtasks */ }; +#define SORTER_TYPE_INTEGER 0x01 +#define SORTER_TYPE_TEXT 0x02 + /* ** An instance of the following object is used to read records out of a ** PMA, in sorted order. The next key to be read is cached in nKey/aKey. @@ -77878,32 +78654,162 @@ static int vdbePmaReaderInit( return rc; } +/* +** A version of vdbeSorterCompare() that assumes that it has already been +** determined that the first field of key1 is equal to the first field of +** key2. +*/ +static int vdbeSorterCompareTail( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + UnpackedRecord *r2 = pTask->pUnpacked; + if( *pbKey2Cached==0 ){ + sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); + *pbKey2Cached = 1; + } + return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1); +} /* ** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, ** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences ** used by the comparison. Return the result of the comparison. ** -** Before returning, object (pTask->pUnpacked) is populated with the -** unpacked version of key2. Or, if pKey2 is passed a NULL pointer, then it -** is assumed that the (pTask->pUnpacked) structure already contains the -** unpacked key to use as key2. +** If IN/OUT parameter *pbKey2Cached is true when this function is called, +** it is assumed that (pTask->pUnpacked) contains the unpacked version +** of key2. If it is false, (pTask->pUnpacked) is populated with the unpacked +** version of key2 and *pbKey2Cached set to true before returning. ** ** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set ** to SQLITE_NOMEM. */ static int vdbeSorterCompare( SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ const void *pKey1, int nKey1, /* Left side of comparison */ const void *pKey2, int nKey2 /* Right side of comparison */ ){ UnpackedRecord *r2 = pTask->pUnpacked; - if( pKey2 ){ + if( !*pbKey2Cached ){ sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); + *pbKey2Cached = 1; } return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); } +/* +** A specially optimized version of vdbeSorterCompare() that assumes that +** the first field of each key is a TEXT value and that the collation +** sequence to compare them with is BINARY. +*/ +static int vdbeSorterCompareText( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + const u8 * const p1 = (const u8 * const)pKey1; + const u8 * const p2 = (const u8 * const)pKey2; + const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */ + const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */ + + int n1; + int n2; + int res; + + getVarint32(&p1[1], n1); n1 = (n1 - 13) / 2; + getVarint32(&p2[1], n2); n2 = (n2 - 13) / 2; + res = memcmp(v1, v2, MIN(n1, n2)); + if( res==0 ){ + res = n1 - n2; + } + + if( res==0 ){ + if( pTask->pSorter->pKeyInfo->nField>1 ){ + res = vdbeSorterCompareTail( + pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 + ); + } + }else{ + if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){ + res = res * -1; + } + } + + return res; +} + +/* +** A specially optimized version of vdbeSorterCompare() that assumes that +** the first field of each key is an INTEGER value. +*/ +static int vdbeSorterCompareInt( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + const u8 * const p1 = (const u8 * const)pKey1; + const u8 * const p2 = (const u8 * const)pKey2; + const int s1 = p1[1]; /* Left hand serial type */ + const int s2 = p2[1]; /* Right hand serial type */ + const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */ + const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */ + int res; /* Return value */ + + assert( (s1>0 && s1<7) || s1==8 || s1==9 ); + assert( (s2>0 && s2<7) || s2==8 || s2==9 ); + + if( s1>7 && s2>7 ){ + res = s1 - s2; + }else{ + if( s1==s2 ){ + if( (*v1 ^ *v2) & 0x80 ){ + /* The two values have different signs */ + res = (*v1 & 0x80) ? -1 : +1; + }else{ + /* The two values have the same sign. Compare using memcmp(). */ + static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 }; + int i; + res = 0; + for(i=0; i<aLen[s1]; i++){ + if( (res = v1[i] - v2[i]) ) break; + } + } + }else{ + if( s2>7 ){ + res = +1; + }else if( s1>7 ){ + res = -1; + }else{ + res = s1 - s2; + } + assert( res!=0 ); + + if( res>0 ){ + if( *v1 & 0x80 ) res = -1; + }else{ + if( *v2 & 0x80 ) res = +1; + } + } + } + + if( res==0 ){ + if( pTask->pSorter->pKeyInfo->nField>1 ){ + res = vdbeSorterCompareTail( + pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 + ); + } + }else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){ + res = res * -1; + } + + return res; +} + /* ** Initialize the temporary index cursor just opened as a sorter cursor. ** @@ -77971,9 +78877,13 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit( pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); pKeyInfo->db = 0; - if( nField && nWorker==0 ) pKeyInfo->nField = nField; + if( nField && nWorker==0 ){ + pKeyInfo->nXField += (pKeyInfo->nField - nField); + pKeyInfo->nField = nField; + } pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); pSorter->nTask = nWorker + 1; + pSorter->iPrev = nWorker-1; pSorter->bUseThreads = (pSorter->nTask>1); pSorter->db = db; for(i=0; i<pSorter->nTask; i++){ @@ -77999,6 +78909,12 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit( if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM; } } + + if( (pKeyInfo->nField+pKeyInfo->nXField)<13 + && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl) + ){ + pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT; + } } return rc; @@ -78023,30 +78939,24 @@ static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){ */ static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){ sqlite3DbFree(db, pTask->pUnpacked); - pTask->pUnpacked = 0; #if SQLITE_MAX_WORKER_THREADS>0 /* pTask->list.aMemory can only be non-zero if it was handed memory ** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */ if( pTask->list.aMemory ){ sqlite3_free(pTask->list.aMemory); - pTask->list.aMemory = 0; }else #endif { assert( pTask->list.aMemory==0 ); vdbeSorterRecordFree(0, pTask->list.pList); } - pTask->list.pList = 0; if( pTask->file.pFd ){ sqlite3OsCloseFree(pTask->file.pFd); - pTask->file.pFd = 0; - pTask->file.iEof = 0; } if( pTask->file2.pFd ){ sqlite3OsCloseFree(pTask->file2.pFd); - pTask->file2.pFd = 0; - pTask->file2.iEof = 0; } + memset(pTask, 0, sizeof(SortSubtask)); } #ifdef SQLITE_DEBUG_SORTER_THREADS @@ -78226,6 +79136,7 @@ SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){ for(i=0; i<pSorter->nTask; i++){ SortSubtask *pTask = &pSorter->aTask[i]; vdbeSortSubtaskCleanup(db, pTask); + pTask->pSorter = pSorter; } if( pSorter->list.aMemory==0 ){ vdbeSorterRecordFree(0, pSorter->list.pList); @@ -78287,6 +79198,7 @@ static int vdbeSorterOpenTempFile( sqlite3_file **ppFd ){ int rc; + if( sqlite3FaultSim(202) ) return SQLITE_IOERR_ACCESS; rc = sqlite3OsOpenMalloc(db->pVfs, 0, ppFd, SQLITE_OPEN_TEMP_JOURNAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | @@ -78334,28 +79246,42 @@ static void vdbeSorterMerge( ){ SorterRecord *pFinal = 0; SorterRecord **pp = &pFinal; - void *pVal2 = p2 ? SRVAL(p2) : 0; + int bCached = 0; while( p1 && p2 ){ int res; - res = vdbeSorterCompare(pTask, SRVAL(p1), p1->nVal, pVal2, p2->nVal); + res = pTask->xCompare( + pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal + ); + if( res<=0 ){ *pp = p1; pp = &p1->u.pNext; p1 = p1->u.pNext; - pVal2 = 0; }else{ *pp = p2; - pp = &p2->u.pNext; + pp = &p2->u.pNext; p2 = p2->u.pNext; - if( p2==0 ) break; - pVal2 = SRVAL(p2); + bCached = 0; } } *pp = p1 ? p1 : p2; *ppOut = pFinal; } +/* +** Return the SorterCompare function to compare values collected by the +** sorter object passed as the only argument. +*/ +static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){ + if( p->typeMask==SORTER_TYPE_INTEGER ){ + return vdbeSorterCompareInt; + }else if( p->typeMask==SORTER_TYPE_TEXT ){ + return vdbeSorterCompareText; + } + return vdbeSorterCompare; +} + /* ** Sort the linked list of records headed at pTask->pList. Return ** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if @@ -78370,12 +79296,14 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ rc = vdbeSortAllocUnpacked(pTask); if( rc!=SQLITE_OK ) return rc; + p = pList->pList; + pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter); + aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *)); if( !aSlot ){ return SQLITE_NOMEM; } - p = pList->pList; while( p ){ SorterRecord *pNext; if( pList->aMemory ){ @@ -78589,13 +79517,12 @@ static int vdbeMergeEngineStep( int i; /* Index of aTree[] to recalculate */ PmaReader *pReadr1; /* First PmaReader to compare */ PmaReader *pReadr2; /* Second PmaReader to compare */ - u8 *pKey2; /* To pReadr2->aKey, or 0 if record cached */ + int bCached = 0; /* Find the first two PmaReaders to compare. The one that was just ** advanced (iPrev) and the one next to it in the array. */ pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)]; pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)]; - pKey2 = pReadr2->aKey; for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){ /* Compare pReadr1 and pReadr2. Store the result in variable iRes. */ @@ -78605,8 +79532,8 @@ static int vdbeMergeEngineStep( }else if( pReadr2->pFd==0 ){ iRes = -1; }else{ - iRes = vdbeSorterCompare(pTask, - pReadr1->aKey, pReadr1->nKey, pKey2, pReadr2->nKey + iRes = pTask->xCompare(pTask, &bCached, + pReadr1->aKey, pReadr1->nKey, pReadr2->aKey, pReadr2->nKey ); } @@ -78628,9 +79555,9 @@ static int vdbeMergeEngineStep( if( iRes<0 || (iRes==0 && pReadr1<pReadr2) ){ pMerger->aTree[i] = (int)(pReadr1 - pMerger->aReadr); pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; - pKey2 = pReadr2->aKey; + bCached = 0; }else{ - if( pReadr1->pFd ) pKey2 = 0; + if( pReadr1->pFd ) bCached = 0; pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr); pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; } @@ -78737,6 +79664,16 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite( int bFlush; /* True to flush contents of memory to PMA */ int nReq; /* Bytes of memory required */ int nPMA; /* Bytes of PMA space required */ + int t; /* serial type of first record field */ + + getVarint32((const u8*)&pVal->z[1], t); + if( t>0 && t<10 && t!=7 ){ + pSorter->typeMask &= SORTER_TYPE_INTEGER; + }else if( t>10 && (t & 0x01) ){ + pSorter->typeMask &= SORTER_TYPE_TEXT; + }else{ + pSorter->typeMask = 0; + } assert( pSorter ); @@ -79002,10 +79939,12 @@ static void vdbeMergeEngineCompare( }else if( p2->pFd==0 ){ iRes = i1; }else{ + SortSubtask *pTask = pMerger->pTask; + int bCached = 0; int res; - assert( pMerger->pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */ - res = vdbeSorterCompare( - pMerger->pTask, p1->aKey, p1->nKey, p2->aKey, p2->nKey + assert( pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */ + res = pTask->xCompare( + pTask, &bCached, p1->aKey, p1->nKey, p2->aKey, p2->nKey ); if( res<=0 ){ iRes = i1; @@ -79029,11 +79968,12 @@ static void vdbeMergeEngineCompare( #define INCRINIT_TASK 1 #define INCRINIT_ROOT 2 -/* Forward reference. -** The vdbeIncrMergeInit() and vdbePmaReaderIncrMergeInit() routines call each -** other (when building a merge tree). +/* +** Forward reference required as the vdbeIncrMergeInit() and +** vdbePmaReaderIncrInit() routines are called mutually recursively when +** building a merge tree. */ -static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode); +static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode); /* ** Initialize the MergeEngine object passed as the second argument. Once this @@ -79080,7 +80020,7 @@ static int vdbeMergeEngineInit( ** better advantage of multi-processor hardware. */ rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]); }else{ - rc = vdbePmaReaderIncrMergeInit(&pMerger->aReadr[i], INCRINIT_NORMAL); + rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], INCRINIT_NORMAL); } if( rc!=SQLITE_OK ) return rc; } @@ -79092,17 +80032,15 @@ static int vdbeMergeEngineInit( } /* -** Initialize the IncrMerge field of a PmaReader. -** -** If the PmaReader passed as the first argument is not an incremental-reader -** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it serves -** to open and/or initialize the temp file related fields of the IncrMerge +** The PmaReader passed as the first argument is guaranteed to be an +** incremental-reader (pReadr->pIncr!=0). This function serves to open +** and/or initialize the temp file related fields of the IncrMerge ** object at (pReadr->pIncr). ** ** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders -** in the sub-tree headed by pReadr are also initialized. Data is then loaded -** into the buffers belonging to pReadr and it is set to -** point to the first key in its range. +** in the sub-tree headed by pReadr are also initialized. Data is then +** loaded into the buffers belonging to pReadr and it is set to point to +** the first key in its range. ** ** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed ** to be a multi-threaded PmaReader and this function is being called in a @@ -79129,59 +80067,62 @@ static int vdbeMergeEngineInit( static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){ int rc = SQLITE_OK; IncrMerger *pIncr = pReadr->pIncr; + SortSubtask *pTask = pIncr->pTask; + sqlite3 *db = pTask->pSorter->db; /* eMode is always INCRINIT_NORMAL in single-threaded mode */ assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); - if( pIncr ){ - SortSubtask *pTask = pIncr->pTask; - sqlite3 *db = pTask->pSorter->db; - - rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); + rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); - /* Set up the required files for pIncr. A multi-theaded IncrMerge object - ** requires two temp files to itself, whereas a single-threaded object - ** only requires a region of pTask->file2. */ - if( rc==SQLITE_OK ){ - int mxSz = pIncr->mxSz; + /* Set up the required files for pIncr. A multi-theaded IncrMerge object + ** requires two temp files to itself, whereas a single-threaded object + ** only requires a region of pTask->file2. */ + if( rc==SQLITE_OK ){ + int mxSz = pIncr->mxSz; #if SQLITE_MAX_WORKER_THREADS>0 - if( pIncr->bUseThread ){ - rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd); - if( rc==SQLITE_OK ){ - rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd); - } - }else + if( pIncr->bUseThread ){ + rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd); + if( rc==SQLITE_OK ){ + rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd); + } + }else #endif - /*if( !pIncr->bUseThread )*/{ - if( pTask->file2.pFd==0 ){ - assert( pTask->file2.iEof>0 ); - rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd); - pTask->file2.iEof = 0; - } - if( rc==SQLITE_OK ){ - pIncr->aFile[1].pFd = pTask->file2.pFd; - pIncr->iStartOff = pTask->file2.iEof; - pTask->file2.iEof += mxSz; - } + /*if( !pIncr->bUseThread )*/{ + if( pTask->file2.pFd==0 ){ + assert( pTask->file2.iEof>0 ); + rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd); + pTask->file2.iEof = 0; + } + if( rc==SQLITE_OK ){ + pIncr->aFile[1].pFd = pTask->file2.pFd; + pIncr->iStartOff = pTask->file2.iEof; + pTask->file2.iEof += mxSz; } } + } #if SQLITE_MAX_WORKER_THREADS>0 - if( rc==SQLITE_OK && pIncr->bUseThread ){ - /* Use the current thread to populate aFile[1], even though this - ** PmaReader is multi-threaded. The reason being that this function - ** is already running in background thread pIncr->pTask->thread. */ - assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK ); - rc = vdbeIncrPopulate(pIncr); - } + if( rc==SQLITE_OK && pIncr->bUseThread ){ + /* Use the current thread to populate aFile[1], even though this + ** PmaReader is multi-threaded. If this is an INCRINIT_TASK object, + ** then this function is already running in background thread + ** pIncr->pTask->thread. + ** + ** If this is the INCRINIT_ROOT object, then it is running in the + ** main VDBE thread. But that is Ok, as that thread cannot return + ** control to the VDBE or proceed with anything useful until the + ** first results are ready from this merger object anyway. + */ + assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK ); + rc = vdbeIncrPopulate(pIncr); + } #endif - if( rc==SQLITE_OK - && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) - ){ - rc = vdbePmaReaderNext(pReadr); - } + if( rc==SQLITE_OK && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) ){ + rc = vdbePmaReaderNext(pReadr); } + return rc; } @@ -79190,7 +80131,7 @@ static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){ ** The main routine for vdbePmaReaderIncrMergeInit() operations run in ** background threads. */ -static void *vdbePmaReaderBgInit(void *pCtx){ +static void *vdbePmaReaderBgIncrInit(void *pCtx){ PmaReader *pReader = (PmaReader*)pCtx; void *pRet = SQLITE_INT_TO_PTR( vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK) @@ -79198,20 +80139,36 @@ static void *vdbePmaReaderBgInit(void *pCtx){ pReader->pIncr->pTask->bDone = 1; return pRet; } +#endif /* -** Use a background thread to invoke vdbePmaReaderIncrMergeInit(INCRINIT_TASK) -** on the PmaReader object passed as the first argument. -** -** This call will initialize the various fields of the pReadr->pIncr -** structure and, if it is a multi-threaded IncrMerger, launch a -** background thread to populate aFile[1]. +** If the PmaReader passed as the first argument is not an incremental-reader +** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it invokes +** the vdbePmaReaderIncrMergeInit() function with the parameters passed to +** this routine to initialize the incremental merge. +** +** If the IncrMerger object is multi-threaded (IncrMerger.bUseThread==1), +** then a background thread is launched to call vdbePmaReaderIncrMergeInit(). +** Or, if the IncrMerger is single threaded, the same function is called +** using the current thread. */ -static int vdbePmaReaderBgIncrInit(PmaReader *pReadr){ - void *pCtx = (void*)pReadr; - return vdbeSorterCreateThread(pReadr->pIncr->pTask, vdbePmaReaderBgInit, pCtx); -} +static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode){ + IncrMerger *pIncr = pReadr->pIncr; /* Incremental merger */ + int rc = SQLITE_OK; /* Return code */ + if( pIncr ){ +#if SQLITE_MAX_WORKER_THREADS>0 + assert( pIncr->bUseThread==0 || eMode==INCRINIT_TASK ); + if( pIncr->bUseThread ){ + void *pCtx = (void*)pReadr; + rc = vdbeSorterCreateThread(pIncr->pTask, vdbePmaReaderBgIncrInit, pCtx); + }else #endif + { + rc = vdbePmaReaderIncrMergeInit(pReadr, eMode); + } + } + return rc; +} /* ** Allocate a new MergeEngine object to merge the contents of nPMA level-0 @@ -79423,6 +80380,11 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){ MergeEngine *pMain = 0; #if SQLITE_MAX_WORKER_THREADS sqlite3 *db = pTask0->pSorter->db; + int i; + SorterCompare xCompare = vdbeSorterGetCompare(pSorter); + for(i=0; i<pSorter->nTask; i++){ + pSorter->aTask[i].xCompare = xCompare; + } #endif rc = vdbeSorterMergeTreeBuild(pSorter, &pMain); @@ -79451,15 +80413,21 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){ } } for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){ + /* Check that: + ** + ** a) The incremental merge object is configured to use the + ** right task, and + ** b) If it is using task (nTask-1), it is configured to run + ** in single-threaded mode. This is important, as the + ** root merge (INCRINIT_ROOT) will be using the same task + ** object. + */ PmaReader *p = &pMain->aReadr[iTask]; - assert( p->pIncr==0 || p->pIncr->pTask==&pSorter->aTask[iTask] ); - if( p->pIncr ){ - if( iTask==pSorter->nTask-1 ){ - rc = vdbePmaReaderIncrMergeInit(p, INCRINIT_TASK); - }else{ - rc = vdbePmaReaderBgIncrInit(p); - } - } + assert( p->pIncr==0 || ( + (p->pIncr->pTask==&pSorter->aTask[iTask]) /* a */ + && (iTask!=pSorter->nTask-1 || p->pIncr->bUseThread==0) /* b */ + )); + rc = vdbePmaReaderIncrInit(p, INCRINIT_TASK); } } pMain = 0; @@ -80414,7 +81382,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){ ** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase; ** ** The nSubquery parameter specifies how many levels of subquery the -** alias is removed from the original expression. The usually value is +** alias is removed from the original expression. The usual value is ** zero but it might be more if the alias is contained within a subquery ** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION ** structures must be increased by the nSubquery amount. @@ -80434,7 +81402,6 @@ static void resolveAlias( assert( iCol>=0 && iCol<pEList->nExpr ); pOrig = pEList->a[iCol].pExpr; assert( pOrig!=0 ); - assert( pOrig->flags & EP_Resolved ); db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); if( pDup==0 ) return; @@ -80582,9 +81549,10 @@ static int lookupName( testcase( pNC->ncFlags & NC_PartIdx ); testcase( pNC->ncFlags & NC_IsCheck ); if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){ - /* Silently ignore database qualifiers inside CHECK constraints and partial - ** indices. Do not raise errors because that might break legacy and - ** because it does not hurt anything to just ignore the database name. */ + /* Silently ignore database qualifiers inside CHECK constraints and + ** partial indices. Do not raise errors because that might break + ** legacy and because it does not hurt anything to just ignore the + ** database name. */ zDb = 0; }else{ for(i=0; i<db->nDb; i++){ @@ -80655,7 +81623,8 @@ static int lookupName( if( pMatch ){ pExpr->iTable = pMatch->iCursor; pExpr->pTab = pMatch->pTab; - assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */ + /* RIGHT JOIN not (yet) supported */ + assert( (pMatch->jointype & JT_RIGHT)==0 ); if( (pMatch->jointype & JT_LEFT)!=0 ){ ExprSetProperty(pExpr, EP_CanBeNull); } @@ -80976,7 +81945,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pExpr->affinity = SQLITE_AFF_INTEGER; break; } -#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */ +#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) + && !defined(SQLITE_OMIT_SUBQUERY) */ /* A lone identifier is the name of a column. */ @@ -81041,19 +82011,20 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ if( n==2 ){ pExpr->iTable = exprProbability(pList->a[1].pExpr); if( pExpr->iTable<0 ){ - sqlite3ErrorMsg(pParse, "second argument to likelihood() must be a " - "constant between 0.0 and 1.0"); + sqlite3ErrorMsg(pParse, + "second argument to likelihood() must be a " + "constant between 0.0 and 1.0"); pNC->nErr++; } }else{ - /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to - ** likelihood(X, 0.0625). - ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for - ** likelihood(X,0.0625). - ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand for - ** likelihood(X,0.9375). - ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent to - ** likelihood(X,0.9375). */ + /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is + ** equivalent to likelihood(X, 0.0625). + ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is + ** short-hand for likelihood(X,0.0625). + ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand + ** for likelihood(X,0.9375). + ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent + ** to likelihood(X,0.9375). */ /* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */ pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120; } @@ -81070,7 +82041,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ return WRC_Prune; } #endif - if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant); + if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ){ + ExprSetProperty(pExpr,EP_ConstFunc); + } } if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); @@ -81322,9 +82295,11 @@ static int resolveCompoundOrderBy( if( pItem->pExpr==pE ){ pItem->pExpr = pNew; }else{ - assert( pItem->pExpr->op==TK_COLLATE ); - assert( pItem->pExpr->pLeft==pE ); - pItem->pExpr->pLeft = pNew; + Expr *pParent = pItem->pExpr; + assert( pParent->op==TK_COLLATE ); + while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft; + assert( pParent->pLeft==pE ); + pParent->pLeft = pNew; } sqlite3ExprDelete(db, pE); pItem->u.x.iOrderByCol = (u16)iCol; @@ -81381,7 +82356,8 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy( resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); return 1; } - resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, zType,0); + resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, + zType,0); } } return 0; @@ -81514,6 +82490,20 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ sqlite3ResolveExprNames(&sNC, p->pOffset) ){ return WRC_Abort; } + + /* If the SF_Converted flags is set, then this Select object was + ** was created by the convertCompoundSelectToSubquery() function. + ** In this case the ORDER BY clause (p->pOrderBy) should be resolved + ** as if it were part of the sub-query, not the parent. This block + ** moves the pOrderBy down to the sub-query. It will be moved back + ** after the names have been resolved. */ + if( p->selFlags & SF_Converted ){ + Select *pSub = p->pSrc->a[0].pSelect; + assert( p->pSrc->nSrc==1 && p->pOrderBy ); + assert( pSub->pPrior && pSub->pOrderBy==0 ); + pSub->pOrderBy = p->pOrderBy; + p->pOrderBy = 0; + } /* Recursively resolve names in all subqueries */ @@ -81596,12 +82586,30 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ sNC.pNext = 0; sNC.ncFlags |= NC_AllowAgg; + /* If this is a converted compound query, move the ORDER BY clause from + ** the sub-query back to the parent query. At this point each term + ** within the ORDER BY clause has been transformed to an integer value. + ** These integers will be replaced by copies of the corresponding result + ** set expressions by the call to resolveOrderGroupBy() below. */ + if( p->selFlags & SF_Converted ){ + Select *pSub = p->pSrc->a[0].pSelect; + p->pOrderBy = pSub->pOrderBy; + pSub->pOrderBy = 0; + } + /* Process the ORDER BY clause for singleton SELECT statements. ** The ORDER BY clause for compounds SELECT statements is handled ** below, after all of the result-sets for all of the elements of ** the compound have been resolved. + ** + ** If there is an ORDER BY clause on a term of a compound-select other + ** than the right-most term, then that is a syntax error. But the error + ** is not detected until much later, and so we need to go ahead and + ** resolve those symbols on the incorrect ORDER BY for consistency. */ - if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){ + if( isCompound<=nCompound /* Defer right-most ORDER BY of a compound */ + && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") + ){ return WRC_Abort; } if( db->mallocFailed ){ @@ -81871,10 +82879,11 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken( Parse *pParse, /* Parsing context */ Expr *pExpr, /* Add the "COLLATE" clause to this expression */ - const Token *pCollName /* Name of collating sequence */ + const Token *pCollName, /* Name of collating sequence */ + int dequote /* True to dequote pCollName */ ){ if( pCollName->n>0 ){ - Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1); + Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); if( pNew ){ pNew->pLeft = pExpr; pNew->flags |= EP_Collate|EP_Skip; @@ -81888,7 +82897,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, con assert( zC!=0 ); s.z = zC; s.n = sqlite3Strlen30(s.z); - return sqlite3ExprAddCollateToken(pParse, pExpr, &s); + return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); } /* @@ -81934,9 +82943,9 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); break; } - if( p->pTab!=0 - && (op==TK_AGG_COLUMN || op==TK_COLUMN + if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER) + && p->pTab!=0 ){ /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally ** a TK_COLUMN but was previously evaluated and cached in a register */ @@ -81948,10 +82957,25 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ break; } if( p->flags & EP_Collate ){ - if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){ + if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){ p = p->pLeft; }else{ - p = p->pRight; + Expr *pNext = p->pRight; + /* The Expr.x union is never used at the same time as Expr.pRight */ + assert( p->x.pList==0 || p->pRight==0 ); + /* p->flags holds EP_Collate and p->pLeft->flags does not. And + ** p->x.pSelect cannot. So if p->x.pLeft exists, it must hold at + ** least one EP_Collate. Thus the following two ALWAYS. */ + if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){ + int i; + for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){ + if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){ + pNext = p->x.pList->a[i].pExpr; + break; + } + } + } + p = pNext; } }else{ break; @@ -82157,6 +83181,9 @@ static void heightOfSelect(Select *p, int *pnHeight){ ** Expr.pSelect member has a height of 1. Any other expression ** has a height equal to the maximum height of any other ** referenced Expr plus one. +** +** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags, +** if appropriate. */ static void exprSetHeight(Expr *p){ int nHeight = 0; @@ -82164,8 +83191,9 @@ static void exprSetHeight(Expr *p){ heightOfExpr(p->pRight, &nHeight); if( ExprHasProperty(p, EP_xIsSelect) ){ heightOfSelect(p->x.pSelect, &nHeight); - }else{ + }else if( p->x.pList ){ heightOfExprList(p->x.pList, &nHeight); + p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); } p->nHeight = nHeight + 1; } @@ -82174,8 +83202,12 @@ static void exprSetHeight(Expr *p){ ** Set the Expr.nHeight variable using the exprSetHeight() function. If ** the height is greater than the maximum allowed expression depth, ** leave an error in pParse. +** +** Also propagate all EP_Propagate flags from the Expr.x.pList into +** Expr.flags. */ -SQLITE_PRIVATE void sqlite3ExprSetHeight(Parse *pParse, Expr *p){ +SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ + if( pParse->nErr ) return; exprSetHeight(p); sqlite3ExprCheckHeight(pParse, p->nHeight); } @@ -82189,8 +83221,17 @@ SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){ heightOfSelect(p, &nHeight); return nHeight; } -#else - #define exprSetHeight(y) +#else /* ABOVE: Height enforcement enabled. BELOW: Height enforcement off */ +/* +** Propagate all EP_Propagate flags from the Expr.x.pList into +** Expr.flags. +*/ +SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ + if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){ + p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); + } +} +#define exprSetHeight(y) #endif /* SQLITE_MAX_EXPR_DEPTH>0 */ /* @@ -82292,11 +83333,11 @@ SQLITE_PRIVATE void sqlite3ExprAttachSubtrees( }else{ if( pRight ){ pRoot->pRight = pRight; - pRoot->flags |= EP_Collate & pRight->flags; + pRoot->flags |= EP_Propagate & pRight->flags; } if( pLeft ){ pRoot->pLeft = pLeft; - pRoot->flags |= EP_Collate & pLeft->flags; + pRoot->flags |= EP_Propagate & pLeft->flags; } exprSetHeight(pRoot); } @@ -82396,7 +83437,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token * } pNew->x.pList = pList; assert( !ExprHasProperty(pNew, EP_xIsSelect) ); - sqlite3ExprSetHeight(pParse, pNew); + sqlite3ExprSetHeightAndFlags(pParse, pNew); return pNew; } @@ -83011,6 +84052,22 @@ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ sqlite3DbFree(db, pList); } +/* +** Return the bitwise-OR of all Expr.flags fields in the given +** ExprList. +*/ +SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){ + int i; + u32 m = 0; + if( pList ){ + for(i=0; i<pList->nExpr; i++){ + Expr *pExpr = pList->a[i].pExpr; + if( ALWAYS(pExpr) ) m |= pExpr->flags; + } + } + return m; +} + /* ** These routines are Walker callbacks used to check expressions to ** see if they are "constant" for some definition of constant. The @@ -83051,7 +84108,7 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ ** and either pWalker->eCode==4 or 5 or the function has the ** SQLITE_FUNC_CONST flag. */ case TK_FUNCTION: - if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_Constant) ){ + if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){ return WRC_Continue; }else{ pWalker->eCode = 0; @@ -83445,7 +84502,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int ** ephemeral table. */ p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0); - if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){ + if( pParse->nErr==0 && isCandidateForInOpt(p) ){ sqlite3 *db = pParse->db; /* Database connection */ Table *pTab; /* Table <table>. */ Expr *pExpr; /* Expression <column> */ @@ -83770,6 +84827,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[1]); pSel->iLimit = 0; + pSel->selFlags &= ~SF_MultiValue; if( sqlite3Select(pParse, pSel, &dest) ){ return 0; } @@ -84058,7 +85116,8 @@ SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int int idxLru; struct yColCache *p; - assert( iReg>0 ); /* Register numbers are always positive */ + /* Unless an error has occurred, register numbers are always positive. */ + assert( iReg>0 || pParse->nErr || pParse->db->mallocFailed ); assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */ /* The SQLITE_ColumnCache flag disables the column cache. This is used @@ -85134,7 +86193,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m break; } case TK_ID: { - sqlite3TreeViewLine(pView,"ID %Q", pExpr->u.zToken); + sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken); break; } #ifndef SQLITE_OMIT_CAST @@ -85769,7 +86828,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2; if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2; if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; - if( ALWAYS((combinedFlags & EP_Reduced)==0) ){ + if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){ if( pA->iColumn!=pB->iColumn ) return 2; if( pA->iTable!=pB->iTable && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; @@ -86301,6 +87360,7 @@ static void renameParentFunc( n = sqlite3GetToken(z, &token); }while( token==TK_SPACE ); + if( token==TK_ILLEGAL ) break; zParent = sqlite3DbStrNDup(db, (const char *)z, n); if( zParent==0 ) break; sqlite3Dequote(zParent); @@ -86865,7 +87925,10 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ */ if( pDflt ){ sqlite3_value *pVal = 0; - if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ + int rc; + rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + if( rc!=SQLITE_OK ){ db->mallocFailed = 1; return; } @@ -88524,14 +89587,17 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ z = argv[2]; if( pIndex ){ + tRowcnt *aiRowEst = 0; int nCol = pIndex->nKeyCol+1; #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero( - sizeof(tRowcnt) * nCol - ); - if( aiRowEst==0 ) pInfo->db->mallocFailed = 1; -#else - tRowcnt * const aiRowEst = 0; + /* Index.aiRowEst may already be set here if there are duplicate + ** sqlite_stat1 entries for this index. In that case just clobber + ** the old data with the new instead of allocating a new array. */ + if( pIndex->aiRowEst==0 ){ + pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); + if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1; + } + aiRowEst = pIndex->aiRowEst; #endif pIndex->bUnordered = 0; decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex); @@ -89087,7 +90153,7 @@ static void attachFunc( case SQLITE_NULL: /* No key specified. Use the key from the main database */ sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); - if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){ + if( nKey>0 || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){ rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); } break; @@ -89194,7 +90260,7 @@ static void detachFunc( sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; pDb->pSchema = 0; - sqlite3ResetAllSchemasOfConnection(db); + sqlite3CollapseDatabaseArray(db); return; detach_error: @@ -89228,7 +90294,6 @@ static void codeAttach( SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) || SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey)) ){ - pParse->nErr++; goto attach_end; } @@ -89550,7 +90615,7 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep( ** Setting the auth function to NULL disables this hook. The default ** setting of the auth function is NULL. */ -SQLITE_API int sqlite3_set_authorizer( +SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer( sqlite3 *db, int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), void *pArg @@ -89887,9 +90952,11 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ assert( pParse->pToplevel==0 ); db = pParse->db; - if( db->mallocFailed ) return; if( pParse->nested ) return; - if( pParse->nErr ) return; + if( db->mallocFailed || pParse->nErr ){ + if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR; + return; + } /* Begin by generating some termination code at the end of the ** vdbe program @@ -89971,7 +91038,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ /* Get the VDBE program ready for execution */ - if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){ + if( v && pParse->nErr==0 && !db->mallocFailed ){ assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ /* A minimum of one cursor is required if autoincrement is used * See ticket [a696379c1f08866] */ @@ -90053,10 +91120,6 @@ SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const cha Table *p = 0; int i; -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zName==0 ) return 0; -#endif - /* All mutexes are required for schema access. Make sure we hold them. */ assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); #if SQLITE_USER_AUTHENTICATION @@ -90510,14 +91573,12 @@ SQLITE_PRIVATE int sqlite3TwoPartName( if( ALWAYS(pName2!=0) && pName2->n>0 ){ if( db->init.busy ) { sqlite3ErrorMsg(pParse, "corrupt database"); - pParse->nErr++; return -1; } *pUnqual = pName2; iDb = sqlite3FindDb(db, pName1); if( iDb<0 ){ sqlite3ErrorMsg(pParse, "unknown database %T", pName1); - pParse->nErr++; return -1; } }else{ @@ -90676,7 +91737,7 @@ SQLITE_PRIVATE void sqlite3StartTable( if( !noErr ){ sqlite3ErrorMsg(pParse, "table %T already exists", pName); }else{ - assert( !db->init.busy ); + assert( !db->init.busy || CORRUPT_DB ); sqlite3CodeVerifySchema(pParse, iDb); } goto begin_table_error; @@ -90965,7 +92026,8 @@ SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){ p = pParse->pNewTable; if( p==0 || NEVER(p->nCol<1) ) return; pCol = &p->aCol[p->nCol-1]; - assert( pCol->zType==0 ); + assert( pCol->zType==0 || CORRUPT_DB ); + sqlite3DbFree(pParse->db, pCol->zType); pCol->zType = sqlite3NameFromToken(pParse->db, pType); pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst); } @@ -91476,11 +92538,14 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ assert( pPk!=0 ); nPk = pPk->nKeyCol; - /* Make sure every column of the PRIMARY KEY is NOT NULL */ - for(i=0; i<nPk; i++){ - pTab->aCol[pPk->aiColumn[i]].notNull = 1; + /* Make sure every column of the PRIMARY KEY is NOT NULL. (Except, + ** do not enforce this for imposter tables.) */ + if( !db->init.imposterTable ){ + for(i=0; i<nPk; i++){ + pTab->aCol[pPk->aiColumn[i]].notNull = 1; + } + pPk->uniqNotNull = 1; } - pPk->uniqNotNull = 1; /* The root page of the PRIMARY KEY is the table root page */ pPk->tnum = pTab->tnum; @@ -92196,6 +93261,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, } assert( pParse->nErr==0 ); assert( pName->nSrc==1 ); + if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; if( noErr ) db->suppressErr++; pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); if( noErr ) db->suppressErr--; @@ -92509,7 +93575,8 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ addr2 = sqlite3VdbeCurrentAddr(v); } sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); - sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1); + sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1); + sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); @@ -92602,8 +93669,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( char *zExtra = 0; /* Extra space after the Index object */ Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */ - assert( pParse->nErr==0 ); /* Never called with prior errors */ - if( db->mallocFailed || IN_DECLARE_VTAB ){ + if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){ goto exit_create_index; } if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ @@ -92929,6 +93995,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex( pIdx->onError = pIndex->onError; } } + pRet = pIdx; goto exit_create_index; } } @@ -93521,7 +94588,6 @@ SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pI SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){ if( p ){ int i; - assert( p->a || p->nSrc==0 ); for(i=p->nSrc-1; i>0; i--){ p->a[i].jointype = p->a[i-1].jointype; } @@ -93768,8 +94834,7 @@ SQLITE_PRIVATE void sqlite3UniqueConstraint( StrAccum errMsg; Table *pTab = pIdx->pTable; - sqlite3StrAccumInit(&errMsg, 0, 0, 200); - errMsg.db = pParse->db; + sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200); for(j=0; j<pIdx->nKeyCol; j++){ char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName; if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2); @@ -94715,7 +95780,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( pInClause->x.pSelect = pSelect; pInClause->flags |= EP_xIsSelect; - sqlite3ExprSetHeight(pParse, pInClause); + sqlite3ExprSetHeightAndFlags(pParse, pInClause); return pInClause; /* something went wrong. clean up anything allocated. */ @@ -95388,7 +96453,9 @@ SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ ** Return the collating function associated with a function. */ static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ - VdbeOp *pOp = &context->pVdbe->aOp[context->iOp-1]; + VdbeOp *pOp; + assert( context->pVdbe!=0 ); + pOp = &context->pVdbe->aOp[context->iOp-1]; assert( pOp->opcode==OP_CollSeq ); assert( pOp->p4type==P4_COLLSEQ ); return pOp->p4.pColl; @@ -95596,13 +96663,13 @@ static void printfFunc( StrAccum str; const char *zFormat; int n; + sqlite3 *db = sqlite3_context_db_handle(context); if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){ x.nArg = argc-1; x.nUsed = 0; x.apArg = argv+1; - sqlite3StrAccumInit(&str, 0, 0, SQLITE_MAX_LENGTH); - str.db = sqlite3_context_db_handle(context); + sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x); n = str.nChar; sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, @@ -95657,6 +96724,14 @@ static void substrFunc( } } } +#ifdef SQLITE_SUBSTR_COMPATIBILITY + /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as + ** as substr(X,1,N) - it returns the first N characters of X. This + ** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8] + ** from 2009-02-02 for compatibility of applications that exploited the + ** old buggy behavior. */ + if( p1==0 ) p1 = 1; /* <rdar://problem/6778339> */ +#endif if( argc==3 ){ p2 = sqlite3_value_int(argv[2]); if( p2<0 ){ @@ -95744,7 +96819,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ #endif /* -** Allocate nByte bytes of space using sqlite3_malloc(). If the +** Allocate nByte bytes of space using sqlite3Malloc(). If the ** allocation fails, call sqlite3_result_error_nomem() to notify ** the database handle that malloc() has failed and return NULL. ** If nByte is larger than the maximum string or blob length, then @@ -96118,7 +97193,7 @@ static int patternCompare( /* ** The sqlite3_strglob() interface. */ -SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){ +SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlobPattern, const char *zString){ return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0; } @@ -96413,7 +97488,7 @@ static void charFunc( ){ unsigned char *z, *zOut; int i; - zOut = z = sqlite3_malloc( argc*4+1 ); + zOut = z = sqlite3_malloc64( argc*4+1 ); if( z==0 ){ sqlite3_result_error_nomem(context); return; @@ -96561,7 +97636,7 @@ static void replaceFunc( return; } zOld = zOut; - zOut = sqlite3_realloc(zOut, (int)nOut); + zOut = sqlite3_realloc64(zOut, (int)nOut); if( zOut==0 ){ sqlite3_result_error_nomem(context); sqlite3_free(zOld); @@ -96923,8 +97998,7 @@ static void groupConcatStep( if( pAccum ){ sqlite3 *db = sqlite3_context_db_handle(context); - int firstTerm = pAccum->useMalloc==0; - pAccum->useMalloc = 2; + int firstTerm = pAccum->mxAlloc==0; pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; if( !firstTerm ){ if( argc==2 ){ @@ -97008,6 +98082,11 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive) ** then set aWc[0] through aWc[2] to the wildcard characters and ** return TRUE. If the function is not a LIKE-style function then ** return FALSE. +** +** *pIsNocase is set to true if uppercase and lowercase are equivalent for +** the function (default for LIKE). If the function makes the distinction +** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to +** false. */ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ FuncDef *pDef; @@ -98339,7 +99418,8 @@ static Trigger *fkActionTrigger( iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; assert( iFromCol>=0 ); - tToCol.z = pIdx ? pTab->aCol[pIdx->aiColumn[i]].zName : "oid"; + assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) ); + tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName; tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName; tToCol.n = sqlite3Strlen30(tToCol.z); @@ -98351,10 +99431,10 @@ static Trigger *fkActionTrigger( ** parent table are used for the comparison. */ pEq = sqlite3PExpr(pParse, TK_EQ, sqlite3PExpr(pParse, TK_DOT, - sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld), - sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol) + sqlite3ExprAlloc(db, TK_ID, &tOld, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0) , 0), - sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol) + sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0) , 0); pWhere = sqlite3ExprAnd(db, pWhere, pEq); @@ -98366,12 +99446,12 @@ static Trigger *fkActionTrigger( if( pChanges ){ pEq = sqlite3PExpr(pParse, TK_IS, sqlite3PExpr(pParse, TK_DOT, - sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld), - sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol), + sqlite3ExprAlloc(db, TK_ID, &tOld, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0), 0), sqlite3PExpr(pParse, TK_DOT, - sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew), - sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol), + sqlite3ExprAlloc(db, TK_ID, &tNew, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0), 0), 0); pWhen = sqlite3ExprAnd(db, pWhen, pEq); @@ -98381,8 +99461,8 @@ static Trigger *fkActionTrigger( Expr *pNew; if( action==OE_Cascade ){ pNew = sqlite3PExpr(pParse, TK_DOT, - sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew), - sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol) + sqlite3ExprAlloc(db, TK_ID, &tNew, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0) , 0); }else if( action==OE_SetDflt ){ Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt; @@ -98429,13 +99509,12 @@ static Trigger *fkActionTrigger( pTrigger = (Trigger *)sqlite3DbMallocZero(db, sizeof(Trigger) + /* struct Trigger */ sizeof(TriggerStep) + /* Single step in trigger program */ - nFrom + 1 /* Space for pStep->target.z */ + nFrom + 1 /* Space for pStep->zTarget */ ); if( pTrigger ){ pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1]; - pStep->target.z = (char *)&pStep[1]; - pStep->target.n = nFrom; - memcpy((char *)pStep->target.z, zFrom, nFrom); + pStep->zTarget = (char *)&pStep[1]; + memcpy((char *)pStep->zTarget, zFrom, nFrom); pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); @@ -98900,20 +99979,23 @@ static int xferOptimization( /* ** This routine is called to handle SQL of the following forms: ** -** insert into TABLE (IDLIST) values(EXPRLIST) +** insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),... ** insert into TABLE (IDLIST) select +** insert into TABLE (IDLIST) default values ** ** The IDLIST following the table name is always optional. If omitted, -** then a list of all columns for the table is substituted. The IDLIST -** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted. +** then a list of all (non-hidden) columns for the table is substituted. +** The IDLIST appears in the pColumn parameter. pColumn is NULL if IDLIST +** is omitted. ** -** The pList parameter holds EXPRLIST in the first form of the INSERT -** statement above, and pSelect is NULL. For the second form, pList is -** NULL and pSelect is a pointer to the select statement used to generate -** data for the insert. +** For the pSelect parameter holds the values to be inserted for the +** first two forms shown above. A VALUES clause is really just short-hand +** for a SELECT statement that omits the FROM clause and everything else +** that follows. If the pSelect parameter is NULL, that means that the +** DEFAULT VALUES form of the INSERT statement is intended. ** ** The code generated follows one of four templates. For a simple -** insert with data coming from a VALUES clause, the code executes +** insert with data coming from a single-row VALUES clause, the code executes ** once straight down through. Pseudo-code follows (we call this ** the "1st template"): ** @@ -99020,7 +100102,7 @@ SQLITE_PRIVATE void sqlite3Insert( u8 useTempTable = 0; /* Store SELECT results in intermediate table */ u8 appendFlag = 0; /* True if the insert is likely to be an append */ u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */ - u8 bIdListInOrder = 1; /* True if IDLIST is in table order */ + u8 bIdListInOrder; /* True if IDLIST is in table order */ ExprList *pList = 0; /* List of VALUES() to be inserted */ /* Register allocations */ @@ -99045,8 +100127,8 @@ SQLITE_PRIVATE void sqlite3Insert( } /* If the Select object is really just a simple VALUES() list with a - ** single row values (the common case) then keep that one row of values - ** and go ahead and discard the Select object + ** single row (the common case) then keep that one row of values + ** and discard the other (unused) parts of the pSelect object */ if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){ pList = pSelect->pEList; @@ -99154,6 +100236,7 @@ SQLITE_PRIVATE void sqlite3Insert( ** is appears in the original table. (The index of the INTEGER ** PRIMARY KEY in the original table is pTab->iPKey.) */ + bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0; if( pColumn ){ for(i=0; i<pColumn->nId; i++){ pColumn->a[i].idx = -1; @@ -99189,7 +100272,8 @@ SQLITE_PRIVATE void sqlite3Insert( ** co-routine is the common header to the 3rd and 4th templates. */ if( pSelect ){ - /* Data is coming from a SELECT. Generate a co-routine to run the SELECT */ + /* Data is coming from a SELECT or from a multi-row VALUES clause. + ** Generate a co-routine to run the SELECT. */ int regYield; /* Register holding co-routine entry-point */ int addrTop; /* Top of the co-routine */ int rc; /* Result code */ @@ -99202,8 +100286,7 @@ SQLITE_PRIVATE void sqlite3Insert( dest.nSdst = pTab->nCol; rc = sqlite3Select(pParse, pSelect, &dest); regFromSelect = dest.iSdst; - assert( pParse->nErr==0 || rc ); - if( rc || db->mallocFailed ) goto insert_cleanup; + if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup; sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ assert( pSelect->pEList ); @@ -99251,8 +100334,8 @@ SQLITE_PRIVATE void sqlite3Insert( sqlite3ReleaseTempReg(pParse, regTempRowid); } }else{ - /* This is the case if the data for the INSERT is coming from a VALUES - ** clause + /* This is the case if the data for the INSERT is coming from a + ** single-row VALUES clause */ NameContext sNC; memset(&sNC, 0, sizeof(sNC)); @@ -100323,6 +101406,7 @@ static int xferOptimization( int onError, /* How to handle constraint errors */ int iDbDest /* The database of pDest */ ){ + sqlite3 *db = pParse->db; ExprList *pEList; /* The result set of the SELECT */ Table *pSrc; /* The table in the FROM clause of SELECT */ Index *pSrcIdx, *pDestIdx; /* Source and destination indices */ @@ -100470,11 +101554,11 @@ static int xferOptimization( ** the extra complication to make this rule less restrictive is probably ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e] */ - if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){ + if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){ return 0; } #endif - if( (pParse->db->flags & SQLITE_CountRows)!=0 ){ + if( (db->flags & SQLITE_CountRows)!=0 ){ return 0; /* xfer opt does not play well with PRAGMA count_changes */ } @@ -100485,7 +101569,7 @@ static int xferOptimization( #ifdef SQLITE_TEST sqlite3_xferopt_count++; #endif - iDbSrc = sqlite3SchemaToIndex(pParse->db, pSrc->pSchema); + iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema); v = sqlite3GetVdbe(pParse); sqlite3CodeVerifySchema(pParse, iDbSrc); iSrc = pParse->nTab++; @@ -100495,14 +101579,18 @@ static int xferOptimization( regRowid = sqlite3GetTempReg(pParse); sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); assert( HasRowid(pDest) || destHasUniqueIdx ); - if( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */ + if( (db->flags & SQLITE_Vacuum)==0 && ( + (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */ || destHasUniqueIdx /* (2) */ || (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */ - ){ + )){ /* In some circumstances, we are able to run the xfer optimization - ** only if the destination table is initially empty. This code makes - ** that determination. Conditions under which the destination must - ** be empty: + ** only if the destination table is initially empty. Unless the + ** SQLITE_Vacuum flag is set, this block generates code to make + ** that determination. If SQLITE_Vacuum is set, then the destination + ** table is always empty. + ** + ** Conditions under which the destination must be empty: ** ** (1) There is no INTEGER PRIMARY KEY but there are indices. ** (If the destination is not initially empty, the rowid fields @@ -100545,6 +101633,7 @@ static int xferOptimization( sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName); } for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ + u8 useSeekResult = 0; for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){ if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; } @@ -100558,7 +101647,33 @@ static int xferOptimization( VdbeComment((v, "%s", pDestIdx->zName)); addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData); + if( db->flags & SQLITE_Vacuum ){ + /* This INSERT command is part of a VACUUM operation, which guarantees + ** that the destination table is empty. If all indexed columns use + ** collation sequence BINARY, then it can also be assumed that the + ** index will be populated by inserting keys in strictly sorted + ** order. In this case, instead of seeking within the b-tree as part + ** of every OP_IdxInsert opcode, an OP_Last is added before the + ** OP_IdxInsert to seek to the point within the b-tree where each key + ** should be inserted. This is faster. + ** + ** If any of the indexed columns use a collation sequence other than + ** BINARY, this optimization is disabled. This is because the user + ** might change the definition of a collation sequence and then run + ** a VACUUM command. In that case keys may not be written in strictly + ** sorted order. */ + for(i=0; i<pSrcIdx->nColumn; i++){ + char *zColl = pSrcIdx->azColl[i]; + assert( zColl!=0 ); + if( sqlite3_stricmp("BINARY", zColl) ) break; + } + if( i==pSrcIdx->nColumn ){ + useSeekResult = OPFLAG_USESEEKRESULT; + sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1); + } + } sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1); + sqlite3VdbeChangeP5(v, useSeekResult); sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); @@ -100608,7 +101723,7 @@ static int xferOptimization( ** argument to xCallback(). If xCallback=NULL then no callback ** is invoked, even for queries. */ -SQLITE_API int sqlite3_exec( +SQLITE_API int SQLITE_STDCALL sqlite3_exec( sqlite3 *db, /* The database on which the SQL executes */ const char *zSql, /* The SQL to be executed */ sqlite3_callback xCallback, /* Invoke this callback routine */ @@ -101677,7 +102792,7 @@ static int sqlite3LoadExtension( const char *zEntry; char *zAltEntry = 0; void **aHandle; - int nMsg = 300 + sqlite3Strlen30(zFile); + u64 nMsg = 300 + sqlite3Strlen30(zFile); int ii; /* Shared library endings to try if zFile cannot be loaded as written */ @@ -101720,7 +102835,7 @@ static int sqlite3LoadExtension( #endif if( handle==0 ){ if( pzErrMsg ){ - *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg); + *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg); if( zErrmsg ){ sqlite3_snprintf(nMsg, zErrmsg, "unable to open shared library [%s]", zFile); @@ -101746,7 +102861,7 @@ static int sqlite3LoadExtension( if( xInit==0 && zProc==0 ){ int iFile, iEntry, c; int ncFile = sqlite3Strlen30(zFile); - zAltEntry = sqlite3_malloc(ncFile+30); + zAltEntry = sqlite3_malloc64(ncFile+30); if( zAltEntry==0 ){ sqlite3OsDlClose(pVfs, handle); return SQLITE_NOMEM; @@ -101768,7 +102883,7 @@ static int sqlite3LoadExtension( if( xInit==0 ){ if( pzErrMsg ){ nMsg += sqlite3Strlen30(zEntry); - *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg); + *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg); if( zErrmsg ){ sqlite3_snprintf(nMsg, zErrmsg, "no entry point [%s] in shared library [%s]", zEntry, zFile); @@ -101803,7 +102918,7 @@ static int sqlite3LoadExtension( db->aExtension[db->nExtension++] = handle; return SQLITE_OK; } -SQLITE_API int sqlite3_load_extension( +SQLITE_API int SQLITE_STDCALL sqlite3_load_extension( sqlite3 *db, /* Load the extension into this database connection */ const char *zFile, /* Name of the shared library containing extension */ const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ @@ -101834,7 +102949,7 @@ SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){ ** Enable or disable extension loading. Extension loading is disabled by ** default so as not to open security holes in older applications. */ -SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ +SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff){ sqlite3_mutex_enter(db->mutex); if( onoff ){ db->flags |= SQLITE_LoadExtension; @@ -101867,7 +102982,7 @@ static const sqlite3_api_routines sqlite3Apis = { 0 }; */ typedef struct sqlite3AutoExtList sqlite3AutoExtList; static SQLITE_WSD struct sqlite3AutoExtList { - int nExt; /* Number of entries in aExt[] */ + u32 nExt; /* Number of entries in aExt[] */ void (**aExt)(void); /* Pointers to the extension init functions */ } sqlite3Autoext = { 0, 0 }; @@ -101891,7 +103006,7 @@ static SQLITE_WSD struct sqlite3AutoExtList { ** Register a statically linked extension that is automatically ** loaded by every new database connection. */ -SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){ +SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xInit)(void)){ int rc = SQLITE_OK; #ifndef SQLITE_OMIT_AUTOINIT rc = sqlite3_initialize(); @@ -101900,7 +103015,7 @@ SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){ }else #endif { - int i; + u32 i; #if SQLITE_THREADSAFE sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); #endif @@ -101910,9 +103025,9 @@ SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){ if( wsdAutoext.aExt[i]==xInit ) break; } if( i==wsdAutoext.nExt ){ - int nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]); + u64 nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]); void (**aNew)(void); - aNew = sqlite3_realloc(wsdAutoext.aExt, nByte); + aNew = sqlite3_realloc64(wsdAutoext.aExt, nByte); if( aNew==0 ){ rc = SQLITE_NOMEM; }else{ @@ -101936,7 +103051,7 @@ SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){ ** Return 1 if xInit was found on the list and removed. Return 0 if xInit ** was not on the list. */ -SQLITE_API int sqlite3_cancel_auto_extension(void (*xInit)(void)){ +SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xInit)(void)){ #if SQLITE_THREADSAFE sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); #endif @@ -101944,7 +103059,7 @@ SQLITE_API int sqlite3_cancel_auto_extension(void (*xInit)(void)){ int n = 0; wsdAutoextInit; sqlite3_mutex_enter(mutex); - for(i=wsdAutoext.nExt-1; i>=0; i--){ + for(i=(int)wsdAutoext.nExt-1; i>=0; i--){ if( wsdAutoext.aExt[i]==xInit ){ wsdAutoext.nExt--; wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt]; @@ -101959,7 +103074,7 @@ SQLITE_API int sqlite3_cancel_auto_extension(void (*xInit)(void)){ /* ** Reset the automatic extension loading mechanism. */ -SQLITE_API void sqlite3_reset_auto_extension(void){ +SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void){ #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize()==SQLITE_OK ) #endif @@ -101982,7 +103097,7 @@ SQLITE_API void sqlite3_reset_auto_extension(void){ ** If anything goes wrong, set an error in the database connection. */ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ - int i; + u32 i; int go = 1; int rc; int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); @@ -102041,11 +103156,18 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ #endif /*************************************************************************** -** The next block of code, including the PragTyp_XXXX macro definitions and -** the aPragmaName[] object is composed of generated code. DO NOT EDIT. -** -** To add new pragmas, edit the code in ../tool/mkpragmatab.tcl and rerun -** that script. Then copy/paste the output in place of the following: +** The "pragma.h" include file is an automatically generated file that +** that includes the PragType_XXXX macro definitions and the aPragmaName[] +** object. This ensures that the aPragmaName[] table is arranged in +** lexicographical order to facility a binary search of the pragma name. +** Do not edit pragma.h directly. Edit and rerun the script in at +** ../tool/mkpragmatab.tcl. */ +/************** Include pragma.h in the middle of pragma.c *******************/ +/************** Begin file pragma.h ******************************************/ +/* DO NOT EDIT! +** This file is automatically generated by the script at +** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit +** that script and rerun it. */ #define PragTyp_HEADER_VALUE 0 #define PragTyp_AUTO_VACUUM 1 @@ -102280,6 +103402,10 @@ static const struct sPragmaNames { /* ePragTyp: */ PragTyp_INDEX_LIST, /* ePragFlag: */ PragFlag_NeedSchema, /* iArg: */ 0 }, + { /* zName: */ "index_xinfo", + /* ePragTyp: */ PragTyp_INDEX_INFO, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 1 }, #endif #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) { /* zName: */ "integrity_check", @@ -102496,9 +103622,10 @@ static const struct sPragmaNames { /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, #endif }; -/* Number of pragmas: 58 on by default, 71 total. */ -/* End of the automatically generated pragma table. -***************************************************************************/ +/* Number of pragmas: 59 on by default, 72 total. */ + +/************** End of pragma.h **********************************************/ +/************** Continuing where we left off in pragma.c *********************/ /* ** Interpret the given string as a safety level. Return 0 for OFF, @@ -102634,15 +103761,15 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){ */ static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){ Vdbe *v = sqlite3GetVdbe(pParse); - int mem = ++pParse->nMem; + int nMem = ++pParse->nMem; i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value)); if( pI64 ){ memcpy(pI64, &value, sizeof(value)); } - sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64); + sqlite3VdbeAddOp4(v, OP_Int64, 0, nMem, 0, (char*)pI64, P4_INT64); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC); - sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); + sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1); } @@ -102751,6 +103878,7 @@ SQLITE_PRIVATE void sqlite3Pragma( sqlite3 *db = pParse->db; /* The database connection */ Db *pDb; /* The specific database being pragmaed */ Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ + const struct sPragmaNames *pPragma; if( v==0 ) return; sqlite3VdbeRunOnlyOnce(v); @@ -102786,6 +103914,17 @@ SQLITE_PRIVATE void sqlite3Pragma( /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS ** connection. If it returns SQLITE_OK, then assume that the VFS ** handled the pragma and generate a no-op prepared statement. + ** + ** IMPLEMENTATION-OF: R-12238-55120 Whenever a PRAGMA statement is parsed, + ** an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file + ** object corresponding to the database file to which the pragma + ** statement refers. + ** + ** IMPLEMENTATION-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA + ** file control is an array of pointers to strings (char**) in which the + ** second element of the array is the name of the pragma and the third + ** element is the argument to the pragma or NULL if the pragma has no + ** argument. */ aFcntl[0] = 0; aFcntl[1] = zLeft; @@ -102795,11 +103934,11 @@ SQLITE_PRIVATE void sqlite3Pragma( rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); if( rc==SQLITE_OK ){ if( aFcntl[0] ){ - int mem = ++pParse->nMem; - sqlite3VdbeAddOp4(v, OP_String8, 0, mem, 0, aFcntl[0], 0); + int nMem = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_String8, 0, nMem, 0, aFcntl[0], 0); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC); - sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); + sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1); sqlite3_free(aFcntl[0]); } goto pragma_out; @@ -102828,14 +103967,15 @@ SQLITE_PRIVATE void sqlite3Pragma( } } if( lwr>upr ) goto pragma_out; + pPragma = &aPragmaNames[mid]; /* Make sure the database schema is loaded if the pragma requires that */ - if( (aPragmaNames[mid].mPragFlag & PragFlag_NeedSchema)!=0 ){ + if( (pPragma->mPragFlag & PragFlag_NeedSchema)!=0 ){ if( sqlite3ReadSchema(pParse) ) goto pragma_out; } /* Jump to the appropriate pragma handler */ - switch( aPragmaNames[mid].ePragTyp ){ + switch( pPragma->ePragTyp ){ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) /* @@ -103403,7 +104543,9 @@ SQLITE_PRIVATE void sqlite3Pragma( sqlite3ErrorMsg(pParse, "Safety level may not be changed inside a transaction"); }else{ - pDb->safety_level = getSafetyLevel(zRight,0,1)+1; + int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK; + if( iLevel==0 ) iLevel = 1; + pDb->safety_level = iLevel; setAllPagerFlags(db); } } @@ -103414,10 +104556,9 @@ SQLITE_PRIVATE void sqlite3Pragma( #ifndef SQLITE_OMIT_FLAG_PRAGMAS case PragTyp_FLAG: { if( zRight==0 ){ - returnSingleInt(pParse, aPragmaNames[mid].zName, - (db->flags & aPragmaNames[mid].iArg)!=0 ); + returnSingleInt(pParse, pPragma->zName, (db->flags & pPragma->iArg)!=0 ); }else{ - int mask = aPragmaNames[mid].iArg; /* Mask of bits to set or clear. */ + int mask = pPragma->iArg; /* Mask of bits to set or clear. */ if( db->autoCommit==0 ){ /* Foreign key support may not be enabled or disabled while not ** in auto-commit mode. */ @@ -103499,7 +104640,7 @@ SQLITE_PRIVATE void sqlite3Pragma( }else if( pPk==0 ){ k = 1; }else{ - for(k=1; ALWAYS(k<=pTab->nCol) && pPk->aiColumn[k-1]!=i; k++){} + for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){} } sqlite3VdbeAddOp2(v, OP_Integer, k, 6); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6); @@ -103546,20 +104687,42 @@ SQLITE_PRIVATE void sqlite3Pragma( pIdx = sqlite3FindIndex(db, zRight, zDb); if( pIdx ){ int i; + int mx; + if( pPragma->iArg ){ + /* PRAGMA index_xinfo (newer version with more rows and columns) */ + mx = pIdx->nColumn; + pParse->nMem = 6; + }else{ + /* PRAGMA index_info (legacy version) */ + mx = pIdx->nKeyCol; + pParse->nMem = 3; + } pTab = pIdx->pTable; - sqlite3VdbeSetNumCols(v, 3); - pParse->nMem = 3; + sqlite3VdbeSetNumCols(v, pParse->nMem); sqlite3CodeVerifySchema(pParse, iDb); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC); sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC); sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC); - for(i=0; i<pIdx->nKeyCol; i++){ + if( pPragma->iArg ){ + sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "desc", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "coll", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "key", SQLITE_STATIC); + } + for(i=0; i<mx; i++){ i16 cnum = pIdx->aiColumn[i]; sqlite3VdbeAddOp2(v, OP_Integer, i, 1); sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2); - assert( pTab->nCol>cnum ); - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); + if( cnum<0 ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, 3); + }else{ + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0); + } + if( pPragma->iArg ){ + sqlite3VdbeAddOp2(v, OP_Integer, pIdx->aSortOrder[i], 4); + sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, pIdx->azColl[i], 0); + sqlite3VdbeAddOp2(v, OP_Integer, i<pIdx->nKeyCol, 6); + } + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem); } } } @@ -103572,17 +104735,22 @@ SQLITE_PRIVATE void sqlite3Pragma( pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ v = sqlite3GetVdbe(pParse); - sqlite3VdbeSetNumCols(v, 3); - pParse->nMem = 3; + sqlite3VdbeSetNumCols(v, 5); + pParse->nMem = 5; sqlite3CodeVerifySchema(pParse, iDb); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "origin", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "partial", SQLITE_STATIC); for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ + const char *azOrigin[] = { "c", "u", "pk" }; sqlite3VdbeAddOp2(v, OP_Integer, i, 1); sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); sqlite3VdbeAddOp2(v, OP_Integer, IsUniqueIndex(pIdx), 3); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); + sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, azOrigin[pIdx->idxType], 0); + sqlite3VdbeAddOp2(v, OP_Integer, pIdx->pPartIdxWhere!=0, 5); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5); } } } @@ -104152,9 +105320,9 @@ SQLITE_PRIVATE void sqlite3Pragma( ** applications for any purpose. */ case PragTyp_HEADER_VALUE: { - int iCookie = aPragmaNames[mid].iArg; /* Which cookie to read or write */ + int iCookie = pPragma->iArg; /* Which cookie to read or write */ sqlite3VdbeUsesBtree(v, iDb); - if( zRight && (aPragmaNames[mid].mPragFlag & PragFlag_ReadOnly)==0 ){ + if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){ /* Write the specified cookie value */ static const VdbeOpList setCookie[] = { { OP_Transaction, 0, 1, 0}, /* 0 */ @@ -104256,8 +105424,9 @@ SQLITE_PRIVATE void sqlite3Pragma( /* ** PRAGMA shrink_memory ** - ** This pragma attempts to free as much memory as possible from the - ** current database connection. + ** IMPLEMENTATION-OF: R-23445-46109 This pragma causes the database + ** connection on which it is invoked to free up as much memory as it + ** can, by calling sqlite3_db_release_memory(). */ case PragTyp_SHRINK_MEMORY: { sqlite3_db_release_memory(db); @@ -104274,7 +105443,7 @@ SQLITE_PRIVATE void sqlite3Pragma( ** disables the timeout. */ /*case PragTyp_BUSY_TIMEOUT*/ default: { - assert( aPragmaNames[mid].ePragTyp==PragTyp_BUSY_TIMEOUT ); + assert( pPragma->ePragTyp==PragTyp_BUSY_TIMEOUT ); if( zRight ){ sqlite3_busy_timeout(db, sqlite3Atoi(zRight)); } @@ -104286,8 +105455,12 @@ SQLITE_PRIVATE void sqlite3Pragma( ** PRAGMA soft_heap_limit ** PRAGMA soft_heap_limit = N ** - ** Call sqlite3_soft_heap_limit64(N). Return the result. If N is omitted, - ** use -1. + ** IMPLEMENTATION-OF: R-26343-45930 This pragma invokes the + ** sqlite3_soft_heap_limit64() interface with the argument N, if N is + ** specified and is a non-negative integer. + ** IMPLEMENTATION-OF: R-64451-07163 The soft_heap_limit pragma always + ** returns the same integer that would be returned by the + ** sqlite3_soft_heap_limit64(-1) C-language function. */ case PragTyp_SOFT_HEAP_LIMIT: { sqlite3_int64 N; @@ -104473,7 +105646,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[1]==0 ){ corruptSchema(pData, argv[0], 0); - }else if( argv[2] && argv[2][0] ){ + }else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){ /* Call the parser to process a CREATE TABLE, INDEX or VIEW. ** But because db->init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data @@ -104504,8 +105677,8 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char } } sqlite3_finalize(pStmt); - }else if( argv[0]==0 ){ - corruptSchema(pData, 0, 0); + }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){ + corruptSchema(pData, argv[0], 0); }else{ /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE @@ -105183,7 +106356,7 @@ SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){ ** and the statement is automatically recompiled if an schema change ** occurs. */ -SQLITE_API int sqlite3_prepare( +SQLITE_API int SQLITE_STDCALL sqlite3_prepare( sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ @@ -105195,7 +106368,7 @@ SQLITE_API int sqlite3_prepare( assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ return rc; } -SQLITE_API int sqlite3_prepare_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2( sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ @@ -105271,7 +106444,7 @@ static int sqlite3Prepare16( ** and the statement is automatically recompiled if an schema change ** occurs. */ -SQLITE_API int sqlite3_prepare16( +SQLITE_API int SQLITE_STDCALL sqlite3_prepare16( sqlite3 *db, /* Database handle. */ const void *zSql, /* UTF-16 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ @@ -105283,7 +106456,7 @@ SQLITE_API int sqlite3_prepare16( assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ return rc; } -SQLITE_API int sqlite3_prepare16_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2( sqlite3 *db, /* Database handle. */ const void *zSql, /* UTF-16 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ @@ -105412,7 +106585,6 @@ SQLITE_PRIVATE Select *sqlite3SelectNew( Select standin; sqlite3 *db = pParse->db; pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); - assert( db->mallocFailed || !pOffset || pLimit ); /* OFFSET implies LIMIT */ if( pNew==0 ){ assert( db->mallocFailed ); pNew = &standin; @@ -105432,7 +106604,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew( pNew->op = TK_SELECT; pNew->pLimit = pLimit; pNew->pOffset = pOffset; - assert( pOffset==0 || pLimit!=0 ); + assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 ); pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; if( db->mallocFailed ) { @@ -105864,20 +107036,17 @@ static void pushOntoSorter( } sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord); if( pSelect->iLimit ){ - int addr1, addr2; + int addr; int iLimit; if( pSelect->iOffset ){ iLimit = pSelect->iOffset+1; }else{ iLimit = pSelect->iLimit; } - addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1); - addr2 = sqlite3VdbeAddOp0(v, OP_Goto); - sqlite3VdbeJumpHere(v, addr1); + addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, -1); VdbeCoverage(v); sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor); sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor); - sqlite3VdbeJumpHere(v, addr2); + sqlite3VdbeJumpHere(v, addr); } } @@ -106274,7 +107443,7 @@ static void selectInnerLoop( ** the output for us. */ if( pSort==0 && p->iLimit ){ - sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); } } @@ -106685,7 +107854,7 @@ static const char *columnTypeImpl( ** of the SELECT statement. Return the declaration type and origin ** data for the result-set column of the sub-select. */ - if( iCol>=0 && ALWAYS(iCol<pS->pEList->nExpr) ){ + if( iCol>=0 && iCol<pS->pEList->nExpr ){ /* If iCol is less than zero, then the expression requests the ** rowid of the sub-select or view. This expression is legal (see ** test case misc2.2.2) - it always evaluates to NULL. @@ -107005,12 +108174,14 @@ static void selectAddColumnTypeAndCollation( a = pSelect->pEList->a; for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ p = a[i].pExpr; - pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst)); + if( pCol->zType==0 ){ + pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst)); + } szAll += pCol->szEst; pCol->affinity = sqlite3ExprAffinity(p); if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE; pColl = sqlite3ExprCollSeq(pParse, p); - if( pColl ){ + if( pColl && pCol->zColl==0 ){ pCol->zColl = sqlite3DbStrDup(db, pColl->zName); } } @@ -107127,7 +108298,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ sqlite3ExprCode(pParse, p->pLimit, iLimit); sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v); VdbeComment((v, "LIMIT counter")); - sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v); } if( p->pOffset ){ p->iOffset = iOffset = ++pParse->nMem; @@ -107346,7 +108517,7 @@ static void generateWithRecursiveQuery( selectInnerLoop(pParse, p, p->pEList, iCurrent, 0, 0, pDest, addrCont, addrBreak); if( regLimit ){ - sqlite3VdbeAddOp3(v, OP_IfZero, regLimit, addrBreak, -1); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak); VdbeCoverage(v); } sqlite3VdbeResolveLabel(v, addrCont); @@ -107412,8 +108583,7 @@ static int multiSelectValues( int nExpr = p->pEList->nExpr; int nRow = 1; int rc = 0; - assert( p->pNext==0 ); - assert( p->selFlags & SF_AllValues ); + assert( p->selFlags & SF_MultiValue ); do{ assert( p->selFlags & SF_Values ); assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) ); @@ -107522,7 +108692,7 @@ static int multiSelect( /* Special handling for a compound-select that originates as a VALUES clause. */ - if( p->selFlags & SF_AllValues ){ + if( p->selFlags & SF_MultiValue ){ rc = multiSelectValues(pParse, p, &dest); goto multi_select_end; } @@ -107571,7 +108741,7 @@ static int multiSelect( p->iLimit = pPrior->iLimit; p->iOffset = pPrior->iOffset; if( p->iLimit ){ - addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); VdbeCoverage(v); + addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); VdbeComment((v, "Jump ahead if LIMIT reached")); } explainSetInteger(iSub2, pParse->iNextSelectId); @@ -107907,7 +109077,7 @@ static int generateOutputSubroutine( */ case SRT_Set: { int r1; - assert( pIn->nSdst==1 ); + assert( pIn->nSdst==1 || pParse->nErr>0 ); pDest->affSdst = sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst); r1 = sqlite3GetTempReg(pParse); @@ -107933,7 +109103,7 @@ static int generateOutputSubroutine( ** of the scan loop. */ case SRT_Mem: { - assert( pIn->nSdst==1 ); + assert( pIn->nSdst==1 || pParse->nErr>0 ); testcase( pIn->nSdst!=1 ); sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1); /* The LIMIT clause will jump out of the loop for us */ break; @@ -107948,7 +109118,7 @@ static int generateOutputSubroutine( pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst); pDest->nSdst = pIn->nSdst; } - sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst); + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst); sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); break; } @@ -107972,7 +109142,7 @@ static int generateOutputSubroutine( /* Jump to the end of the loop if the LIMIT is reached. */ if( p->iLimit ){ - sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); } /* Generate the subroutine return @@ -108164,8 +109334,10 @@ static int multiSelectOrderBy( if( aPermute ){ struct ExprList_item *pItem; for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){ - assert( pItem->u.x.iOrderByCol>0 - && pItem->u.x.iOrderByCol<=p->pEList->nExpr ); + assert( pItem->u.x.iOrderByCol>0 ); + /* assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ) is also true + ** but only for well-formed SELECT statements. */ + testcase( pItem->u.x.iOrderByCol > p->pEList->nExpr ); aPermute[i] = pItem->u.x.iOrderByCol - 1; } pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1); @@ -108375,7 +109547,7 @@ static int multiSelectOrderBy( /*** TBD: Insert subroutine calls to close cursors on incomplete **** subqueries ****/ explainComposite(pParse, p->op, iSub1, iSub2, 0); - return SQLITE_OK; + return pParse->nErr!=0; } #endif @@ -108495,7 +109667,10 @@ static void substSelect( ** ** (1) The subquery and the outer query do not both use aggregates. ** -** (2) The subquery is not an aggregate or the outer query is not a join. +** (2) The subquery is not an aggregate or (2a) the outer query is not a join +** and (2b) the outer query does not use subqueries other than the one +** FROM-clause subquery that is a candidate for flattening. (2b is +** due to ticket [2f7170d73bf9abf80] from 2015-02-09.) ** ** (3) The subquery is not the right operand of a left outer join ** (Originally ticket #306. Strengthened by ticket #3300) @@ -108632,8 +109807,17 @@ static int flattenSubquery( iParent = pSubitem->iCursor; pSub = pSubitem->pSelect; assert( pSub!=0 ); - if( isAgg && subqueryIsAgg ) return 0; /* Restriction (1) */ - if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; /* Restriction (2) */ + if( subqueryIsAgg ){ + if( isAgg ) return 0; /* Restriction (1) */ + if( pSrc->nSrc>1 ) return 0; /* Restriction (2a) */ + if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery)) + || (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0 + || (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0 + ){ + return 0; /* Restriction (2b) */ + } + } + pSubSrc = pSub->pSrc; assert( pSubSrc ); /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants, @@ -109175,7 +110359,10 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ pNew->pOrderBy = 0; p->pPrior = 0; p->pNext = 0; + p->pWith = 0; p->selFlags &= ~SF_Compound; + assert( (p->selFlags & SF_Converted)==0 ); + p->selFlags |= SF_Converted; assert( pNew->pPrior!=0 ); pNew->pPrior->pNext = pNew; pNew->pLimit = 0; @@ -109327,7 +110514,7 @@ static int withExpand( for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior); pEList = pLeft->pEList; if( pCte->pCols ){ - if( pEList->nExpr!=pCte->pCols->nExpr ){ + if( pEList && pEList->nExpr!=pCte->pCols->nExpr ){ sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns", pCte->zName, pEList->nExpr, pCte->pCols->nExpr ); @@ -109454,7 +110641,7 @@ static int selectExpander(Walker *pWalker, Select *p){ /* A sub-query in the FROM clause of a SELECT */ assert( pSel!=0 ); assert( pFrom->pTab==0 ); - sqlite3WalkSelect(pWalker, pSel); + if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; pTab->nRef = 1; @@ -109711,7 +110898,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ sqlite3WalkSelect(&w, pSelect); } w.xSelectCallback = selectExpander; - if( (pSelect->selFlags & SF_AllValues)==0 ){ + if( (pSelect->selFlags & SF_MultiValue)==0 ){ w.xSelectCallback2 = selectPopWith; } sqlite3WalkSelect(&w, pSelect); @@ -109897,7 +111084,8 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ } if( pF->iDistinct>=0 ){ addrNext = sqlite3VdbeMakeLabel(v); - assert( nArg==1 ); + testcase( nArg==0 ); /* Error condition */ + testcase( nArg>1 ); /* Also an error */ codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg); } if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ @@ -110053,6 +111241,13 @@ SQLITE_PRIVATE int sqlite3Select( } isAgg = (p->selFlags & SF_Aggregate)!=0; assert( pEList!=0 ); +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x100 ){ + SELECTTRACE(0x100,pParse,p, ("after name resolution:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + /* Begin generating code. */ @@ -110765,10 +111960,9 @@ SQLITE_PRIVATE int sqlite3Select( */ sqlite3VdbeResolveLabel(v, iEnd); - /* The SELECT was successfully coded. Set the return code to 0 - ** to indicate no errors. - */ - rc = 0; + /* The SELECT has been coded. If there is an error in the Parse structure, + ** set the return code to 1. Otherwise 0. */ + rc = (pParse->nErr>0); /* Control jumps to here if an error is encountered above, or upon ** successful coding of the SELECT. @@ -110798,9 +111992,9 @@ select_end: SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ int n = 0; pView = sqlite3TreeViewPush(pView, moreToFollow); - sqlite3TreeViewLine(pView, "SELECT%s%s", + sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p)", ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""), - ((p->selFlags & SF_Aggregate) ? " agg_flag" : "") + ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p ); if( p->pSrc && p->pSrc->nSrc ) n++; if( p->pWhere ) n++; @@ -110819,7 +112013,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m struct SrcList_item *pItem = &p->pSrc->a[i]; StrAccum x; char zLine[100]; - sqlite3StrAccumInit(&x, zLine, sizeof(zLine), 0); + sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor); if( pItem->zDatabase ){ sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName); @@ -110978,7 +112172,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ z = 0; }else{ int n = sqlite3Strlen30(argv[i])+1; - z = sqlite3_malloc( n ); + z = sqlite3_malloc64( n ); if( z==0 ) goto malloc_failed; memcpy(z, argv[i], n); } @@ -111003,7 +112197,7 @@ malloc_failed: ** Instead, the entire table should be passed to sqlite3_free_table() when ** the calling procedure is finished using it. */ -SQLITE_API int sqlite3_get_table( +SQLITE_API int SQLITE_STDCALL sqlite3_get_table( sqlite3 *db, /* The database on which the SQL executes */ const char *zSql, /* The SQL to be executed */ char ***pazResult, /* Write the result table here */ @@ -111027,7 +112221,7 @@ SQLITE_API int sqlite3_get_table( res.nData = 1; res.nAlloc = 20; res.rc = SQLITE_OK; - res.azResult = sqlite3_malloc(sizeof(char*)*res.nAlloc ); + res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc ); if( res.azResult==0 ){ db->errCode = SQLITE_NOMEM; return SQLITE_NOMEM; @@ -111055,7 +112249,7 @@ SQLITE_API int sqlite3_get_table( } if( res.nAlloc>res.nData ){ char **azNew; - azNew = sqlite3_realloc( res.azResult, sizeof(char*)*res.nData ); + azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData ); if( azNew==0 ){ sqlite3_free_table(&res.azResult[1]); db->errCode = SQLITE_NOMEM; @@ -111072,7 +112266,7 @@ SQLITE_API int sqlite3_get_table( /* ** This routine frees the space the sqlite3_get_table() malloced. */ -SQLITE_API void sqlite3_free_table( +SQLITE_API void SQLITE_STDCALL sqlite3_free_table( char **azResult /* Result returned from sqlite3_get_table() */ ){ if( azResult ){ @@ -111283,7 +112477,6 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( /* Do not create a trigger on a system table */ if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ sqlite3ErrorMsg(pParse, "cannot create trigger on system table"); - pParse->nErr++; goto trigger_cleanup; } @@ -111463,12 +112656,12 @@ static TriggerStep *triggerStepAllocate( ){ TriggerStep *pTriggerStep; - pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n); + pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); if( pTriggerStep ){ char *z = (char*)&pTriggerStep[1]; memcpy(z, pName->z, pName->n); - pTriggerStep->target.z = z; - pTriggerStep->target.n = pName->n; + sqlite3Dequote(z); + pTriggerStep->zTarget = z; pTriggerStep->op = op; } return pTriggerStep; @@ -111751,7 +112944,7 @@ SQLITE_PRIVATE Trigger *sqlite3TriggersExist( } /* -** Convert the pStep->target token into a SrcList and return a pointer +** Convert the pStep->zTarget string into a SrcList and return a pointer ** to that SrcList. ** ** This routine adds a specific database name, if needed, to the target when @@ -111764,17 +112957,17 @@ static SrcList *targetSrcList( Parse *pParse, /* The parsing context */ TriggerStep *pStep /* The trigger containing the target token */ ){ + sqlite3 *db = pParse->db; int iDb; /* Index of the database to use */ SrcList *pSrc; /* SrcList to be returned */ - pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0); + pSrc = sqlite3SrcListAppend(db, 0, 0, 0); if( pSrc ){ assert( pSrc->nSrc>0 ); - assert( pSrc->a!=0 ); - iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema); + pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget); + iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema); if( iDb==0 || iDb>=2 ){ - sqlite3 *db = pParse->db; - assert( iDb<pParse->db->nDb ); + assert( iDb<db->nDb ); pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName); } } @@ -111886,6 +113079,7 @@ static void transferParseError(Parse *pTo, Parse *pFrom){ if( pTo->nErr==0 ){ pTo->zErrMsg = pFrom->zErrMsg; pTo->nErr = pFrom->nErr; + pTo->rc = pFrom->rc; }else{ sqlite3DbFree(pFrom->db, pFrom->zErrMsg); } @@ -113170,7 +114364,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ ** cause problems for the call to BtreeSetPageSize() below. */ sqlite3BtreeCommit(pTemp); - nRes = sqlite3BtreeGetReserve(pMain); + nRes = sqlite3BtreeGetOptimalReserve(pMain); /* A VACUUM cannot change the pagesize of an encrypted database. */ #ifdef SQLITE_HAS_CODEC @@ -113236,6 +114430,8 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy ** the contents to the temporary database. */ + assert( (db->flags & SQLITE_Vacuum)==0 ); + db->flags |= SQLITE_Vacuum; rc = execExecSql(db, pzErrMsg, "SELECT 'INSERT INTO vacuum_db.' || quote(name) " "|| ' SELECT * FROM main.' || quote(name) || ';'" @@ -113243,6 +114439,8 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ "WHERE type = 'table' AND name!='sqlite_sequence' " " AND coalesce(rootpage,1)>0" ); + assert( (db->flags & SQLITE_Vacuum)!=0 ); + db->flags &= ~SQLITE_Vacuum; if( rc!=SQLITE_OK ) goto end_of_vacuum; /* Copy over the sequence table @@ -113381,6 +114579,8 @@ end_of_vacuum: struct VtabCtx { VTable *pVTable; /* The virtual table being constructed */ Table *pTab; /* The Table object to which the virtual table belongs */ + VtabCtx *pPrior; /* Parent context (if any) */ + int bDeclared; /* True after sqlite3_declare_vtab() is called */ }; /* @@ -113432,7 +114632,7 @@ static int createModule( /* ** External API function used to create a new virtual-table module. */ -SQLITE_API int sqlite3_create_module( +SQLITE_API int SQLITE_STDCALL sqlite3_create_module( sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ const sqlite3_module *pModule, /* The definition of the module */ @@ -113447,7 +114647,7 @@ SQLITE_API int sqlite3_create_module( /* ** External API function used to create a new virtual-table module. */ -SQLITE_API int sqlite3_create_module_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2( sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ const sqlite3_module *pModule, /* The definition of the module */ @@ -113746,6 +114946,7 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ char *zStmt; char *zWhere; int iDb; + int iReg; Vdbe *v; /* Compute the complete text of the CREATE VIRTUAL TABLE statement */ @@ -113780,8 +114981,10 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName); sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); - sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0, - pTab->zName, sqlite3Strlen30(pTab->zName) + 1); + + iReg = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_String8, 0, iReg, 0, pTab->zName, 0); + sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg); } /* If we are rereading the sqlite_master table create the in-memory @@ -113824,7 +115027,7 @@ SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){ pArg->z = p->z; pArg->n = p->n; }else{ - assert(pArg->z < p->z); + assert(pArg->z <= p->z); pArg->n = (int)(&p->z[p->n] - pArg->z); } } @@ -113841,15 +115044,27 @@ static int vtabCallConstructor( int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), char **pzErr ){ - VtabCtx sCtx, *pPriorCtx; + VtabCtx sCtx; VTable *pVTable; int rc; const char *const*azArg = (const char *const*)pTab->azModuleArg; int nArg = pTab->nModuleArg; char *zErr = 0; - char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName); + char *zModuleName; int iDb; + VtabCtx *pCtx; + + /* Check that the virtual-table is not already being initialized */ + for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){ + if( pCtx->pTab==pTab ){ + *pzErr = sqlite3MPrintf(db, + "vtable constructor called recursively: %s", pTab->zName + ); + return SQLITE_LOCKED; + } + } + zModuleName = sqlite3MPrintf(db, "%s", pTab->zName); if( !zModuleName ){ return SQLITE_NOMEM; } @@ -113870,11 +115085,13 @@ static int vtabCallConstructor( assert( xConstruct ); sCtx.pTab = pTab; sCtx.pVTable = pVTable; - pPriorCtx = db->pVtabCtx; + sCtx.pPrior = db->pVtabCtx; + sCtx.bDeclared = 0; db->pVtabCtx = &sCtx; rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); - db->pVtabCtx = pPriorCtx; + db->pVtabCtx = sCtx.pPrior; if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + assert( sCtx.pTab==pTab ); if( SQLITE_OK!=rc ){ if( zErr==0 ){ @@ -113890,13 +115107,14 @@ static int vtabCallConstructor( memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0])); pVTable->pVtab->pModule = pMod->pModule; pVTable->nRef = 1; - if( sCtx.pTab ){ + if( sCtx.bDeclared==0 ){ const char *zFormat = "vtable constructor did not declare schema: %s"; *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); sqlite3VtabUnlock(pVTable); rc = SQLITE_ERROR; }else{ int iCol; + u8 oooHidden = 0; /* If everything went according to plan, link the new VTable structure ** into the linked list headed by pTab->pVTable. Then loop through the ** columns of the table to see if any of them contain the token "hidden". @@ -113909,7 +115127,10 @@ static int vtabCallConstructor( char *zType = pTab->aCol[iCol].zType; int nType; int i = 0; - if( !zType ) continue; + if( !zType ){ + pTab->tabFlags |= oooHidden; + continue; + } nType = sqlite3Strlen30(zType); if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){ for(i=0; i<nType; i++){ @@ -113932,6 +115153,9 @@ static int vtabCallConstructor( zType[i-1] = '\0'; } pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN; + oooHidden = TF_OOOHidden; + }else{ + pTab->tabFlags |= oooHidden; } } } @@ -114059,22 +115283,26 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, ** valid to call this function from within the xCreate() or xConnect() of a ** virtual table module. */ -SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ +SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ + VtabCtx *pCtx; Parse *pParse; - int rc = SQLITE_OK; Table *pTab; char *zErr = 0; #ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){ + return SQLITE_MISUSE_BKPT; + } #endif sqlite3_mutex_enter(db->mutex); - if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){ + pCtx = db->pVtabCtx; + if( !pCtx || pCtx->bDeclared ){ sqlite3Error(db, SQLITE_MISUSE); sqlite3_mutex_leave(db->mutex); return SQLITE_MISUSE_BKPT; } + pTab = pCtx->pTab; assert( (pTab->tabFlags & TF_Virtual)!=0 ); pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); @@ -114097,7 +115325,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ pParse->pNewTable->nCol = 0; pParse->pNewTable->aCol = 0; } - db->pVtabCtx->pTab = 0; + pCtx->bDeclared = 1; }else{ sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr); sqlite3DbFree(db, zErr); @@ -114132,11 +115360,15 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){ - VTable *p = vtabDisconnectAll(db, pTab); - - assert( rc==SQLITE_OK ); + VTable *p; + for(p=pTab->pVTable; p; p=p->pNext){ + assert( p->pVtab ); + if( p->pVtab->nRef>0 ){ + return SQLITE_LOCKED; + } + } + p = vtabDisconnectAll(db, pTab); rc = p->pMod->pModule->xDestroy(p->pVtab); - /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ if( rc==SQLITE_OK ){ assert( pTab->pVTable==p && p->pNext==0 ); @@ -114287,7 +115519,7 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ int rc = SQLITE_OK; assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); - assert( iSavepoint>=0 ); + assert( iSavepoint>=-1 ); if( db->aVTrans ){ int i; for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ @@ -114405,7 +115637,7 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ if( pTab==pToplevel->apVtabLock[i] ) return; } n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]); - apVtabLock = sqlite3_realloc(pToplevel->apVtabLock, n); + apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n); if( apVtabLock ){ pToplevel->apVtabLock = apVtabLock; pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab; @@ -114421,7 +115653,7 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ ** The results of this routine are undefined unless it is called from ** within an xUpdate method. */ -SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){ +SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *db){ static const unsigned char aMap[] = { SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE }; @@ -114439,7 +115671,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){ ** the SQLite core with additional information about the behavior ** of the virtual table being implemented. */ -SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){ +SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3 *db, int op, ...){ va_list ap; int rc = SQLITE_OK; @@ -114565,6 +115797,8 @@ struct WhereLevel { int addrCont; /* Jump here to continue with the next loop cycle */ int addrFirst; /* First instruction of interior of the loop */ int addrBody; /* Beginning of the body of this loop */ + int iLikeRepCntr; /* LIKE range processing counter register */ + int addrLikeRep; /* LIKE range processing address */ u8 iFrom; /* Which entry in the FROM clause */ u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ int p1, p2; /* Operands of the opcode used to ends the loop */ @@ -114749,7 +115983,7 @@ struct WhereTerm { } u; LogEst truthProb; /* Probability of truth for this expression */ u16 eOperator; /* A WO_xx value describing <op> */ - u8 wtFlags; /* TERM_xxx bit flags. See below */ + u16 wtFlags; /* TERM_xxx bit flags. See below */ u8 nChild; /* Number of children that must disable us */ WhereClause *pWC; /* The clause this term is part of */ Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */ @@ -114771,6 +116005,9 @@ struct WhereTerm { #else # define TERM_VNULL 0x00 /* Disabled if not using stat3 */ #endif +#define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */ +#define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */ +#define TERM_LIKE 0x400 /* The original LIKE operator */ /* ** An instance of the WhereScan object is used as an iterator for locating @@ -115146,7 +116383,7 @@ static void whereClauseClear(WhereClause *pWC){ ** calling this routine. Such pointers may be reinitialized by referencing ** the pWC->a[] array. */ -static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){ +static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ WhereTerm *pTerm; int idx; testcase( wtFlags & TERM_VIRTUAL ); @@ -115199,13 +116436,14 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){ ** all terms of the WHERE clause. */ static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){ + Expr *pE2 = sqlite3ExprSkipCollate(pExpr); pWC->op = op; - if( pExpr==0 ) return; - if( pExpr->op!=op ){ + if( pE2==0 ) return; + if( pE2->op!=op ){ whereClauseInsert(pWC, pExpr, 0); }else{ - whereSplit(pWC, pExpr->pLeft, op); - whereSplit(pWC, pExpr->pRight, op); + whereSplit(pWC, pE2->pLeft, op); + whereSplit(pWC, pE2->pRight, op); } } @@ -115571,7 +116809,11 @@ static void exprAnalyzeAll( ** so and false if not. ** ** In order for the operator to be optimizible, the RHS must be a string -** literal that does not begin with a wildcard. +** literal that does not begin with a wildcard. The LHS must be a column +** that may only be NULL, a string, or a BLOB, never a number. (This means +** that virtual tables cannot participate in the LIKE optimization.) If the +** collating sequence for the column on the LHS must be appropriate for +** the operator. */ static int isLikeOrGlob( Parse *pParse, /* Parsing and code generating context */ @@ -115600,7 +116842,7 @@ static int isLikeOrGlob( pLeft = pList->a[1].pExpr; if( pLeft->op!=TK_COLUMN || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT - || IsVirtual(pLeft->pTab) + || IsVirtual(pLeft->pTab) /* Value might be numeric */ ){ /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must ** be the name of an indexed column with TEXT affinity. */ @@ -115710,6 +116952,79 @@ static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){ pWC->a[iParent].nChild++; } +/* +** Return the N-th AND-connected subterm of pTerm. Or if pTerm is not +** a conjunction, then return just pTerm when N==0. If N is exceeds +** the number of available subterms, return NULL. +*/ +static WhereTerm *whereNthSubterm(WhereTerm *pTerm, int N){ + if( pTerm->eOperator!=WO_AND ){ + return N==0 ? pTerm : 0; + } + if( N<pTerm->u.pAndInfo->wc.nTerm ){ + return &pTerm->u.pAndInfo->wc.a[N]; + } + return 0; +} + +/* +** Subterms pOne and pTwo are contained within WHERE clause pWC. The +** two subterms are in disjunction - they are OR-ed together. +** +** If these two terms are both of the form: "A op B" with the same +** A and B values but different operators and if the operators are +** compatible (if one is = and the other is <, for example) then +** add a new virtual AND term to pWC that is the combination of the +** two. +** +** Some examples: +** +** x<y OR x=y --> x<=y +** x=y OR x=y --> x=y +** x<=y OR x<y --> x<=y +** +** The following is NOT generated: +** +** x<y OR x>y --> x!=y +*/ +static void whereCombineDisjuncts( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* The complete WHERE clause */ + WhereTerm *pOne, /* First disjunct */ + WhereTerm *pTwo /* Second disjunct */ +){ + u16 eOp = pOne->eOperator | pTwo->eOperator; + sqlite3 *db; /* Database connection (for malloc) */ + Expr *pNew; /* New virtual expression */ + int op; /* Operator for the combined expression */ + int idxNew; /* Index in pWC of the next virtual term */ + + if( (pOne->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; + if( (pTwo->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; + if( (eOp & (WO_EQ|WO_LT|WO_LE))!=eOp + && (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return; + assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 ); + assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 ); + if( sqlite3ExprCompare(pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return; + if( sqlite3ExprCompare(pOne->pExpr->pRight, pTwo->pExpr->pRight, -1) )return; + /* If we reach this point, it means the two subterms can be combined */ + if( (eOp & (eOp-1))!=0 ){ + if( eOp & (WO_LT|WO_LE) ){ + eOp = WO_LE; + }else{ + assert( eOp & (WO_GT|WO_GE) ); + eOp = WO_GE; + } + } + db = pWC->pWInfo->pParse->db; + pNew = sqlite3ExprDup(db, pOne->pExpr, 0); + if( pNew==0 ) return; + for(op=TK_EQ; eOp!=(WO_EQ<<(op-TK_EQ)); op++){ assert( op<TK_GE ); } + pNew->op = op; + idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); + exprAnalyze(pSrc, pWC, idxNew); +} + #if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY) /* ** Analyze a term that consists of two or more OR-connected @@ -115734,6 +117049,7 @@ static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){ ** (C) t1.x=t2.y OR (t1.x=t2.z AND t1.y=15) ** (D) x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*') ** (E) (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6) +** (F) x>A OR (x=A AND y>=B) ** ** CASE 1: ** @@ -115750,6 +117066,16 @@ static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){ ** ** CASE 2: ** +** If there are exactly two disjuncts one side has x>A and the other side +** has x=A (for the same x and A) then add a new virtual conjunct term to the +** WHERE clause of the form "x>=A". Example: +** +** x>A OR (x=A AND y>B) adds: x>=A +** +** The added conjunct can sometimes be helpful in query planning. +** +** CASE 3: +** ** If all subterms are indexable by a single table T, then set ** ** WhereTerm.eOperator = WO_OR @@ -115876,12 +117202,26 @@ static void exprAnalyzeOrTerm( } /* - ** Record the set of tables that satisfy case 2. The set might be + ** Record the set of tables that satisfy case 3. The set might be ** empty. */ pOrInfo->indexable = indexable; pTerm->eOperator = indexable==0 ? 0 : WO_OR; + /* For a two-way OR, attempt to implementation case 2. + */ + if( indexable && pOrWc->nTerm==2 ){ + int iOne = 0; + WhereTerm *pOne; + while( (pOne = whereNthSubterm(&pOrWc->a[0],iOne++))!=0 ){ + int iTwo = 0; + WhereTerm *pTwo; + while( (pTwo = whereNthSubterm(&pOrWc->a[1],iTwo++))!=0 ){ + whereCombineDisjuncts(pSrc, pWC, pOne, pTwo); + } + } + } + /* ** chngToIN holds a set of tables that *might* satisfy case 1. But ** we have to do some additional checking to see if case 1 really @@ -116011,7 +117351,7 @@ static void exprAnalyzeOrTerm( }else{ sqlite3ExprListDelete(db, pList); } - pTerm->eOperator = WO_NOOP; /* case 1 trumps case 2 */ + pTerm->eOperator = WO_NOOP; /* case 1 trumps case 3 */ } } } @@ -116049,7 +117389,7 @@ static void exprAnalyze( Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */ Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */ int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */ - int noCase = 0; /* LIKE/GLOB distinguishes case */ + int noCase = 0; /* uppercase equivalent to lowercase */ int op; /* Top-level operator. pExpr->op */ Parse *pParse = pWInfo->pParse; /* Parsing context */ sqlite3 *db = pParse->db; /* Database connection */ @@ -116187,12 +117527,15 @@ static void exprAnalyze( /* Add constraints to reduce the search space on a LIKE or GLOB ** operator. ** - ** A like pattern of the form "x LIKE 'abc%'" is changed into constraints + ** A like pattern of the form "x LIKE 'aBc%'" is changed into constraints ** - ** x>='abc' AND x<'abd' AND x LIKE 'abc%' + ** x>='ABC' AND x<'abd' AND x LIKE 'aBc%' ** ** The last character of the prefix "abc" is incremented to form the - ** termination condition "abd". + ** termination condition "abd". If case is not significant (the default + ** for LIKE) then the lower-bound is made all uppercase and the upper- + ** bound is made all lowercase so that the bounds also work when comparing + ** BLOBs. */ if( pWC->op==TK_AND && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase) @@ -116203,10 +117546,26 @@ static void exprAnalyze( Expr *pNewExpr2; int idxNew1; int idxNew2; - Token sCollSeqName; /* Name of collating sequence */ + const char *zCollSeqName; /* Name of collating sequence */ + const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC; pLeft = pExpr->x.pList->a[1].pExpr; pStr2 = sqlite3ExprDup(db, pStr1, 0); + + /* Convert the lower bound to upper-case and the upper bound to + ** lower-case (upper-case is less than lower-case in ASCII) so that + ** the range constraints also work for BLOBs + */ + if( noCase && !pParse->db->mallocFailed ){ + int i; + char c; + pTerm->wtFlags |= TERM_LIKE; + for(i=0; (c = pStr1->u.zToken[i])!=0; i++){ + pStr1->u.zToken[i] = sqlite3Toupper(c); + pStr2->u.zToken[i] = sqlite3Tolower(c); + } + } + if( !db->mallocFailed ){ u8 c, *pC; /* Last character before the first wildcard */ pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1]; @@ -116223,22 +117582,21 @@ static void exprAnalyze( } *pC = c + 1; } - sCollSeqName.z = noCase ? "NOCASE" : "BINARY"; - sCollSeqName.n = 6; + zCollSeqName = noCase ? "NOCASE" : "BINARY"; pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); - pNewExpr1 = sqlite3PExpr(pParse, TK_GE, - sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName), + pNewExpr1 = sqlite3PExpr(pParse, TK_GE, + sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), pStr1, 0); transferJoinMarkings(pNewExpr1, pExpr); - idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC); + idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags); testcase( idxNew1==0 ); exprAnalyze(pSrc, pWC, idxNew1); pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); pNewExpr2 = sqlite3PExpr(pParse, TK_LT, - sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName), + sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName), pStr2, 0); transferJoinMarkings(pNewExpr2, pExpr); - idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC); + idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags); testcase( idxNew2==0 ); exprAnalyze(pSrc, pWC, idxNew2); pTerm = &pWC->a[idxTerm]; @@ -116356,7 +117714,7 @@ static int findIndexCol( && p->iTable==iBase ){ CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr); - if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){ + if( pColl && 0==sqlite3StrICmp(pColl->zName, zColl) ){ return i; } } @@ -116556,11 +117914,16 @@ static void constructAutomaticIndex( pLoop = pLevel->pWLoop; idxCols = 0; for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ + Expr *pExpr = pTerm->pExpr; + assert( !ExprHasProperty(pExpr, EP_FromJoin) /* prereq always non-zero */ + || pExpr->iRightJoinTable!=pSrc->iCursor /* for the right-hand */ + || pLoop->prereq!=0 ); /* table of a LEFT JOIN */ if( pLoop->prereq==0 && (pTerm->wtFlags & TERM_VIRTUAL)==0 - && sqlite3ExprIsTableConstant(pTerm->pExpr, pSrc->iCursor) ){ + && !ExprHasProperty(pExpr, EP_FromJoin) + && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){ pPartial = sqlite3ExprAnd(pParse->db, pPartial, - sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); + sqlite3ExprDup(pParse->db, pExpr, 0)); } if( termCanDriveIndex(pTerm, pSrc, notReady) ){ int iCol = pTerm->u.leftColumn; @@ -116625,7 +117988,7 @@ static void constructAutomaticIndex( idxCols |= cMask; pIdx->aiColumn[n] = pTerm->u.leftColumn; pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); - pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : "BINARY"; + pIdx->azColl[n] = pColl ? pColl->zName : "BINARY"; n++; } } @@ -116847,11 +118210,14 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ ** Estimate the location of a particular key among all keys in an ** index. Store the results in aStat as follows: ** -** aStat[0] Est. number of rows less than pVal -** aStat[1] Est. number of rows equal to pVal +** aStat[0] Est. number of rows less than pRec +** aStat[1] Est. number of rows equal to pRec ** ** Return the index of the sample that is the smallest sample that -** is greater than or equal to pRec. +** is greater than or equal to pRec. Note that this index is not an index +** into the aSample[] array - it is an index into a virtual set of samples +** based on the contents of aSample[] and the number of fields in record +** pRec. */ static int whereKeyStats( Parse *pParse, /* Database connection */ @@ -116862,67 +118228,158 @@ static int whereKeyStats( ){ IndexSample *aSample = pIdx->aSample; int iCol; /* Index of required stats in anEq[] etc. */ + int i; /* Index of first sample >= pRec */ + int iSample; /* Smallest sample larger than or equal to pRec */ int iMin = 0; /* Smallest sample not yet tested */ - int i = pIdx->nSample; /* Smallest sample larger than or equal to pRec */ int iTest; /* Next sample to test */ int res; /* Result of comparison operation */ + int nField; /* Number of fields in pRec */ + tRowcnt iLower = 0; /* anLt[] + anEq[] of largest sample pRec is > */ #ifndef SQLITE_DEBUG UNUSED_PARAMETER( pParse ); #endif assert( pRec!=0 ); - iCol = pRec->nField - 1; assert( pIdx->nSample>0 ); - assert( pRec->nField>0 && iCol<pIdx->nSampleCol ); + assert( pRec->nField>0 && pRec->nField<=pIdx->nSampleCol ); + + /* Do a binary search to find the first sample greater than or equal + ** to pRec. If pRec contains a single field, the set of samples to search + ** is simply the aSample[] array. If the samples in aSample[] contain more + ** than one fields, all fields following the first are ignored. + ** + ** If pRec contains N fields, where N is more than one, then as well as the + ** samples in aSample[] (truncated to N fields), the search also has to + ** consider prefixes of those samples. For example, if the set of samples + ** in aSample is: + ** + ** aSample[0] = (a, 5) + ** aSample[1] = (a, 10) + ** aSample[2] = (b, 5) + ** aSample[3] = (c, 100) + ** aSample[4] = (c, 105) + ** + ** Then the search space should ideally be the samples above and the + ** unique prefixes [a], [b] and [c]. But since that is hard to organize, + ** the code actually searches this set: + ** + ** 0: (a) + ** 1: (a, 5) + ** 2: (a, 10) + ** 3: (a, 10) + ** 4: (b) + ** 5: (b, 5) + ** 6: (c) + ** 7: (c, 100) + ** 8: (c, 105) + ** 9: (c, 105) + ** + ** For each sample in the aSample[] array, N samples are present in the + ** effective sample array. In the above, samples 0 and 1 are based on + ** sample aSample[0]. Samples 2 and 3 on aSample[1] etc. + ** + ** Often, sample i of each block of N effective samples has (i+1) fields. + ** Except, each sample may be extended to ensure that it is greater than or + ** equal to the previous sample in the array. For example, in the above, + ** sample 2 is the first sample of a block of N samples, so at first it + ** appears that it should be 1 field in size. However, that would make it + ** smaller than sample 1, so the binary search would not work. As a result, + ** it is extended to two fields. The duplicates that this creates do not + ** cause any problems. + */ + nField = pRec->nField; + iCol = 0; + iSample = pIdx->nSample * nField; do{ - iTest = (iMin+i)/2; - res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec); + int iSamp; /* Index in aSample[] of test sample */ + int n; /* Number of fields in test sample */ + + iTest = (iMin+iSample)/2; + iSamp = iTest / nField; + if( iSamp>0 ){ + /* The proposed effective sample is a prefix of sample aSample[iSamp]. + ** Specifically, the shortest prefix of at least (1 + iTest%nField) + ** fields that is greater than the previous effective sample. */ + for(n=(iTest % nField) + 1; n<nField; n++){ + if( aSample[iSamp-1].anLt[n-1]!=aSample[iSamp].anLt[n-1] ) break; + } + }else{ + n = iTest + 1; + } + + pRec->nField = n; + res = sqlite3VdbeRecordCompare(aSample[iSamp].n, aSample[iSamp].p, pRec); if( res<0 ){ + iLower = aSample[iSamp].anLt[n-1] + aSample[iSamp].anEq[n-1]; iMin = iTest+1; + }else if( res==0 && n<nField ){ + iLower = aSample[iSamp].anLt[n-1]; + iMin = iTest+1; + res = -1; }else{ - i = iTest; + iSample = iTest; + iCol = n-1; } - }while( res && iMin<i ); + }while( res && iMin<iSample ); + i = iSample / nField; #ifdef SQLITE_DEBUG /* The following assert statements check that the binary search code ** above found the right answer. This block serves no purpose other ** than to invoke the asserts. */ - if( res==0 ){ - /* If (res==0) is true, then sample $i must be equal to pRec */ - assert( i<pIdx->nSample ); - assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) - || pParse->db->mallocFailed ); - }else{ - /* Otherwise, pRec must be smaller than sample $i and larger than - ** sample ($i-1). */ - assert( i==pIdx->nSample - || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 - || pParse->db->mallocFailed ); - assert( i==0 - || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 - || pParse->db->mallocFailed ); + if( pParse->db->mallocFailed==0 ){ + if( res==0 ){ + /* If (res==0) is true, then pRec must be equal to sample i. */ + assert( i<pIdx->nSample ); + assert( iCol==nField-1 ); + pRec->nField = nField; + assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) + || pParse->db->mallocFailed + ); + }else{ + /* Unless i==pIdx->nSample, indicating that pRec is larger than + ** all samples in the aSample[] array, pRec must be smaller than the + ** (iCol+1) field prefix of sample i. */ + assert( i<=pIdx->nSample && i>=0 ); + pRec->nField = iCol+1; + assert( i==pIdx->nSample + || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 + || pParse->db->mallocFailed ); + + /* if i==0 and iCol==0, then record pRec is smaller than all samples + ** in the aSample[] array. Otherwise, if (iCol>0) then pRec must + ** be greater than or equal to the (iCol) field prefix of sample i. + ** If (i>0), then pRec must also be greater than sample (i-1). */ + if( iCol>0 ){ + pRec->nField = iCol; + assert( sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0 + || pParse->db->mallocFailed ); + } + if( i>0 ){ + pRec->nField = nField; + assert( sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 + || pParse->db->mallocFailed ); + } + } } #endif /* ifdef SQLITE_DEBUG */ - /* At this point, aSample[i] is the first sample that is greater than - ** or equal to pVal. Or if i==pIdx->nSample, then all samples are less - ** than pVal. If aSample[i]==pVal, then res==0. - */ if( res==0 ){ + /* Record pRec is equal to sample i */ + assert( iCol==nField-1 ); aStat[0] = aSample[i].anLt[iCol]; aStat[1] = aSample[i].anEq[iCol]; }else{ - tRowcnt iLower, iUpper, iGap; - if( i==0 ){ - iLower = 0; - iUpper = aSample[0].anLt[iCol]; + /* At this point, the (iCol+1) field prefix of aSample[i] is the first + ** sample that is greater than pRec. Or, if i==pIdx->nSample then pRec + ** is larger than all samples in the array. */ + tRowcnt iUpper, iGap; + if( i>=pIdx->nSample ){ + iUpper = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]); }else{ - i64 nRow0 = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]); - iUpper = i>=pIdx->nSample ? nRow0 : aSample[i].anLt[iCol]; - iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol]; + iUpper = aSample[i].anLt[iCol]; } - aStat[1] = pIdx->aAvgEq[iCol]; + if( iLower>=iUpper ){ iGap = 0; }else{ @@ -116934,7 +118391,11 @@ static int whereKeyStats( iGap = iGap/3; } aStat[0] = iLower + iGap; + aStat[1] = pIdx->aAvgEq[iCol]; } + + /* Restore the pRec->nField value before returning. */ + pRec->nField = nField; return i; } #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ @@ -117408,20 +118869,43 @@ static int whereInScanEst( ** but joins might run a little slower. The trick is to disable as much ** as we can without disabling too much. If we disabled in (1), we'd get ** the wrong answer. See ticket #813. +** +** If all the children of a term are disabled, then that term is also +** automatically disabled. In this way, terms get disabled if derived +** virtual terms are tested first. For example: +** +** x GLOB 'abc*' AND x>='abc' AND x<'acd' +** \___________/ \______/ \_____/ +** parent child1 child2 +** +** Only the parent term was in the original WHERE clause. The child1 +** and child2 terms were added by the LIKE optimization. If both of +** the virtual child terms are valid, then testing of the parent can be +** skipped. +** +** Usually the parent term is marked as TERM_CODED. But if the parent +** term was originally TERM_LIKE, then the parent gets TERM_LIKECOND instead. +** The TERM_LIKECOND marking indicates that the term should be coded inside +** a conditional such that is only evaluated on the second pass of a +** LIKE-optimization loop, when scanning BLOBs instead of strings. */ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ - if( pTerm + int nLoop = 0; + while( pTerm && (pTerm->wtFlags & TERM_CODED)==0 && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) && (pLevel->notReady & pTerm->prereqAll)==0 ){ - pTerm->wtFlags |= TERM_CODED; - if( pTerm->iParent>=0 ){ - WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent]; - if( (--pOther->nChild)==0 ){ - disableTerm(pLevel, pOther); - } + if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){ + pTerm->wtFlags |= TERM_LIKECOND; + }else{ + pTerm->wtFlags |= TERM_CODED; } + if( pTerm->iParent<0 ) break; + pTerm = &pTerm->pWC->a[pTerm->iParent]; + pTerm->nChild--; + if( pTerm->nChild!=0 ) break; + nLoop++; } } @@ -117800,8 +119284,7 @@ static int explainOneScan( || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); - sqlite3StrAccumInit(&str, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); - str.db = db; + sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN"); if( pItem->pSelect ){ sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId); @@ -117905,7 +119388,34 @@ static void addScanStatus( # define addScanStatus(a, b, c, d) ((void)d) #endif - +/* +** If the most recently coded instruction is a constant range contraint +** that originated from the LIKE optimization, then change the P3 to be +** pLoop->iLikeRepCntr and set P5. +** +** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range +** expression: "x>='ABC' AND x<'abd'". But this requires that the range +** scan loop run twice, once for strings and a second time for BLOBs. +** The OP_String opcodes on the second pass convert the upper and lower +** bound string contants to blobs. This routine makes the necessary changes +** to the OP_String opcodes for that to happen. +*/ +static void whereLikeOptimizationStringFixup( + Vdbe *v, /* prepared statement under construction */ + WhereLevel *pLevel, /* The loop that contains the LIKE operator */ + WhereTerm *pTerm /* The upper or lower bound just coded */ +){ + if( pTerm->wtFlags & TERM_LIKEOPT ){ + VdbeOp *pOp; + assert( pLevel->iLikeRepCntr>0 ); + pOp = sqlite3VdbeGetOp(v, -1); + assert( pOp!=0 ); + assert( pOp->opcode==OP_String8 + || pTerm->pWC->pWInfo->pParse->db->mallocFailed ); + pOp->p3 = pLevel->iLikeRepCntr; + pOp->p5 = 1; + } +} /* ** Generate code for the start of the iLevel-th loop in the WHERE clause @@ -118235,10 +119745,25 @@ static Bitmask codeOneLoopStart( if( pLoop->wsFlags & WHERE_BTM_LIMIT ){ pRangeStart = pLoop->aLTerm[j++]; nExtraReg = 1; + /* Like optimization range constraints always occur in pairs */ + assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 || + (pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 ); } if( pLoop->wsFlags & WHERE_TOP_LIMIT ){ pRangeEnd = pLoop->aLTerm[j++]; nExtraReg = 1; + if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){ + assert( pRangeStart!=0 ); /* LIKE opt constraints */ + assert( pRangeStart->wtFlags & TERM_LIKEOPT ); /* occur in pairs */ + pLevel->iLikeRepCntr = ++pParse->nMem; + testcase( bRev ); + testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC ); + sqlite3VdbeAddOp2(v, OP_Integer, + bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC), + pLevel->iLikeRepCntr); + VdbeComment((v, "LIKE loop counter")); + pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v); + } if( pRangeStart==0 && (j = pIdx->aiColumn[nEq])>=0 && pIdx->pTable->aCol[j].notNull==0 @@ -118281,6 +119806,7 @@ static Bitmask codeOneLoopStart( if( pRangeStart ){ Expr *pRight = pRangeStart->pExpr->pRight; sqlite3ExprCode(pParse, pRight, regBase+nEq); + whereLikeOptimizationStringFixup(v, pLevel, pRangeStart); if( (pRangeStart->wtFlags & TERM_VNULL)==0 && sqlite3ExprCanBeNull(pRight) ){ @@ -118326,6 +119852,7 @@ static Bitmask codeOneLoopStart( Expr *pRight = pRangeEnd->pExpr->pRight; sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); sqlite3ExprCode(pParse, pRight, regBase+nEq); + whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); if( (pRangeEnd->wtFlags & TERM_VNULL)==0 && sqlite3ExprCanBeNull(pRight) ){ @@ -118553,7 +120080,8 @@ static Bitmask codeOneLoopStart( */ wctrlFlags = WHERE_OMIT_OPEN_CLOSE | WHERE_FORCE_TABLE - | WHERE_ONETABLE_ONLY; + | WHERE_ONETABLE_ONLY + | WHERE_NO_AUTOINDEX; for(ii=0; ii<pOrWc->nTerm; ii++){ WhereTerm *pOrTerm = &pOrWc->a[ii]; if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ @@ -118715,6 +120243,7 @@ static Bitmask codeOneLoopStart( */ for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ Expr *pE; + int skipLikeAddr = 0; testcase( pTerm->wtFlags & TERM_VIRTUAL ); testcase( pTerm->wtFlags & TERM_CODED ); if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; @@ -118729,7 +120258,13 @@ static Bitmask codeOneLoopStart( if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){ continue; } + if( pTerm->wtFlags & TERM_LIKECOND ){ + assert( pLevel->iLikeRepCntr>0 ); + skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfNot, pLevel->iLikeRepCntr); + VdbeCoverage(v); + } sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); + if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr); pTerm->wtFlags |= TERM_CODED; } @@ -118948,6 +120483,13 @@ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ */ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ if( ALWAYS(pWInfo) ){ + int i; + for(i=0; i<pWInfo->nLevel; i++){ + WhereLevel *pLevel = &pWInfo->a[i]; + if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){ + sqlite3DbFree(db, pLevel->u.in.aInLoop); + } + } whereClauseClear(&pWInfo->sWC); while( pWInfo->pLoops ){ WhereLoop *p = pWInfo->pLoops; @@ -119394,6 +120936,10 @@ static int whereLoopAddBtreeIndex( } if( pTerm->prereqRight & pNew->maskSelf ) continue; + /* Do not allow the upper bound of a LIKE optimization range constraint + ** to mix with a lower range bound from some other source */ + if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; + pNew->wsFlags = saved_wsFlags; pNew->u.btree.nEq = saved_nEq; pNew->nLTerm = saved_nLTerm; @@ -119423,7 +120969,7 @@ static int whereLoopAddBtreeIndex( }else if( eOp & (WO_EQ) ){ pNew->wsFlags |= WHERE_COLUMN_EQ; if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){ - if( iCol>=0 && !IsUniqueIndex(pProbe) ){ + if( iCol>=0 && pProbe->uniqNotNull==0 ){ pNew->wsFlags |= WHERE_UNQ_WANTED; }else{ pNew->wsFlags |= WHERE_ONEROW; @@ -119437,6 +120983,17 @@ static int whereLoopAddBtreeIndex( pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; pBtm = pTerm; pTop = 0; + if( pTerm->wtFlags & TERM_LIKEOPT ){ + /* Range contraints that come from the LIKE optimization are + ** always used in pairs. */ + pTop = &pTerm[1]; + assert( (pTop-(pTerm->pWC->a))<pTerm->pWC->nTerm ); + assert( pTop->wtFlags & TERM_LIKEOPT ); + assert( pTop->eOperator==WO_LT ); + if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ + pNew->aLTerm[pNew->nLTerm++] = pTop; + pNew->wsFlags |= WHERE_TOP_LIMIT; + } }else{ assert( eOp & (WO_LT|WO_LE) ); testcase( eOp & WO_LT ); @@ -119638,7 +121195,12 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){ int i; WhereTerm *pTerm; for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ - if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab) ) return 1; + Expr *pExpr = pTerm->pExpr; + if( sqlite3ExprImpliesExpr(pExpr, pWhere, iTab) + && (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab) + ){ + return 1; + } } return 0; } @@ -119742,6 +121304,7 @@ static int whereLoopAddBtree( #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* Automatic indexes */ if( !pBuilder->pOrSet + && (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 && pSrc->pIndex==0 && !pSrc->viaCoroutine @@ -120625,10 +122188,10 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ /* Seed the search with a single WherePath containing zero WhereLoops. ** - ** TUNING: Do not let the number of iterations go above 25. If the cost - ** of computing an automatic index is not paid back within the first 25 + ** TUNING: Do not let the number of iterations go above 28. If the cost + ** of computing an automatic index is not paid back within the first 28 ** rows, then do not use the automatic index. */ - aFrom[0].nRow = MIN(pParse->nQueryLoop, 46); assert( 46==sqlite3LogEst(25) ); + aFrom[0].nRow = MIN(pParse->nQueryLoop, 48); assert( 48==sqlite3LogEst(28) ); nFrom = 1; assert( aFrom[0].isOrdered==0 ); if( nOrderBy ){ @@ -120866,7 +122429,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pWInfo->revMask = pFrom->revLoop; } if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP) - && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr + && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0 ){ Bitmask revMask = 0; int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, @@ -121271,7 +122834,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( } #ifdef WHERETRACE_ENABLED /* !=0 */ if( sqlite3WhereTrace ){ - int ii; sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut); if( pWInfo->nOBSat>0 ){ sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask); @@ -121426,6 +122988,12 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( op ){ sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIx); + if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0 + && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0 + && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 + ){ + sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */ + } VdbeComment((v, "%s", pIx->zName)); } } @@ -121518,7 +123086,6 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen); sqlite3VdbeJumpHere(v, pIn->addrInTop-1); } - sqlite3DbFree(db, pLevel->u.in.aInLoop); } sqlite3VdbeResolveLabel(v, pLevel->addrBrk); if( pLevel->addrSkip ){ @@ -121527,6 +123094,16 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeJumpHere(v, pLevel->addrSkip); sqlite3VdbeJumpHere(v, pLevel->addrSkip-2); } + if( pLevel->addrLikeRep ){ + int op; + if( sqlite3VdbeGetOp(v, pLevel->addrLikeRep-1)->p1 ){ + op = OP_DecrJumpZero; + }else{ + op = OP_JumpZeroIncr; + } + sqlite3VdbeAddOp2(v, op, pLevel->iLikeRepCntr, pLevel->addrLikeRep); + VdbeCoverage(v); + } if( pLevel->iLeftJoin ){ addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 @@ -121720,6 +123297,28 @@ struct TrigEvent { int a; IdList * b; }; struct AttachKey { int type; Token key; }; + /* + ** For a compound SELECT statement, make sure p->pPrior->pNext==p for + ** all elements in the list. And make sure list length does not exceed + ** SQLITE_LIMIT_COMPOUND_SELECT. + */ + static void parserDoubleLinkSelect(Parse *pParse, Select *p){ + if( p->pPrior ){ + Select *pNext = 0, *pLoop; + int mxSelect, cnt = 0; + for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){ + pLoop->pNext = pNext; + pLoop->selFlags |= SF_Compound; + } + if( (p->selFlags & SF_MultiValue)==0 && + (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && + cnt>mxSelect + ){ + sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); + } + } + } + /* This is a utility routine used to set the ExprSpan.zStart and ** ExprSpan.zEnd values of pOut so that the span covers the complete ** range of text beginning with pStart and going to the end of pEnd. @@ -124036,27 +125635,10 @@ static void yy_reduce( break; case 112: /* select ::= with selectnowith */ { - Select *p = yymsp[0].minor.yy3, *pNext, *pLoop; + Select *p = yymsp[0].minor.yy3; if( p ){ - int cnt = 0, mxSelect; p->pWith = yymsp[-1].minor.yy59; - if( p->pPrior ){ - u16 allValues = SF_Values; - pNext = 0; - for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){ - pLoop->pNext = pNext; - pLoop->selFlags |= SF_Compound; - allValues &= pLoop->selFlags; - } - if( allValues ){ - p->selFlags |= SF_AllValues; - }else if( - (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 - && cnt>mxSelect - ){ - sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); - } - } + parserDoubleLinkSelect(pParse, p); }else{ sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy59); } @@ -124074,12 +125656,14 @@ static void yy_reduce( SrcList *pFrom; Token x; x.n = 0; + parserDoubleLinkSelect(pParse, pRhs); pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0); pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0); } if( pRhs ){ pRhs->op = (u8)yymsp[-1].minor.yy328; pRhs->pPrior = yymsp[-2].minor.yy3; + pRhs->selFlags &= ~SF_MultiValue; if( yymsp[-1].minor.yy328!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy3); @@ -124126,13 +125710,16 @@ static void yy_reduce( break; case 121: /* values ::= values COMMA LP exprlist RP */ { - Select *pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0); + Select *pRight, *pLeft = yymsp[-4].minor.yy3; + pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values|SF_MultiValue,0,0); + if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; if( pRight ){ pRight->op = TK_ALL; - pRight->pPrior = yymsp[-4].minor.yy3; + pLeft = yymsp[-4].minor.yy3; + pRight->pPrior = pLeft; yygotominor.yy3 = pRight; }else{ - yygotominor.yy3 = yymsp[-4].minor.yy3; + yygotominor.yy3 = pLeft; } } break; @@ -124417,7 +126004,7 @@ static void yy_reduce( break; case 193: /* expr ::= expr COLLATE ID|STRING */ { - yygotominor.yy346.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy346.pExpr, &yymsp[0].minor.yy0); + yygotominor.yy346.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy346.pExpr, &yymsp[0].minor.yy0, 1); yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart; yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } @@ -124580,7 +126167,7 @@ static void yy_reduce( yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0); if( yygotominor.yy346.pExpr ){ yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy14; - sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); + sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr); }else{ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); } @@ -124595,8 +126182,8 @@ static void yy_reduce( yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); if( yygotominor.yy346.pExpr ){ yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3; - ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect); - sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); + ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery); + sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr); }else{ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3); } @@ -124609,8 +126196,8 @@ static void yy_reduce( yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0); if( yygotominor.yy346.pExpr ){ yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3; - ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect); - sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); + ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery); + sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr); }else{ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3); } @@ -124625,8 +126212,8 @@ static void yy_reduce( yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy346.pExpr, 0, 0); if( yygotominor.yy346.pExpr ){ yygotominor.yy346.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); - ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect); - sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); + ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery); + sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr); }else{ sqlite3SrcListDelete(pParse->db, pSrc); } @@ -124640,8 +126227,8 @@ static void yy_reduce( Expr *p = yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); if( p ){ p->x.pSelect = yymsp[-1].minor.yy3; - ExprSetProperty(p, EP_xIsSelect); - sqlite3ExprSetHeight(pParse, p); + ExprSetProperty(p, EP_xIsSelect|EP_Subquery); + sqlite3ExprSetHeightAndFlags(pParse, p); }else{ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3); } @@ -124654,7 +126241,7 @@ static void yy_reduce( yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy132, 0, 0); if( yygotominor.yy346.pExpr ){ yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy132 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy132) : yymsp[-2].minor.yy14; - sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); + sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr); }else{ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14); sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy132); @@ -124697,7 +126284,7 @@ static void yy_reduce( break; case 244: /* idxlist ::= idxlist COMMA nm collate sortorder */ { - Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0); + Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0, 1); yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, p); sqlite3ExprListSetName(pParse,yygotominor.yy14,&yymsp[-2].minor.yy0,1); sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index"); @@ -124706,7 +126293,7 @@ static void yy_reduce( break; case 245: /* idxlist ::= nm collate sortorder */ { - Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0); + Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0, 1); yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, p); sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1); sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index"); @@ -125896,10 +127483,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr sqlite3 *db = pParse->db; /* The database connection */ int mxSqlLen; /* Max length of an SQL string */ - -#ifdef SQLITE_ENABLE_API_ARMOR - if( zSql==0 || pzErrMsg==0 ) return SQLITE_MISUSE_BKPT; -#endif + assert( zSql!=0 ); mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; if( db->nVdbeActive==0 ){ db->u1.isInterrupted = 0; @@ -125939,10 +127523,8 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr break; } case TK_ILLEGAL: { - sqlite3DbFree(db, *pzErrMsg); - *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"", + sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &pParse->sLastToken); - nErr++; goto abort_parse; } case TK_SEMI: { @@ -125960,17 +127542,22 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr } } abort_parse: - if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){ + assert( nErr==0 ); + if( zSql[i]==0 && pParse->rc==SQLITE_OK && db->mallocFailed==0 ){ if( lastTokenParsed!=TK_SEMI ){ sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse); pParse->zTail = &zSql[i]; } - sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse); + if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){ + sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse); + } } #ifdef YYTRACKMAXSTACKDEPTH + sqlite3_mutex_enter(sqlite3MallocMutex()); sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK, sqlite3ParserStackPeak(pEngine) ); + sqlite3_mutex_leave(sqlite3MallocMutex()); #endif /* YYDEBUG */ sqlite3ParserFree(pEngine, sqlite3_free); db->lookaside.bEnabled = enableLookaside; @@ -126024,9 +127611,7 @@ abort_parse: pParse->pZombieTab = p->pNextZombie; sqlite3DeleteTable(db, p); } - if( nErr>0 && pParse->rc==SQLITE_OK ){ - pParse->rc = SQLITE_ERROR; - } + assert( nErr==0 || pParse->rc!=SQLITE_OK ); return nErr; } @@ -126134,7 +127719,7 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[]; ** to recognize the end of a trigger can be omitted. All we have to do ** is look for a semicolon that is not part of an string or comment. */ -SQLITE_API int sqlite3_complete(const char *zSql){ +SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *zSql){ u8 state = 0; /* Current state, using numbers defined in header comment */ u8 token; /* Value of the next token */ @@ -126299,10 +127884,10 @@ SQLITE_API int sqlite3_complete(const char *zSql){ ** above, except that the parameter is required to be UTF-16 encoded, not ** UTF-8. */ -SQLITE_API int sqlite3_complete16(const void *zSql){ +SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *zSql){ sqlite3_value *pVal; char const *zSql8; - int rc = SQLITE_NOMEM; + int rc; #ifndef SQLITE_OMIT_AUTOINIT rc = sqlite3_initialize(); @@ -126449,24 +128034,36 @@ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; /* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns ** a pointer to the to the sqlite3_version[] string constant. */ -SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; } +SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void){ return sqlite3_version; } /* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a ** pointer to a string constant whose value is the same as the ** SQLITE_SOURCE_ID C preprocessor macro. */ -SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } +SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } /* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function ** returns an integer equal to SQLITE_VERSION_NUMBER. */ -SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } +SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } /* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns ** zero if and only if SQLite was compiled with mutexing code omitted due to ** the SQLITE_THREADSAFE compile-time option being set to 0. */ -SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } +SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } + +/* +** When compiling the test fixture or with debugging enabled (on Win32), +** this variable being set to non-zero will cause OSTRACE macros to emit +** extra diagnostic information. +*/ +#ifdef SQLITE_HAVE_OS_TRACE +# ifndef SQLITE_DEBUG_OS_TRACE +# define SQLITE_DEBUG_OS_TRACE 0 +# endif + int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; +#endif #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE) /* @@ -126475,7 +128072,7 @@ SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } ** I/O active are written using this function. These messages ** are intended for debugging activity only. */ -/* not-private */ void (*sqlite3IoTrace)(const char*, ...) = 0; +SQLITE_API void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...) = 0; #endif /* @@ -126527,7 +128124,7 @@ SQLITE_API char *sqlite3_data_directory = 0; ** * Recursive calls to this routine from thread X return immediately ** without blocking. */ -SQLITE_API int sqlite3_initialize(void){ +SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void){ MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */ int rc; /* Result code */ #ifdef SQLITE_EXTRA_INIT @@ -126541,6 +128138,11 @@ SQLITE_API int sqlite3_initialize(void){ } #endif + /* If the following assert() fails on some obscure processor/compiler + ** combination, the work-around is to set the correct pointer + ** size at compile-time using -DSQLITE_PTRSIZE=n compile-time option */ + assert( SQLITE_PTRSIZE==sizeof(char*) ); + /* If SQLite is already completely initialized, then this call ** to sqlite3_initialize() should be a no-op. But the initialization ** must be complete. So isInit must not be set until the very end @@ -126683,7 +128285,7 @@ SQLITE_API int sqlite3_initialize(void){ ** on when SQLite is already shut down. If SQLite is already shut down ** when this routine is invoked, then this routine is a harmless no-op. */ -SQLITE_API int sqlite3_shutdown(void){ +SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void){ #ifdef SQLITE_OMIT_WSD int rc = sqlite3_wsd_init(4096, 24); if( rc!=SQLITE_OK ){ @@ -126737,7 +128339,7 @@ SQLITE_API int sqlite3_shutdown(void){ ** threadsafe. Failure to heed these warnings can lead to unpredictable ** behavior. */ -SQLITE_API int sqlite3_config(int op, ...){ +SQLITE_API int SQLITE_CDECL sqlite3_config(int op, ...){ va_list ap; int rc = SQLITE_OK; @@ -126753,26 +128355,28 @@ SQLITE_API int sqlite3_config(int op, ...){ */ #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-54466-46756 */ case SQLITE_CONFIG_SINGLETHREAD: { - /* Disable all mutexing */ - sqlite3GlobalConfig.bCoreMutex = 0; - sqlite3GlobalConfig.bFullMutex = 0; + /* EVIDENCE-OF: R-02748-19096 This option sets the threading mode to + ** Single-thread. */ + sqlite3GlobalConfig.bCoreMutex = 0; /* Disable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ break; } #endif #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-20520-54086 */ case SQLITE_CONFIG_MULTITHREAD: { - /* Disable mutexing of database connections */ - /* Enable mutexing of core data structures */ - sqlite3GlobalConfig.bCoreMutex = 1; - sqlite3GlobalConfig.bFullMutex = 0; + /* EVIDENCE-OF: R-14374-42468 This option sets the threading mode to + ** Multi-thread. */ + sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ break; } #endif #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-59593-21810 */ case SQLITE_CONFIG_SERIALIZED: { - /* Enable all mutexing */ - sqlite3GlobalConfig.bCoreMutex = 1; - sqlite3GlobalConfig.bFullMutex = 1; + /* EVIDENCE-OF: R-41220-51800 This option sets the threading mode to + ** Serialized. */ + sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 1; /* Enable mutex on connections */ break; } #endif @@ -126884,7 +128488,8 @@ SQLITE_API int sqlite3_config(int op, ...){ case SQLITE_CONFIG_HEAP: { /* EVIDENCE-OF: R-19854-42126 There are three arguments to ** SQLITE_CONFIG_HEAP: An 8-byte aligned pointer to the memory, the - ** number of bytes in the memory buffer, and the minimum allocation size. */ + ** number of bytes in the memory buffer, and the minimum allocation size. + */ sqlite3GlobalConfig.pHeap = va_arg(ap, void*); sqlite3GlobalConfig.nHeap = va_arg(ap, int); sqlite3GlobalConfig.mnReq = va_arg(ap, int); @@ -126989,7 +128594,9 @@ SQLITE_API int sqlite3_config(int op, ...){ ** compile-time maximum mmap size set by the SQLITE_MAX_MMAP_SIZE ** compile-time option. */ - if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ) mxMmap = SQLITE_MAX_MMAP_SIZE; + if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ){ + mxMmap = SQLITE_MAX_MMAP_SIZE; + } if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE; if( szMmap>mxMmap) szMmap = mxMmap; sqlite3GlobalConfig.mxMmap = mxMmap; @@ -127089,7 +128696,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ /* ** Return the mutex associated with a database connection. */ -SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){ +SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; @@ -127103,7 +128710,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){ ** Free up as much memory as we can from the given database ** connection. */ -SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){ +SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3 *db){ int i; #ifdef SQLITE_ENABLE_API_ARMOR @@ -127126,7 +128733,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){ /* ** Configuration settings for an individual database connection */ -SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ +SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3 *db, int op, ...){ va_list ap; int rc; va_start(ap, op); @@ -127245,7 +128852,7 @@ static int nocaseCollatingFunc( /* ** Return the ROWID of the most recent insert */ -SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){ +SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; @@ -127258,7 +128865,7 @@ SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){ /* ** Return the number of changes in the most recent call to sqlite3_exec(). */ -SQLITE_API int sqlite3_changes(sqlite3 *db){ +SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; @@ -127271,7 +128878,7 @@ SQLITE_API int sqlite3_changes(sqlite3 *db){ /* ** Return the number of changes since the database handle was opened. */ -SQLITE_API int sqlite3_total_changes(sqlite3 *db){ +SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; @@ -127413,8 +129020,8 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){ ** unclosed resources, and arranges for deallocation when the last ** prepare statement or sqlite3_backup closes. */ -SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); } -SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); } +SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); } +SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); } /* @@ -127597,7 +129204,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ ** Return a static string containing the name corresponding to the error code ** specified in the argument. */ -#if (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) || defined(SQLITE_TEST) +#if defined(SQLITE_NEED_ERR_NAME) SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ const char *zName = 0; int i, origRc = rc; @@ -127821,13 +129428,13 @@ SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){ ** This routine sets the busy callback for an Sqlite database to the ** given callback function with the given argument. */ -SQLITE_API int sqlite3_busy_handler( +SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler( sqlite3 *db, int (*xBusy)(void*,int), void *pArg ){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif sqlite3_mutex_enter(db->mutex); db->busyHandler.xFunc = xBusy; @@ -127844,7 +129451,7 @@ SQLITE_API int sqlite3_busy_handler( ** given callback function with the given argument. The progress callback will ** be invoked every nOps opcodes. */ -SQLITE_API void sqlite3_progress_handler( +SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler( sqlite3 *db, int nOps, int (*xProgress)(void*), @@ -127875,7 +129482,7 @@ SQLITE_API void sqlite3_progress_handler( ** This routine installs a default busy handler that waits for the ** specified number of milliseconds before returning 0. */ -SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ +SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3 *db, int ms){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif @@ -127891,7 +129498,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ /* ** Cause any pending operation to stop at its earliest opportunity. */ -SQLITE_API void sqlite3_interrupt(sqlite3 *db){ +SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; @@ -128008,7 +129615,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc( /* ** Create new user functions. */ -SQLITE_API int sqlite3_create_function( +SQLITE_API int SQLITE_STDCALL sqlite3_create_function( sqlite3 *db, const char *zFunc, int nArg, @@ -128022,7 +129629,7 @@ SQLITE_API int sqlite3_create_function( xFinal, 0); } -SQLITE_API int sqlite3_create_function_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2( sqlite3 *db, const char *zFunc, int nArg, @@ -128065,7 +129672,7 @@ SQLITE_API int sqlite3_create_function_v2( } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API int sqlite3_create_function16( +SQLITE_API int SQLITE_STDCALL sqlite3_create_function16( sqlite3 *db, const void *zFunctionName, int nArg, @@ -128105,7 +129712,7 @@ SQLITE_API int sqlite3_create_function16( ** A global function must exist in order for name resolution to work ** properly. */ -SQLITE_API int sqlite3_overload_function( +SQLITE_API int SQLITE_STDCALL sqlite3_overload_function( sqlite3 *db, const char *zName, int nArg @@ -128137,7 +129744,7 @@ SQLITE_API int sqlite3_overload_function( ** trace is a pointer to a function that is invoked at the start of each ** SQL statement. */ -SQLITE_API void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ +SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ void *pOld; #ifdef SQLITE_ENABLE_API_ARMOR @@ -128161,7 +129768,7 @@ SQLITE_API void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), v ** profile is a pointer to a function that is invoked at the conclusion of ** each SQL statement that is run. */ -SQLITE_API void *sqlite3_profile( +SQLITE_API void *SQLITE_STDCALL sqlite3_profile( sqlite3 *db, void (*xProfile)(void*,const char*,sqlite_uint64), void *pArg @@ -128188,7 +129795,7 @@ SQLITE_API void *sqlite3_profile( ** If the invoked function returns non-zero, then the commit becomes a ** rollback. */ -SQLITE_API void *sqlite3_commit_hook( +SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook( sqlite3 *db, /* Attach the hook to this database */ int (*xCallback)(void*), /* Function to invoke on each commit */ void *pArg /* Argument to the function */ @@ -128213,7 +129820,7 @@ SQLITE_API void *sqlite3_commit_hook( ** Register a callback to be invoked each time a row is updated, ** inserted or deleted using this database connection. */ -SQLITE_API void *sqlite3_update_hook( +SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook( sqlite3 *db, /* Attach the hook to this database */ void (*xCallback)(void*,int,char const *,char const *,sqlite_int64), void *pArg /* Argument to the function */ @@ -128238,7 +129845,7 @@ SQLITE_API void *sqlite3_update_hook( ** Register a callback to be invoked each time a transaction is rolled ** back by this database connection. */ -SQLITE_API void *sqlite3_rollback_hook( +SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook( sqlite3 *db, /* Attach the hook to this database */ void (*xCallback)(void*), /* Callback function */ void *pArg /* Argument to the function */ @@ -128292,7 +129899,7 @@ SQLITE_PRIVATE int sqlite3WalDefaultHook( ** using sqlite3_wal_hook() disables the automatic checkpoint mechanism ** configured by this function. */ -SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){ +SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){ #ifdef SQLITE_OMIT_WAL UNUSED_PARAMETER(db); UNUSED_PARAMETER(nFrame); @@ -128313,7 +129920,7 @@ SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){ ** Register a callback to be invoked each time a transaction is written ** into the write-ahead-log by this database connection. */ -SQLITE_API void *sqlite3_wal_hook( +SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook( sqlite3 *db, /* Attach the hook to this db handle */ int(*xCallback)(void *, sqlite3*, const char*, int), void *pArg /* First argument passed to xCallback() */ @@ -128340,7 +129947,7 @@ SQLITE_API void *sqlite3_wal_hook( /* ** Checkpoint database zDb. */ -SQLITE_API int sqlite3_wal_checkpoint_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2( sqlite3 *db, /* Database handle */ const char *zDb, /* Name of attached database (or NULL) */ int eMode, /* SQLITE_CHECKPOINT_* value */ @@ -128395,7 +130002,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( ** to contains a zero-length string, all attached databases are ** checkpointed. */ -SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ +SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ /* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to ** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */ return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0); @@ -128484,7 +130091,7 @@ SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){ ** Return UTF-8 encoded English language explanation of the most recent ** error. */ -SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){ +SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3 *db){ const char *z; if( !db ){ return sqlite3ErrStr(SQLITE_NOMEM); @@ -128512,7 +130119,7 @@ SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){ ** Return UTF-16 encoded English language explanation of the most recent ** error. */ -SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){ +SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3 *db){ static const u16 outOfMem[] = { 'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0 }; @@ -128557,7 +130164,7 @@ SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){ ** Return the most recent error code generated by an SQLite routine. If NULL is ** passed to this function, we assume a malloc() failed during sqlite3_open(). */ -SQLITE_API int sqlite3_errcode(sqlite3 *db){ +SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db){ if( db && !sqlite3SafetyCheckSickOrOk(db) ){ return SQLITE_MISUSE_BKPT; } @@ -128566,7 +130173,7 @@ SQLITE_API int sqlite3_errcode(sqlite3 *db){ } return db->errCode & db->errMask; } -SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){ +SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db){ if( db && !sqlite3SafetyCheckSickOrOk(db) ){ return SQLITE_MISUSE_BKPT; } @@ -128581,7 +130188,7 @@ SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){ ** argument. For now, this simply calls the internal sqlite3ErrStr() ** function. */ -SQLITE_API const char *sqlite3_errstr(int rc){ +SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int rc){ return sqlite3ErrStr(rc); } @@ -128729,7 +130336,7 @@ static const int aHardLimit[] = { ** It merely prevents new constructs that exceed the limit ** from forming. */ -SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ +SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ int oldLimit; #ifdef SQLITE_ENABLE_API_ARMOR @@ -128822,18 +130429,30 @@ SQLITE_PRIVATE int sqlite3ParseUri( int eState; /* Parser state when parsing URI */ int iIn; /* Input character index */ int iOut = 0; /* Output character index */ - int nByte = nUri+2; /* Bytes of space to allocate */ + u64 nByte = nUri+2; /* Bytes of space to allocate */ /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen ** method that there may be extra parameters following the file-name. */ flags |= SQLITE_OPEN_URI; for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&'); - zFile = sqlite3_malloc(nByte); + zFile = sqlite3_malloc64(nByte); if( !zFile ) return SQLITE_NOMEM; iIn = 5; -#ifndef SQLITE_ALLOW_URI_AUTHORITY +#ifdef SQLITE_ALLOW_URI_AUTHORITY + if( strncmp(zUri+5, "///", 3)==0 ){ + iIn = 7; + /* The following condition causes URIs with five leading / characters + ** like file://///host/path to be converted into UNCs like //host/path. + ** The correct URI for that UNC has only two or four leading / characters + ** file://host/path or file:////host/path. But 5 leading slashes is a + ** common error, we are told, so we handle it as a special case. */ + if( strncmp(zUri+7, "///", 3)==0 ){ iIn++; } + }else if( strncmp(zUri+5, "//localhost/", 12)==0 ){ + iIn = 16; + } +#else /* Discard the scheme and authority segments of the URI. */ if( zUri[5]=='/' && zUri[6]=='/' ){ iIn = 7; @@ -128983,7 +130602,7 @@ SQLITE_PRIVATE int sqlite3ParseUri( } }else{ - zFile = sqlite3_malloc(nUri+2); + zFile = sqlite3_malloc64(nUri+2); if( !zFile ) return SQLITE_NOMEM; memcpy(zFile, zUri, nUri); zFile[nUri] = '\0'; @@ -129120,6 +130739,9 @@ static int openDatabase( #if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX | SQLITE_AutoIndex #endif +#if SQLITE_DEFAULT_CKPTFULLFSYNC + | SQLITE_CkptFullFSync +#endif #if SQLITE_DEFAULT_FILE_FORMAT<4 | SQLITE_LegacyFileFmt #endif @@ -129252,6 +130874,13 @@ static int openDatabase( } #endif +#ifdef SQLITE_ENABLE_DBSTAT_VTAB + if( !db->mallocFailed && rc==SQLITE_OK){ + int sqlite3_dbstat_register(sqlite3*); + rc = sqlite3_dbstat_register(db); + } +#endif + /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking ** mode. Doing nothing at all also makes NORMAL the default. @@ -129273,7 +130902,8 @@ static int openDatabase( opendb_out: sqlite3_free(zOpen); if( db ){ - assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 ); + assert( db->mutex!=0 || isThreadsafe==0 + || sqlite3GlobalConfig.bFullMutex==0 ); sqlite3_mutex_leave(db->mutex); } rc = sqlite3_errcode(db); @@ -129298,14 +130928,14 @@ opendb_out: /* ** Open a new database handle. */ -SQLITE_API int sqlite3_open( +SQLITE_API int SQLITE_STDCALL sqlite3_open( const char *zFilename, sqlite3 **ppDb ){ return openDatabase(zFilename, ppDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); } -SQLITE_API int sqlite3_open_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_open_v2( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb, /* OUT: SQLite db handle */ int flags, /* Flags */ @@ -129318,7 +130948,7 @@ SQLITE_API int sqlite3_open_v2( /* ** Open a new database handle. */ -SQLITE_API int sqlite3_open16( +SQLITE_API int SQLITE_STDCALL sqlite3_open16( const void *zFilename, sqlite3 **ppDb ){ @@ -129357,7 +130987,7 @@ SQLITE_API int sqlite3_open16( /* ** Register a new collation sequence with the database handle db. */ -SQLITE_API int sqlite3_create_collation( +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation( sqlite3* db, const char *zName, int enc, @@ -129370,7 +131000,7 @@ SQLITE_API int sqlite3_create_collation( /* ** Register a new collation sequence with the database handle db. */ -SQLITE_API int sqlite3_create_collation_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2( sqlite3* db, const char *zName, int enc, @@ -129395,7 +131025,7 @@ SQLITE_API int sqlite3_create_collation_v2( /* ** Register a new collation sequence with the database handle db. */ -SQLITE_API int sqlite3_create_collation16( +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16( sqlite3* db, const void *zName, int enc, @@ -129425,7 +131055,7 @@ SQLITE_API int sqlite3_create_collation16( ** Register a collation sequence factory callback with the database handle ** db. Replace any previously installed collation sequence factory. */ -SQLITE_API int sqlite3_collation_needed( +SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed( sqlite3 *db, void *pCollNeededArg, void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*) @@ -129446,7 +131076,7 @@ SQLITE_API int sqlite3_collation_needed( ** Register a collation sequence factory callback with the database handle ** db. Replace any previously installed collation sequence factory. */ -SQLITE_API int sqlite3_collation_needed16( +SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16( sqlite3 *db, void *pCollNeededArg, void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*) @@ -129468,7 +131098,7 @@ SQLITE_API int sqlite3_collation_needed16( ** This function is now an anachronism. It used to be used to recover from a ** malloc() failure, but SQLite now does this automatically. */ -SQLITE_API int sqlite3_global_recover(void){ +SQLITE_API int SQLITE_STDCALL sqlite3_global_recover(void){ return SQLITE_OK; } #endif @@ -129479,7 +131109,7 @@ SQLITE_API int sqlite3_global_recover(void){ ** by default. Autocommit is disabled by a BEGIN statement and reenabled ** by the next COMMIT or ROLLBACK. */ -SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){ +SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; @@ -129531,7 +131161,7 @@ SQLITE_PRIVATE int sqlite3CantopenError(int lineno){ ** SQLite no longer uses thread-specific data so this routine is now a ** no-op. It is retained for historical compatibility. */ -SQLITE_API void sqlite3_thread_cleanup(void){ +SQLITE_API void SQLITE_STDCALL sqlite3_thread_cleanup(void){ } #endif @@ -129539,7 +131169,7 @@ SQLITE_API void sqlite3_thread_cleanup(void){ ** Return meta information about a specific column of a database table. ** See comment in sqlite3.h (sqlite.h.in) for details. */ -SQLITE_API int sqlite3_table_column_metadata( +SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata( sqlite3 *db, /* Connection handle */ const char *zDbName, /* Database name or NULL */ const char *zTableName, /* Table name */ @@ -129555,13 +131185,19 @@ SQLITE_API int sqlite3_table_column_metadata( Table *pTab = 0; Column *pCol = 0; int iCol = 0; - char const *zDataType = 0; char const *zCollSeq = 0; int notnull = 0; int primarykey = 0; int autoinc = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zTableName==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + /* Ensure the database schema has been loaded */ sqlite3_mutex_enter(db->mutex); sqlite3BtreeEnterAll(db); @@ -129651,7 +131287,7 @@ error_out: /* ** Sleep for a little while. Return the amount of time slept. */ -SQLITE_API int sqlite3_sleep(int ms){ +SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int ms){ sqlite3_vfs *pVfs; int rc; pVfs = sqlite3_vfs_find(0); @@ -129667,7 +131303,7 @@ SQLITE_API int sqlite3_sleep(int ms){ /* ** Enable or disable the extended result codes. */ -SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){ +SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3 *db, int onoff){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif @@ -129680,7 +131316,7 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){ /* ** Invoke the xFileControl method on a particular database. */ -SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ +SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ int rc = SQLITE_ERROR; Btree *pBtree; @@ -129708,13 +131344,13 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo sqlite3BtreeLeave(pBtree); } sqlite3_mutex_leave(db->mutex); - return rc; + return rc; } /* ** Interface to the testing logic. */ -SQLITE_API int sqlite3_test_control(int op, ...){ +SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...){ int rc = 0; #ifndef SQLITE_OMIT_BUILTIN_TEST va_list ap; @@ -130011,6 +131647,35 @@ SQLITE_API int sqlite3_test_control(int op, ...){ if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; break; } + + /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, onOff, tnum); + ** + ** This test control is used to create imposter tables. "db" is a pointer + ** to the database connection. dbName is the database name (ex: "main" or + ** "temp") which will receive the imposter. "onOff" turns imposter mode on + ** or off. "tnum" is the root page of the b-tree to which the imposter + ** table should connect. + ** + ** Enable imposter mode only when the schema has already been parsed. Then + ** run a single CREATE TABLE statement to construct the imposter table in + ** the parsed schema. Then turn imposter mode back off again. + ** + ** If onOff==0 and tnum>0 then reset the schema for all databases, causing + ** the schema to be reparsed the next time it is needed. This has the + ** effect of erasing all imposter tables. + */ + case SQLITE_TESTCTRL_IMPOSTER: { + sqlite3 *db = va_arg(ap, sqlite3*); + sqlite3_mutex_enter(db->mutex); + db->init.iDb = sqlite3FindDbName(db, va_arg(ap,const char*)); + db->init.busy = db->init.imposterTable = va_arg(ap,int); + db->init.newTnum = va_arg(ap,int); + if( db->init.busy==0 && db->init.newTnum>0 ){ + sqlite3ResetAllSchemasOfConnection(db); + } + sqlite3_mutex_leave(db->mutex); + break; + } } va_end(ap); #endif /* SQLITE_OMIT_BUILTIN_TEST */ @@ -130028,7 +131693,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){ ** parameter if it exists. If the parameter does not exist, this routine ** returns a NULL pointer. */ -SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ +SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam){ if( zFilename==0 || zParam==0 ) return 0; zFilename += sqlite3Strlen30(zFilename) + 1; while( zFilename[0] ){ @@ -130043,7 +131708,7 @@ SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char * /* ** Return a boolean value for a query parameter. */ -SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){ +SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){ const char *z = sqlite3_uri_parameter(zFilename, zParam); bDflt = bDflt!=0; return z ? sqlite3GetBoolean(z, bDflt) : bDflt; @@ -130052,7 +131717,7 @@ SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, in /* ** Return a 64-bit integer value for a query parameter. */ -SQLITE_API sqlite3_int64 sqlite3_uri_int64( +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64( const char *zFilename, /* Filename as passed to xOpen */ const char *zParam, /* URI parameter sought */ sqlite3_int64 bDflt /* return if parameter is missing */ @@ -130084,7 +131749,7 @@ SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){ ** Return the filename of the database associated with a database ** connection. */ -SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){ +SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName){ Btree *pBt; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ @@ -130100,7 +131765,7 @@ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){ ** Return 1 if database is read-only or 0 if read/write. Return -1 if ** no such database exists. */ -SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){ +SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName){ Btree *pBt; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ @@ -130259,7 +131924,7 @@ static void leaveMutex(void){ ** on the same "db". If xNotify==0 then any prior callbacks are immediately ** cancelled. */ -SQLITE_API int sqlite3_unlock_notify( +SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify( sqlite3 *db, void (*xNotify)(void **, int), void *pArg @@ -131153,6 +132818,11 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi #ifdef SQLITE_COVERAGE_TEST # define ALWAYS(x) (1) # define NEVER(X) (0) +#elif defined(SQLITE_DEBUG) +# define ALWAYS(x) sqlite3Fts3Always((x)!=0) +# define NEVER(x) sqlite3Fts3Never((x)!=0) +SQLITE_PRIVATE int sqlite3Fts3Always(int b); +SQLITE_PRIVATE int sqlite3Fts3Never(int b); #else # define ALWAYS(x) (x) # define NEVER(x) (x) @@ -131394,6 +133064,11 @@ struct Fts3Phrase { int bIncr; /* True if doclist is loaded incrementally */ int iDoclistToken; + /* Used by sqlite3Fts3EvalPhrasePoslist() if this is a descendent of an + ** OR condition. */ + char *pOrPoslist; + i64 iOrDocid; + /* Variables below this point are populated by fts3_expr.c when parsing ** a MATCH expression. Everything above is part of the evaluation phase. */ @@ -131548,6 +133223,7 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int); ) /* fts3.c */ +SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char**,const char*,...); SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *); @@ -131637,6 +133313,13 @@ static int fts3EvalStart(Fts3Cursor *pCsr); static int fts3TermSegReaderCursor( Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **); +#ifndef SQLITE_AMALGAMATION +# if defined(SQLITE_DEBUG) +SQLITE_PRIVATE int sqlite3Fts3Always(int b) { assert( b ); return b; } +SQLITE_PRIVATE int sqlite3Fts3Never(int b) { assert( !b ); return b; } +# endif +#endif + /* ** Write a 64-bit variable-length integer to memory starting at p[0]. ** The length of data written will be between 1 and FTS3_VARINT_MAX bytes. @@ -131746,7 +133429,7 @@ SQLITE_PRIVATE void sqlite3Fts3Dequote(char *z){ /* If the first byte was a '[', then the close-quote character is a ']' */ if( quote=='[' ) quote = ']'; - while( ALWAYS(z[iIn]) ){ + while( z[iIn] ){ if( z[iIn]==quote ){ if( z[iIn+1]!=quote ) break; z[iOut++] = quote; @@ -131825,6 +133508,17 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){ return SQLITE_OK; } +/* +** Write an error message into *pzErr +*/ +SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char **pzErr, const char *zFormat, ...){ + va_list ap; + sqlite3_free(*pzErr); + va_start(ap, zFormat); + *pzErr = sqlite3_vmprintf(zFormat, ap); + va_end(ap); +} + /* ** Construct one or more SQL statements from the format string given ** and then evaluate those statements. The success code is written @@ -132234,11 +133928,16 @@ static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){ ** This function is used when parsing the "prefix=" FTS4 parameter. */ static int fts3GobbleInt(const char **pp, int *pnOut){ + const int MAX_NPREFIX = 10000000; const char *p; /* Iterator pointer */ int nInt = 0; /* Output value */ for(p=*pp; p[0]>='0' && p[0]<='9'; p++){ nInt = nInt * 10 + (p[0] - '0'); + if( nInt>MAX_NPREFIX ){ + nInt = 0; + break; + } } if( p==*pp ) return SQLITE_ERROR; *pnOut = nInt; @@ -132281,7 +133980,6 @@ static int fts3PrefixParameter( aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex); *apIndex = aIndex; - *pnIndex = nIndex; if( !aIndex ){ return SQLITE_NOMEM; } @@ -132291,13 +133989,20 @@ static int fts3PrefixParameter( const char *p = zParam; int i; for(i=1; i<nIndex; i++){ - int nPrefix; + int nPrefix = 0; if( fts3GobbleInt(&p, &nPrefix) ) return SQLITE_ERROR; - aIndex[i].nPrefix = nPrefix; + assert( nPrefix>=0 ); + if( nPrefix==0 ){ + nIndex--; + i--; + }else{ + aIndex[i].nPrefix = nPrefix; + } p++; } } + *pnIndex = nIndex; return SQLITE_OK; } @@ -132332,7 +134037,8 @@ static int fts3ContentColumns( const char *zTbl, /* Name of content table */ const char ***pazCol, /* OUT: Malloc'd array of column names */ int *pnCol, /* OUT: Size of array *pazCol */ - int *pnStr /* OUT: Bytes of string content */ + int *pnStr, /* OUT: Bytes of string content */ + char **pzErr /* OUT: error message */ ){ int rc = SQLITE_OK; /* Return code */ char *zSql; /* "SELECT *" statement on zTbl */ @@ -132343,6 +134049,9 @@ static int fts3ContentColumns( rc = SQLITE_NOMEM; }else{ rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ){ + sqlite3Fts3ErrMsg(pzErr, "%s", sqlite3_errmsg(db)); + } } sqlite3_free(zSql); @@ -132421,7 +134130,7 @@ static int fts3InitVtab( const char **aCol; /* Array of column names */ sqlite3_tokenizer *pTokenizer = 0; /* Tokenizer for this table */ - int nIndex; /* Size of aIndex[] array */ + int nIndex = 0; /* Size of aIndex[] array */ struct Fts3Index *aIndex = 0; /* Array of indexes for this table */ /* The results of parsing supported FTS4 key=value options: */ @@ -132509,13 +134218,13 @@ static int fts3InitVtab( } } if( iOpt==SizeofArray(aFts4Opt) ){ - *pzErr = sqlite3_mprintf("unrecognized parameter: %s", z); + sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z); rc = SQLITE_ERROR; }else{ switch( iOpt ){ case 0: /* MATCHINFO */ if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){ - *pzErr = sqlite3_mprintf("unrecognized matchinfo: %s", zVal); + sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal); rc = SQLITE_ERROR; } bNoDocsize = 1; @@ -132543,7 +134252,7 @@ static int fts3InitVtab( if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3)) && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4)) ){ - *pzErr = sqlite3_mprintf("unrecognized order: %s", zVal); + sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal); rc = SQLITE_ERROR; } bDescIdx = (zVal[0]=='d' || zVal[0]=='D'); @@ -132594,7 +134303,7 @@ static int fts3InitVtab( if( nCol==0 ){ sqlite3_free((void*)aCol); aCol = 0; - rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString); + rc = fts3ContentColumns(db, argv[1], zContent,&aCol,&nCol,&nString,pzErr); /* If a languageid= option was specified, remove the language id ** column from the aCol[] array. */ @@ -132629,7 +134338,7 @@ static int fts3InitVtab( rc = fts3PrefixParameter(zPrefix, &nIndex, &aIndex); if( rc==SQLITE_ERROR ){ assert( zPrefix ); - *pzErr = sqlite3_mprintf("error parsing prefix parameter: %s", zPrefix); + sqlite3Fts3ErrMsg(pzErr, "error parsing prefix parameter: %s", zPrefix); } if( rc!=SQLITE_OK ) goto fts3_init_out; @@ -132711,7 +134420,7 @@ static int fts3InitVtab( } for(i=0; i<nNotindexed; i++){ if( azNotindexed[i] ){ - *pzErr = sqlite3_mprintf("no such column: %s", azNotindexed[i]); + sqlite3Fts3ErrMsg(pzErr, "no such column: %s", azNotindexed[i]); rc = SQLITE_ERROR; } } @@ -132719,7 +134428,7 @@ static int fts3InitVtab( if( rc==SQLITE_OK && (zCompress==0)!=(zUncompress==0) ){ char const *zMiss = (zCompress==0 ? "compress" : "uncompress"); rc = SQLITE_ERROR; - *pzErr = sqlite3_mprintf("missing %s parameter in fts4 constructor", zMiss); + sqlite3Fts3ErrMsg(pzErr, "missing %s parameter in fts4 constructor", zMiss); } p->zReadExprlist = fts3ReadExprList(p, zUncompress, &rc); p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc); @@ -133815,26 +135524,33 @@ static int fts3DoclistOrMerge( ** ** The right-hand input doclist is overwritten by this function. */ -static void fts3DoclistPhraseMerge( +static int fts3DoclistPhraseMerge( int bDescDoclist, /* True if arguments are desc */ int nDist, /* Distance from left to right (1=adjacent) */ char *aLeft, int nLeft, /* Left doclist */ - char *aRight, int *pnRight /* IN/OUT: Right/output doclist */ + char **paRight, int *pnRight /* IN/OUT: Right/output doclist */ ){ sqlite3_int64 i1 = 0; sqlite3_int64 i2 = 0; sqlite3_int64 iPrev = 0; + char *aRight = *paRight; char *pEnd1 = &aLeft[nLeft]; char *pEnd2 = &aRight[*pnRight]; char *p1 = aLeft; char *p2 = aRight; char *p; int bFirstOut = 0; - char *aOut = aRight; + char *aOut; assert( nDist>0 ); - + if( bDescDoclist ){ + aOut = sqlite3_malloc(*pnRight + FTS3_VARINT_MAX); + if( aOut==0 ) return SQLITE_NOMEM; + }else{ + aOut = aRight; + } p = aOut; + fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); @@ -133863,6 +135579,12 @@ static void fts3DoclistPhraseMerge( } *pnRight = (int)(p - aOut); + if( bDescDoclist ){ + sqlite3_free(aRight); + *paRight = aOut; + } + + return SQLITE_OK; } /* @@ -133987,8 +135709,22 @@ static int fts3TermSelectMerge( ){ if( pTS->aaOutput[0]==0 ){ /* If this is the first term selected, copy the doclist to the output - ** buffer using memcpy(). */ - pTS->aaOutput[0] = sqlite3_malloc(nDoclist); + ** buffer using memcpy(). + ** + ** Add FTS3_VARINT_MAX bytes of unused space to the end of the + ** allocation. This is so as to ensure that the buffer is big enough + ** to hold the current doclist AND'd with any other doclist. If the + ** doclists are stored in order=ASC order, this padding would not be + ** required (since the size of [doclistA AND doclistB] is always less + ** than or equal to the size of [doclistA] in that case). But this is + ** not true for order=DESC. For example, a doclist containing (1, -1) + ** may be smaller than (-1), as in the first example the -1 may be stored + ** as a single-byte delta, whereas in the second it must be stored as a + ** FTS3_VARINT_MAX byte varint. + ** + ** Similar padding is added in the fts3DoclistOrMerge() function. + */ + pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1); pTS->anOutput[0] = nDoclist; if( pTS->aaOutput[0] ){ memcpy(pTS->aaOutput[0], aDoclist, nDoclist); @@ -134085,7 +135821,7 @@ static int fts3SegReaderCursor( ** calls out here. */ if( iLevel<0 && p->aIndex ){ Fts3SegReader *pSeg = 0; - rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix, &pSeg); + rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg); if( rc==SQLITE_OK && pSeg ){ rc = fts3SegReaderCursorAppend(pCsr, pSeg); } @@ -134488,10 +136224,17 @@ static int fts3FilterMethod( ** row by docid. */ if( eSearch==FTS3_FULLSCAN_SEARCH ){ - zSql = sqlite3_mprintf( - "SELECT %s ORDER BY rowid %s", - p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC") - ); + if( pDocidGe || pDocidLe ){ + zSql = sqlite3_mprintf( + "SELECT %s WHERE rowid BETWEEN %lld AND %lld ORDER BY rowid %s", + p->zReadExprlist, pCsr->iMinDocid, pCsr->iMaxDocid, + (pCsr->bDesc ? "DESC" : "ASC") + ); + }else{ + zSql = sqlite3_mprintf("SELECT %s ORDER BY rowid %s", + p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC") + ); + } if( zSql ){ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0); sqlite3_free(zSql); @@ -134727,11 +136470,31 @@ static void fts3ReversePoslist(char *pStart, char **ppPoslist){ char *p = &(*ppPoslist)[-2]; char c = 0; + /* Skip backwards passed any trailing 0x00 bytes added by NearTrim() */ while( p>pStart && (c=*p--)==0 ); + + /* Search backwards for a varint with value zero (the end of the previous + ** poslist). This is an 0x00 byte preceded by some byte that does not + ** have the 0x80 bit set. */ while( p>pStart && (*p & 0x80) | c ){ c = *p--; } - if( p>pStart ){ p = &p[2]; } + assert( p==pStart || c==0 ); + + /* At this point p points to that preceding byte without the 0x80 bit + ** set. So to find the start of the poslist, skip forward 2 bytes then + ** over a varint. + ** + ** Normally. The other case is that p==pStart and the poslist to return + ** is the first in the doclist. In this case do not skip forward 2 bytes. + ** The second part of the if condition (c==0 && *ppPoslist>&p[2]) + ** is required for cases where the first byte of a doclist and the + ** doclist is empty. For example, if the first docid is 10, a doclist + ** that begins with: + ** + ** 0x0A 0x00 <next docid delta varint> + */ + if( p>pStart || (c==0 && *ppPoslist>&p[2]) ){ p = &p[2]; } while( *p++&0x80 ); *ppPoslist = p; } @@ -134802,6 +136565,8 @@ static void fts3SnippetFunc( } if( !zEllipsis || !zEnd || !zStart ){ sqlite3_result_error_nomem(pContext); + }else if( nToken==0 ){ + sqlite3_result_text(pContext, "", -1, SQLITE_STATIC); }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken); } @@ -135237,14 +137002,17 @@ static void fts3EvalAllocateReaders( ** This function assumes that pList points to a buffer allocated using ** sqlite3_malloc(). This function takes responsibility for eventually ** freeing the buffer. +** +** SQLITE_OK is returned if successful, or SQLITE_NOMEM if an error occurs. */ -static void fts3EvalPhraseMergeToken( +static int fts3EvalPhraseMergeToken( Fts3Table *pTab, /* FTS Table pointer */ Fts3Phrase *p, /* Phrase to merge pList/nList into */ int iToken, /* Token pList/nList corresponds to */ char *pList, /* Pointer to doclist */ int nList /* Number of bytes in pList */ ){ + int rc = SQLITE_OK; assert( iToken!=p->iDoclistToken ); if( pList==0 ){ @@ -135283,13 +137051,16 @@ static void fts3EvalPhraseMergeToken( nDiff = p->iDoclistToken - iToken; } - fts3DoclistPhraseMerge(pTab->bDescIdx, nDiff, pLeft, nLeft, pRight,&nRight); + rc = fts3DoclistPhraseMerge( + pTab->bDescIdx, nDiff, pLeft, nLeft, &pRight, &nRight + ); sqlite3_free(pLeft); p->doclist.aAll = pRight; p->doclist.nAll = nRight; } if( iToken>p->iDoclistToken ) p->iDoclistToken = iToken; + return rc; } /* @@ -135315,7 +137086,7 @@ static int fts3EvalPhraseLoad( char *pThis = 0; rc = fts3TermSelect(pTab, pToken, p->iColumn, &nThis, &pThis); if( rc==SQLITE_OK ){ - fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis); + rc = fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis); } } assert( pToken->pSegcsr==0 ); @@ -135857,12 +137628,14 @@ static void fts3EvalStartReaders( ){ if( pExpr && SQLITE_OK==*pRc ){ if( pExpr->eType==FTSQUERY_PHRASE ){ - int i; int nToken = pExpr->pPhrase->nToken; - for(i=0; i<nToken; i++){ - if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break; + if( nToken ){ + int i; + for(i=0; i<nToken; i++){ + if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break; + } + pExpr->bDeferred = (i==nToken); } - pExpr->bDeferred = (i==nToken); *pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase); }else{ fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc); @@ -136117,9 +137890,13 @@ static int fts3EvalSelectDeferred( char *pList = 0; rc = fts3TermSelect(pTab, pToken, pTC->iCol, &nList, &pList); assert( rc==SQLITE_OK || pList==0 ); + if( rc==SQLITE_OK ){ + rc = fts3EvalPhraseMergeToken( + pTab, pTC->pPhrase, pTC->iToken,pList,nList + ); + } if( rc==SQLITE_OK ){ int nCount; - fts3EvalPhraseMergeToken(pTab, pTC->pPhrase, pTC->iToken,pList,nList); nCount = fts3DoclistCountDocids( pTC->pPhrase->doclist.aAll, pTC->pPhrase->doclist.nAll ); @@ -136344,6 +138121,22 @@ static void fts3EvalNextRow( } pExpr->iDocid = pLeft->iDocid; pExpr->bEof = (pLeft->bEof || pRight->bEof); + if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){ + if( pRight->pPhrase && pRight->pPhrase->doclist.aAll ){ + Fts3Doclist *pDl = &pRight->pPhrase->doclist; + while( *pRc==SQLITE_OK && pRight->bEof==0 ){ + memset(pDl->pList, 0, pDl->nList); + fts3EvalNextRow(pCsr, pRight, pRc); + } + } + if( pLeft->pPhrase && pLeft->pPhrase->doclist.aAll ){ + Fts3Doclist *pDl = &pLeft->pPhrase->doclist; + while( *pRc==SQLITE_OK && pLeft->bEof==0 ){ + memset(pDl->pList, 0, pDl->nList); + fts3EvalNextRow(pCsr, pLeft, pRc); + } + } + } } break; } @@ -136716,6 +138509,7 @@ static void fts3EvalRestart( } pPhrase->doclist.pNextDocid = 0; pPhrase->doclist.iDocid = 0; + pPhrase->pOrPoslist = 0; } pExpr->iDocid = 0; @@ -136961,8 +138755,8 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist( iDocid = pExpr->iDocid; pIter = pPhrase->doclist.pList; if( iDocid!=pCsr->iPrevId || pExpr->bEof ){ + int rc = SQLITE_OK; int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */ - int iMul; /* +1 if csr dir matches index dir, else -1 */ int bOr = 0; u8 bEof = 0; u8 bTreeEof = 0; @@ -136986,72 +138780,44 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist( ** an incremental phrase. Load the entire doclist for the phrase ** into memory in this case. */ if( pPhrase->bIncr ){ - int rc = SQLITE_OK; - int bEofSave = pExpr->bEof; - fts3EvalRestart(pCsr, pExpr, &rc); - while( rc==SQLITE_OK && !pExpr->bEof ){ - fts3EvalNextRow(pCsr, pExpr, &rc); - if( bEofSave==0 && pExpr->iDocid==iDocid ) break; + int bEofSave = pNear->bEof; + fts3EvalRestart(pCsr, pNear, &rc); + while( rc==SQLITE_OK && !pNear->bEof ){ + fts3EvalNextRow(pCsr, pNear, &rc); + if( bEofSave==0 && pNear->iDocid==iDocid ) break; } - pIter = pPhrase->doclist.pList; assert( rc!=SQLITE_OK || pPhrase->bIncr==0 ); - if( rc!=SQLITE_OK ) return rc; } - - iMul = ((pCsr->bDesc==bDescDoclist) ? 1 : -1); - while( bTreeEof==1 - && pNear->bEof==0 - && (DOCID_CMP(pNear->iDocid, pCsr->iPrevId) * iMul)<0 - ){ - int rc = SQLITE_OK; - fts3EvalNextRow(pCsr, pExpr, &rc); - if( rc!=SQLITE_OK ) return rc; - iDocid = pExpr->iDocid; - pIter = pPhrase->doclist.pList; + if( bTreeEof ){ + while( rc==SQLITE_OK && !pNear->bEof ){ + fts3EvalNextRow(pCsr, pNear, &rc); + } } + if( rc!=SQLITE_OK ) return rc; - bEof = (pPhrase->doclist.nAll==0); - assert( bDescDoclist==0 || bDescDoclist==1 ); - assert( pCsr->bDesc==0 || pCsr->bDesc==1 ); - - if( bEof==0 ){ - if( pCsr->bDesc==bDescDoclist ){ + pIter = pPhrase->pOrPoslist; + iDocid = pPhrase->iOrDocid; + if( pCsr->bDesc==bDescDoclist ){ + bEof = !pPhrase->doclist.nAll || + (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll)); + while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){ + sqlite3Fts3DoclistNext( + bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, + &pIter, &iDocid, &bEof + ); + } + }else{ + bEof = !pPhrase->doclist.nAll || (pIter && pIter<=pPhrase->doclist.aAll); + while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){ int dummy; - if( pNear->bEof ){ - /* This expression is already at EOF. So position it to point to the - ** last entry in the doclist at pPhrase->doclist.aAll[]. Variable - ** iDocid is already set for this entry, so all that is required is - ** to set pIter to point to the first byte of the last position-list - ** in the doclist. - ** - ** It would also be correct to set pIter and iDocid to zero. In - ** this case, the first call to sqltie3Fts4DoclistPrev() below - ** would also move the iterator to point to the last entry in the - ** doclist. However, this is expensive, as to do so it has to - ** iterate through the entire doclist from start to finish (since - ** it does not know the docid for the last entry). */ - pIter = &pPhrase->doclist.aAll[pPhrase->doclist.nAll-1]; - fts3ReversePoslist(pPhrase->doclist.aAll, &pIter); - } - while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){ - sqlite3Fts3DoclistPrev( - bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, - &pIter, &iDocid, &dummy, &bEof - ); - } - }else{ - if( pNear->bEof ){ - pIter = 0; - iDocid = 0; - } - while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){ - sqlite3Fts3DoclistNext( - bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, - &pIter, &iDocid, &bEof - ); - } + sqlite3Fts3DoclistPrev( + bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, + &pIter, &iDocid, &dummy, &bEof + ); } } + pPhrase->pOrPoslist = pIter; + pPhrase->iOrDocid = iDocid; if( bEof || iDocid!=pCsr->iPrevId ) pIter = 0; } @@ -137065,10 +138831,13 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist( } while( iThis<iCol ){ fts3ColumnlistCopy(0, &pIter); - if( *pIter==0x00 ) return 0; + if( *pIter==0x00 ) return SQLITE_OK; pIter++; pIter += fts3GetVarint32(pIter, &iThis); } + if( *pIter==0x00 ){ + pIter = 0; + } *ppOut = ((iCol==iThis)?pIter:0); return SQLITE_OK; @@ -137111,7 +138880,7 @@ SQLITE_PRIVATE int sqlite3Fts3Corrupt(){ #ifdef _WIN32 __declspec(dllexport) #endif -SQLITE_API int sqlite3_fts3_init( +SQLITE_API int SQLITE_STDCALL sqlite3_fts3_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi @@ -137242,7 +139011,7 @@ static int fts3auxConnectMethod( return SQLITE_OK; bad_args: - *pzErr = sqlite3_mprintf("invalid arguments to fts4aux constructor"); + sqlite3Fts3ErrMsg(pzErr, "invalid arguments to fts4aux constructor"); return SQLITE_ERROR; } @@ -138700,13 +140469,13 @@ SQLITE_PRIVATE int sqlite3Fts3ExprParse( sqlite3Fts3ExprFree(*ppExpr); *ppExpr = 0; if( rc==SQLITE_TOOBIG ){ - *pzErr = sqlite3_mprintf( + sqlite3Fts3ErrMsg(pzErr, "FTS expression tree is too large (maximum depth %d)", SQLITE_FTS3_MAX_EXPR_DEPTH ); rc = SQLITE_ERROR; }else if( rc==SQLITE_ERROR ){ - *pzErr = sqlite3_mprintf("malformed MATCH expression: [%s]", z); + sqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z); } } @@ -140079,7 +141848,7 @@ static void scalarFunc( if( argc==2 ){ void *pOld; int n = sqlite3_value_bytes(argv[1]); - if( n!=sizeof(pPtr) ){ + if( zName==0 || n!=sizeof(pPtr) ){ sqlite3_result_error(context, "argument type mismatch", -1); return; } @@ -140090,7 +141859,9 @@ static void scalarFunc( return; } }else{ - pPtr = sqlite3Fts3HashFind(pHash, zName, nName); + if( zName ){ + pPtr = sqlite3Fts3HashFind(pHash, zName, nName); + } if( !pPtr ){ char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName); sqlite3_result_error(context, zErr, -1); @@ -140171,12 +141942,16 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( zEnd = &zCopy[strlen(zCopy)]; z = (char *)sqlite3Fts3NextToken(zCopy, &n); + if( z==0 ){ + assert( n==0 ); + z = zCopy; + } z[n] = '\0'; sqlite3Fts3Dequote(z); m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1); if( !m ){ - *pzErr = sqlite3_mprintf("unknown tokenizer: %s", z); + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z); rc = SQLITE_ERROR; }else{ char const **aArg = 0; @@ -140199,7 +141974,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( rc = m->xCreate(iArg, aArg, ppTok); assert( rc!=SQLITE_OK || *ppTok ); if( rc!=SQLITE_OK ){ - *pzErr = sqlite3_mprintf("unknown tokenizer"); + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer"); }else{ (*ppTok)->pModule = m; } @@ -140283,9 +142058,9 @@ static void testFunc( p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1); if( !p ){ - char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName); - sqlite3_result_error(context, zErr, -1); - sqlite3_free(zErr); + char *zErr2 = sqlite3_mprintf("unknown tokenizer: %s", zName); + sqlite3_result_error(context, zErr2, -1); + sqlite3_free(zErr2); return; } @@ -140820,7 +142595,7 @@ static int fts3tokQueryTokenizer( p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1); if( !p ){ - *pzErr = sqlite3_mprintf("unknown tokenizer: %s", zName); + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", zName); return SQLITE_ERROR; } @@ -141517,7 +143292,7 @@ static int fts3SqlStmt( /* 25 */ "", /* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", -/* 27 */ "SELECT DISTINCT level / (1024 * ?) FROM %Q.'%q_segdir'", +/* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'", /* This statement is used to determine which level to read the input from ** when performing an incremental merge. It returns the absolute level number @@ -142816,7 +144591,10 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew( ** an array of pending terms by term. This occurs as part of flushing ** the contents of the pending-terms hash table to the database. */ -static int fts3CompareElemByTerm(const void *lhs, const void *rhs){ +static int SQLITE_CDECL fts3CompareElemByTerm( + const void *lhs, + const void *rhs +){ char *z1 = fts3HashKey(*(Fts3HashElem **)lhs); char *z2 = fts3HashKey(*(Fts3HashElem **)rhs); int n1 = fts3HashKeysize(*(Fts3HashElem **)lhs); @@ -144632,7 +146410,8 @@ static int fts3DoOptimize(Fts3Table *p, int bReturnDone){ rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); if( rc==SQLITE_OK ){ int rc2; - sqlite3_bind_int(pAllLangid, 1, p->nIndex); + sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); + sqlite3_bind_int(pAllLangid, 2, p->nIndex); while( sqlite3_step(pAllLangid)==SQLITE_ROW ){ int i; int iLangid = sqlite3_column_int(pAllLangid, 0); @@ -145964,7 +147743,7 @@ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){ pHint->n = i; i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); i += fts3GetVarint32(&pHint->a[i], pnInput); - if( i!=nHint ) return SQLITE_CORRUPT_VTAB; + if( i!=nHint ) return FTS_CORRUPT_VTAB; return SQLITE_OK; } @@ -146332,7 +148111,8 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); if( rc==SQLITE_OK ){ int rc2; - sqlite3_bind_int(pAllLangid, 1, p->nIndex); + sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); + sqlite3_bind_int(pAllLangid, 2, p->nIndex); while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){ int iLangid = sqlite3_column_int(pAllLangid, 0); int i; @@ -146345,7 +148125,6 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ } /* This block calculates the checksum according to the %_content table */ - rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); if( rc==SQLITE_OK ){ sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule; sqlite3_stmt *pStmt = 0; @@ -146442,7 +148221,7 @@ static int fts3DoIntegrityCheck( int rc; int bOk = 0; rc = fts3IntegrityCheck(p, &bOk); - if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_CORRUPT_VTAB; + if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB; return rc; } @@ -146880,6 +148659,7 @@ SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){ #define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */ #define FTS3_MATCHINFO_LCS 's' /* nCol values */ #define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */ +#define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */ /* ** The default value for the second argument to matchinfo(). @@ -147295,37 +149075,39 @@ static int fts3BestSnippet( sIter.nSnippet = nSnippet; sIter.nPhrase = nList; sIter.iCurrent = -1; - (void)fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter); + rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter); + if( rc==SQLITE_OK ){ - /* Set the *pmSeen output variable. */ - for(i=0; i<nList; i++){ - if( sIter.aPhrase[i].pHead ){ - *pmSeen |= (u64)1 << i; + /* Set the *pmSeen output variable. */ + for(i=0; i<nList; i++){ + if( sIter.aPhrase[i].pHead ){ + *pmSeen |= (u64)1 << i; + } } - } - /* Loop through all candidate snippets. Store the best snippet in - ** *pFragment. Store its associated 'score' in iBestScore. - */ - pFragment->iCol = iCol; - while( !fts3SnippetNextCandidate(&sIter) ){ - int iPos; - int iScore; - u64 mCover; - u64 mHighlight; - fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover, &mHighlight); - assert( iScore>=0 ); - if( iScore>iBestScore ){ - pFragment->iPos = iPos; - pFragment->hlmask = mHighlight; - pFragment->covered = mCover; - iBestScore = iScore; + /* Loop through all candidate snippets. Store the best snippet in + ** *pFragment. Store its associated 'score' in iBestScore. + */ + pFragment->iCol = iCol; + while( !fts3SnippetNextCandidate(&sIter) ){ + int iPos; + int iScore; + u64 mCover; + u64 mHighlite; + fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover,&mHighlite); + assert( iScore>=0 ); + if( iScore>iBestScore ){ + pFragment->iPos = iPos; + pFragment->hlmask = mHighlite; + pFragment->covered = mCover; + iBestScore = iScore; + } } - } + *piScore = iBestScore; + } sqlite3_free(sIter.aPhrase); - *piScore = iBestScore; - return SQLITE_OK; + return rc; } @@ -147533,8 +149315,12 @@ static int fts3SnippetText( ** required. They are required if (a) this is not the first fragment, ** or (b) this fragment does not begin at position 0 of its column. */ - if( rc==SQLITE_OK && (iPos>0 || iFragment>0) ){ - rc = fts3StringAppend(pOut, zEllipsis, -1); + if( rc==SQLITE_OK ){ + if( iPos>0 || iFragment>0 ){ + rc = fts3StringAppend(pOut, zEllipsis, -1); + }else if( iBegin ){ + rc = fts3StringAppend(pOut, zDoc, iBegin); + } } if( rc!=SQLITE_OK || iCurrent<iPos ) continue; } @@ -147656,6 +149442,51 @@ static int fts3ExprLocalHitsCb( return rc; } +/* +** fts3ExprIterate() callback used to gather information for the matchinfo +** directive 'y'. +*/ +static int fts3ExprLHitsCb( + Fts3Expr *pExpr, /* Phrase expression node */ + int iPhrase, /* Phrase number */ + void *pCtx /* Pointer to MatchInfo structure */ +){ + MatchInfo *p = (MatchInfo *)pCtx; + Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab; + int rc = SQLITE_OK; + int iStart = iPhrase * p->nCol; + Fts3Expr *pEof; /* Ancestor node already at EOF */ + + /* This must be a phrase */ + assert( pExpr->pPhrase ); + + /* Initialize all output integers to zero. */ + memset(&p->aMatchinfo[iStart], 0, sizeof(u32) * p->nCol); + + /* Check if this or any parent node is at EOF. If so, then all output + ** values are zero. */ + for(pEof=pExpr; pEof && pEof->bEof==0; pEof=pEof->pParent); + + if( pEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + char *pIter = pPhrase->doclist.pList; + int iCol = 0; + + while( 1 ){ + int nHit = fts3ColumnlistCount(&pIter); + if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){ + p->aMatchinfo[iStart + iCol] = (u32)nHit; + } + assert( *pIter==0x00 || *pIter==0x01 ); + if( *pIter!=0x01 ) break; + pIter++; + pIter += fts3GetVarint32(pIter, &iCol); + } + } + + return rc; +} + static int fts3MatchinfoCheck( Fts3Table *pTab, char cArg, @@ -147668,10 +149499,11 @@ static int fts3MatchinfoCheck( || (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize) || (cArg==FTS3_MATCHINFO_LCS) || (cArg==FTS3_MATCHINFO_HITS) + || (cArg==FTS3_MATCHINFO_LHITS) ){ return SQLITE_OK; } - *pzErr = sqlite3_mprintf("unrecognized matchinfo request: %c", cArg); + sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg); return SQLITE_ERROR; } @@ -147691,6 +149523,10 @@ static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ nVal = pInfo->nCol; break; + case FTS3_MATCHINFO_LHITS: + nVal = pInfo->nCol * pInfo->nPhrase; + break; + default: assert( cArg==FTS3_MATCHINFO_HITS ); nVal = pInfo->nCol * pInfo->nPhrase * 3; @@ -147945,6 +149781,10 @@ static int fts3MatchinfoValues( } break; + case FTS3_MATCHINFO_LHITS: + (void)fts3ExprIterate(pCsr->pExpr, fts3ExprLHitsCb, (void*)pInfo); + break; + default: { Fts3Expr *pExpr; assert( zArg[i]==FTS3_MATCHINFO_HITS ); @@ -148100,7 +149940,7 @@ SQLITE_PRIVATE void sqlite3Fts3Snippet( */ for(iRead=0; iRead<pTab->nColumn; iRead++){ SnippetFragment sF = {0, 0, 0, 0}; - int iS; + int iS = 0; if( iCol>=0 && iRead!=iCol ) continue; /* Find the best snippet of nFToken tokens in column iRead. */ @@ -151957,11 +153797,19 @@ static int rtreeUpdate( if( nData>1 ){ int ii; - /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */ - assert( nData==(pRtree->nDim*2 + 3) ); + /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. + ** + ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared + ** with "column" that are interpreted as table constraints. + ** Example: CREATE VIRTUAL TABLE bad USING rtree(x,y,CHECK(y>5)); + ** This problem was discovered after years of use, so we silently ignore + ** these kinds of misdeclared tables to avoid breaking any legacy. + */ + assert( nData<=(pRtree->nDim*2 + 3) ); + #ifndef SQLITE_RTREE_INT_ONLY if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ - for(ii=0; ii<(pRtree->nDim*2); ii+=2){ + for(ii=0; ii<nData-4; ii+=2){ cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]); cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]); if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){ @@ -151972,7 +153820,7 @@ static int rtreeUpdate( }else #endif { - for(ii=0; ii<(pRtree->nDim*2); ii+=2){ + for(ii=0; ii<nData-4; ii+=2){ cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]); cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]); if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){ @@ -152543,7 +154391,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ /* ** Register a new geometry function for use with the r-tree MATCH operator. */ -SQLITE_API int sqlite3_rtree_geometry_callback( +SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback( sqlite3 *db, /* Register SQL function on this connection */ const char *zGeom, /* Name of the new SQL function */ int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */ @@ -152567,7 +154415,7 @@ SQLITE_API int sqlite3_rtree_geometry_callback( ** Register a new 2nd-generation geometry function for use with the ** r-tree MATCH operator. */ -SQLITE_API int sqlite3_rtree_query_callback( +SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback( sqlite3 *db, /* Register SQL function on this connection */ const char *zQueryFunc, /* Name of new SQL function */ int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */ @@ -152592,7 +154440,7 @@ SQLITE_API int sqlite3_rtree_query_callback( #ifdef _WIN32 __declspec(dllexport) #endif -SQLITE_API int sqlite3_rtree_init( +SQLITE_API int SQLITE_STDCALL sqlite3_rtree_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi @@ -153097,7 +154945,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){ #ifdef _WIN32 __declspec(dllexport) #endif -SQLITE_API int sqlite3_icu_init( +SQLITE_API int SQLITE_STDCALL sqlite3_icu_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi @@ -153372,3 +155220,654 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ /************** End of fts3_icu.c ********************************************/ +/************** Begin file dbstat.c ******************************************/ +/* +** 2010 July 12 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains an implementation of the "dbstat" virtual table. +** +** The dbstat virtual table is used to extract low-level formatting +** information from an SQLite database in order to implement the +** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script +** for an example implementation. +*/ + +#if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \ + && !defined(SQLITE_OMIT_VIRTUALTABLE) + +/* +** Page paths: +** +** The value of the 'path' column describes the path taken from the +** root-node of the b-tree structure to each page. The value of the +** root-node path is '/'. +** +** The value of the path for the left-most child page of the root of +** a b-tree is '/000/'. (Btrees store content ordered from left to right +** so the pages to the left have smaller keys than the pages to the right.) +** The next to left-most child of the root page is +** '/001', and so on, each sibling page identified by a 3-digit hex +** value. The children of the 451st left-most sibling have paths such +** as '/1c2/000/, '/1c2/001/' etc. +** +** Overflow pages are specified by appending a '+' character and a +** six-digit hexadecimal value to the path to the cell they are linked +** from. For example, the three overflow pages in a chain linked from +** the left-most cell of the 450th child of the root page are identified +** by the paths: +** +** '/1c2/000+000000' // First page in overflow chain +** '/1c2/000+000001' // Second page in overflow chain +** '/1c2/000+000002' // Third page in overflow chain +** +** If the paths are sorted using the BINARY collation sequence, then +** the overflow pages associated with a cell will appear earlier in the +** sort-order than its child page: +** +** '/1c2/000/' // Left-most child of 451st child of root +*/ +#define VTAB_SCHEMA \ + "CREATE TABLE xx( " \ + " name STRING, /* Name of table or index */" \ + " path INTEGER, /* Path to page from root */" \ + " pageno INTEGER, /* Page number */" \ + " pagetype STRING, /* 'internal', 'leaf' or 'overflow' */" \ + " ncell INTEGER, /* Cells on page (0 for overflow) */" \ + " payload INTEGER, /* Bytes of payload on this page */" \ + " unused INTEGER, /* Bytes of unused space on this page */" \ + " mx_payload INTEGER, /* Largest payload size of all cells */" \ + " pgoffset INTEGER, /* Offset of page in file */" \ + " pgsize INTEGER /* Size of the page */" \ + ");" + + +typedef struct StatTable StatTable; +typedef struct StatCursor StatCursor; +typedef struct StatPage StatPage; +typedef struct StatCell StatCell; + +struct StatCell { + int nLocal; /* Bytes of local payload */ + u32 iChildPg; /* Child node (or 0 if this is a leaf) */ + int nOvfl; /* Entries in aOvfl[] */ + u32 *aOvfl; /* Array of overflow page numbers */ + int nLastOvfl; /* Bytes of payload on final overflow page */ + int iOvfl; /* Iterates through aOvfl[] */ +}; + +struct StatPage { + u32 iPgno; + DbPage *pPg; + int iCell; + + char *zPath; /* Path to this page */ + + /* Variables populated by statDecodePage(): */ + u8 flags; /* Copy of flags byte */ + int nCell; /* Number of cells on page */ + int nUnused; /* Number of unused bytes on page */ + StatCell *aCell; /* Array of parsed cells */ + u32 iRightChildPg; /* Right-child page number (or 0) */ + int nMxPayload; /* Largest payload of any cell on this page */ +}; + +struct StatCursor { + sqlite3_vtab_cursor base; + sqlite3_stmt *pStmt; /* Iterates through set of root pages */ + int isEof; /* After pStmt has returned SQLITE_DONE */ + + StatPage aPage[32]; + int iPage; /* Current entry in aPage[] */ + + /* Values to return. */ + char *zName; /* Value of 'name' column */ + char *zPath; /* Value of 'path' column */ + u32 iPageno; /* Value of 'pageno' column */ + char *zPagetype; /* Value of 'pagetype' column */ + int nCell; /* Value of 'ncell' column */ + int nPayload; /* Value of 'payload' column */ + int nUnused; /* Value of 'unused' column */ + int nMxPayload; /* Value of 'mx_payload' column */ + i64 iOffset; /* Value of 'pgOffset' column */ + int szPage; /* Value of 'pgSize' column */ +}; + +struct StatTable { + sqlite3_vtab base; + sqlite3 *db; + int iDb; /* Index of database to analyze */ +}; + +#ifndef get2byte +# define get2byte(x) ((x)[0]<<8 | (x)[1]) +#endif + +/* +** Connect to or create a statvfs virtual table. +*/ +static int statConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + StatTable *pTab = 0; + int rc = SQLITE_OK; + int iDb; + + if( argc>=4 ){ + iDb = sqlite3FindDbName(db, argv[3]); + if( iDb<0 ){ + *pzErr = sqlite3_mprintf("no such database: %s", argv[3]); + return SQLITE_ERROR; + } + }else{ + iDb = 0; + } + rc = sqlite3_declare_vtab(db, VTAB_SCHEMA); + if( rc==SQLITE_OK ){ + pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable)); + if( pTab==0 ) rc = SQLITE_NOMEM; + } + + assert( rc==SQLITE_OK || pTab==0 ); + if( rc==SQLITE_OK ){ + memset(pTab, 0, sizeof(StatTable)); + pTab->db = db; + pTab->iDb = iDb; + } + + *ppVtab = (sqlite3_vtab*)pTab; + return rc; +} + +/* +** Disconnect from or destroy a statvfs virtual table. +*/ +static int statDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** There is no "best-index". This virtual table always does a linear +** scan of the binary VFS log file. +*/ +static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + + /* Records are always returned in ascending order of (name, path). + ** If this will satisfy the client, set the orderByConsumed flag so that + ** SQLite does not do an external sort. + */ + if( ( pIdxInfo->nOrderBy==1 + && pIdxInfo->aOrderBy[0].iColumn==0 + && pIdxInfo->aOrderBy[0].desc==0 + ) || + ( pIdxInfo->nOrderBy==2 + && pIdxInfo->aOrderBy[0].iColumn==0 + && pIdxInfo->aOrderBy[0].desc==0 + && pIdxInfo->aOrderBy[1].iColumn==1 + && pIdxInfo->aOrderBy[1].desc==0 + ) + ){ + pIdxInfo->orderByConsumed = 1; + } + + pIdxInfo->estimatedCost = 10.0; + return SQLITE_OK; +} + +/* +** Open a new statvfs cursor. +*/ +static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ + StatTable *pTab = (StatTable *)pVTab; + StatCursor *pCsr; + int rc; + + pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor)); + if( pCsr==0 ){ + rc = SQLITE_NOMEM; + }else{ + char *zSql; + memset(pCsr, 0, sizeof(StatCursor)); + pCsr->base.pVtab = pVTab; + + zSql = sqlite3_mprintf( + "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type" + " UNION ALL " + "SELECT name, rootpage, type" + " FROM \"%w\".sqlite_master WHERE rootpage!=0" + " ORDER BY name", pTab->db->aDb[pTab->iDb].zName); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0); + sqlite3_free(zSql); + } + if( rc!=SQLITE_OK ){ + sqlite3_free(pCsr); + pCsr = 0; + } + } + + *ppCursor = (sqlite3_vtab_cursor *)pCsr; + return rc; +} + +static void statClearPage(StatPage *p){ + int i; + if( p->aCell ){ + for(i=0; i<p->nCell; i++){ + sqlite3_free(p->aCell[i].aOvfl); + } + sqlite3_free(p->aCell); + } + sqlite3PagerUnref(p->pPg); + sqlite3_free(p->zPath); + memset(p, 0, sizeof(StatPage)); +} + +static void statResetCsr(StatCursor *pCsr){ + int i; + sqlite3_reset(pCsr->pStmt); + for(i=0; i<ArraySize(pCsr->aPage); i++){ + statClearPage(&pCsr->aPage[i]); + } + pCsr->iPage = 0; + sqlite3_free(pCsr->zPath); + pCsr->zPath = 0; +} + +/* +** Close a statvfs cursor. +*/ +static int statClose(sqlite3_vtab_cursor *pCursor){ + StatCursor *pCsr = (StatCursor *)pCursor; + statResetCsr(pCsr); + sqlite3_finalize(pCsr->pStmt); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +static void getLocalPayload( + int nUsable, /* Usable bytes per page */ + u8 flags, /* Page flags */ + int nTotal, /* Total record (payload) size */ + int *pnLocal /* OUT: Bytes stored locally */ +){ + int nLocal; + int nMinLocal; + int nMaxLocal; + + if( flags==0x0D ){ /* Table leaf node */ + nMinLocal = (nUsable - 12) * 32 / 255 - 23; + nMaxLocal = nUsable - 35; + }else{ /* Index interior and leaf nodes */ + nMinLocal = (nUsable - 12) * 32 / 255 - 23; + nMaxLocal = (nUsable - 12) * 64 / 255 - 23; + } + + nLocal = nMinLocal + (nTotal - nMinLocal) % (nUsable - 4); + if( nLocal>nMaxLocal ) nLocal = nMinLocal; + *pnLocal = nLocal; +} + +static int statDecodePage(Btree *pBt, StatPage *p){ + int nUnused; + int iOff; + int nHdr; + int isLeaf; + int szPage; + + u8 *aData = sqlite3PagerGetData(p->pPg); + u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0]; + + p->flags = aHdr[0]; + p->nCell = get2byte(&aHdr[3]); + p->nMxPayload = 0; + + isLeaf = (p->flags==0x0A || p->flags==0x0D); + nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100; + + nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell; + nUnused += (int)aHdr[7]; + iOff = get2byte(&aHdr[1]); + while( iOff ){ + nUnused += get2byte(&aData[iOff+2]); + iOff = get2byte(&aData[iOff]); + } + p->nUnused = nUnused; + p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]); + szPage = sqlite3BtreeGetPageSize(pBt); + + if( p->nCell ){ + int i; /* Used to iterate through cells */ + int nUsable; /* Usable bytes per page */ + + sqlite3BtreeEnter(pBt); + nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt); + sqlite3BtreeLeave(pBt); + p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell)); + if( p->aCell==0 ) return SQLITE_NOMEM; + memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell)); + + for(i=0; i<p->nCell; i++){ + StatCell *pCell = &p->aCell[i]; + + iOff = get2byte(&aData[nHdr+i*2]); + if( !isLeaf ){ + pCell->iChildPg = sqlite3Get4byte(&aData[iOff]); + iOff += 4; + } + if( p->flags==0x05 ){ + /* A table interior node. nPayload==0. */ + }else{ + u32 nPayload; /* Bytes of payload total (local+overflow) */ + int nLocal; /* Bytes of payload stored locally */ + iOff += getVarint32(&aData[iOff], nPayload); + if( p->flags==0x0D ){ + u64 dummy; + iOff += sqlite3GetVarint(&aData[iOff], &dummy); + } + if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload; + getLocalPayload(nUsable, p->flags, nPayload, &nLocal); + pCell->nLocal = nLocal; + assert( nLocal>=0 ); + assert( nPayload>=(u32)nLocal ); + assert( nLocal<=(nUsable-35) ); + if( nPayload>(u32)nLocal ){ + int j; + int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4); + pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4); + pCell->nOvfl = nOvfl; + pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl); + if( pCell->aOvfl==0 ) return SQLITE_NOMEM; + pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]); + for(j=1; j<nOvfl; j++){ + int rc; + u32 iPrev = pCell->aOvfl[j-1]; + DbPage *pPg = 0; + rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg); + if( rc!=SQLITE_OK ){ + assert( pPg==0 ); + return rc; + } + pCell->aOvfl[j] = sqlite3Get4byte(sqlite3PagerGetData(pPg)); + sqlite3PagerUnref(pPg); + } + } + } + } + } + + return SQLITE_OK; +} + +/* +** Populate the pCsr->iOffset and pCsr->szPage member variables. Based on +** the current value of pCsr->iPageno. +*/ +static void statSizeAndOffset(StatCursor *pCsr){ + StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab; + Btree *pBt = pTab->db->aDb[pTab->iDb].pBt; + Pager *pPager = sqlite3BtreePager(pBt); + sqlite3_file *fd; + sqlite3_int64 x[2]; + + /* The default page size and offset */ + pCsr->szPage = sqlite3BtreeGetPageSize(pBt); + pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1); + + /* If connected to a ZIPVFS backend, override the page size and + ** offset with actual values obtained from ZIPVFS. + */ + fd = sqlite3PagerFile(pPager); + x[0] = pCsr->iPageno; + if( fd->pMethods!=0 && sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ + pCsr->iOffset = x[0]; + pCsr->szPage = (int)x[1]; + } +} + +/* +** Move a statvfs cursor to the next entry in the file. +*/ +static int statNext(sqlite3_vtab_cursor *pCursor){ + int rc; + int nPayload; + char *z; + StatCursor *pCsr = (StatCursor *)pCursor; + StatTable *pTab = (StatTable *)pCursor->pVtab; + Btree *pBt = pTab->db->aDb[pTab->iDb].pBt; + Pager *pPager = sqlite3BtreePager(pBt); + + sqlite3_free(pCsr->zPath); + pCsr->zPath = 0; + +statNextRestart: + if( pCsr->aPage[0].pPg==0 ){ + rc = sqlite3_step(pCsr->pStmt); + if( rc==SQLITE_ROW ){ + int nPage; + u32 iRoot = (u32)sqlite3_column_int64(pCsr->pStmt, 1); + sqlite3PagerPagecount(pPager, &nPage); + if( nPage==0 ){ + pCsr->isEof = 1; + return sqlite3_reset(pCsr->pStmt); + } + rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg); + pCsr->aPage[0].iPgno = iRoot; + pCsr->aPage[0].iCell = 0; + pCsr->aPage[0].zPath = z = sqlite3_mprintf("/"); + pCsr->iPage = 0; + if( z==0 ) rc = SQLITE_NOMEM; + }else{ + pCsr->isEof = 1; + return sqlite3_reset(pCsr->pStmt); + } + }else{ + + /* Page p itself has already been visited. */ + StatPage *p = &pCsr->aPage[pCsr->iPage]; + + while( p->iCell<p->nCell ){ + StatCell *pCell = &p->aCell[p->iCell]; + if( pCell->iOvfl<pCell->nOvfl ){ + int nUsable; + sqlite3BtreeEnter(pBt); + nUsable = sqlite3BtreeGetPageSize(pBt) - + sqlite3BtreeGetReserveNoMutex(pBt); + sqlite3BtreeLeave(pBt); + pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0); + pCsr->iPageno = pCell->aOvfl[pCell->iOvfl]; + pCsr->zPagetype = "overflow"; + pCsr->nCell = 0; + pCsr->nMxPayload = 0; + pCsr->zPath = z = sqlite3_mprintf( + "%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl + ); + if( pCell->iOvfl<pCell->nOvfl-1 ){ + pCsr->nUnused = 0; + pCsr->nPayload = nUsable - 4; + }else{ + pCsr->nPayload = pCell->nLastOvfl; + pCsr->nUnused = nUsable - 4 - pCsr->nPayload; + } + pCell->iOvfl++; + statSizeAndOffset(pCsr); + return z==0 ? SQLITE_NOMEM : SQLITE_OK; + } + if( p->iRightChildPg ) break; + p->iCell++; + } + + if( !p->iRightChildPg || p->iCell>p->nCell ){ + statClearPage(p); + if( pCsr->iPage==0 ) return statNext(pCursor); + pCsr->iPage--; + goto statNextRestart; /* Tail recursion */ + } + pCsr->iPage++; + assert( p==&pCsr->aPage[pCsr->iPage-1] ); + + if( p->iCell==p->nCell ){ + p[1].iPgno = p->iRightChildPg; + }else{ + p[1].iPgno = p->aCell[p->iCell].iChildPg; + } + rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg); + p[1].iCell = 0; + p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell); + p->iCell++; + if( z==0 ) rc = SQLITE_NOMEM; + } + + + /* Populate the StatCursor fields with the values to be returned + ** by the xColumn() and xRowid() methods. + */ + if( rc==SQLITE_OK ){ + int i; + StatPage *p = &pCsr->aPage[pCsr->iPage]; + pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0); + pCsr->iPageno = p->iPgno; + + rc = statDecodePage(pBt, p); + if( rc==SQLITE_OK ){ + statSizeAndOffset(pCsr); + + switch( p->flags ){ + case 0x05: /* table internal */ + case 0x02: /* index internal */ + pCsr->zPagetype = "internal"; + break; + case 0x0D: /* table leaf */ + case 0x0A: /* index leaf */ + pCsr->zPagetype = "leaf"; + break; + default: + pCsr->zPagetype = "corrupted"; + break; + } + pCsr->nCell = p->nCell; + pCsr->nUnused = p->nUnused; + pCsr->nMxPayload = p->nMxPayload; + pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath); + if( z==0 ) rc = SQLITE_NOMEM; + nPayload = 0; + for(i=0; i<p->nCell; i++){ + nPayload += p->aCell[i].nLocal; + } + pCsr->nPayload = nPayload; + } + } + + return rc; +} + +static int statEof(sqlite3_vtab_cursor *pCursor){ + StatCursor *pCsr = (StatCursor *)pCursor; + return pCsr->isEof; +} + +static int statFilter( + sqlite3_vtab_cursor *pCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + StatCursor *pCsr = (StatCursor *)pCursor; + + statResetCsr(pCsr); + return statNext(pCursor); +} + +static int statColumn( + sqlite3_vtab_cursor *pCursor, + sqlite3_context *ctx, + int i +){ + StatCursor *pCsr = (StatCursor *)pCursor; + switch( i ){ + case 0: /* name */ + sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_TRANSIENT); + break; + case 1: /* path */ + sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT); + break; + case 2: /* pageno */ + sqlite3_result_int64(ctx, pCsr->iPageno); + break; + case 3: /* pagetype */ + sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC); + break; + case 4: /* ncell */ + sqlite3_result_int(ctx, pCsr->nCell); + break; + case 5: /* payload */ + sqlite3_result_int(ctx, pCsr->nPayload); + break; + case 6: /* unused */ + sqlite3_result_int(ctx, pCsr->nUnused); + break; + case 7: /* mx_payload */ + sqlite3_result_int(ctx, pCsr->nMxPayload); + break; + case 8: /* pgoffset */ + sqlite3_result_int64(ctx, pCsr->iOffset); + break; + default: /* pgsize */ + assert( i==9 ); + sqlite3_result_int(ctx, pCsr->szPage); + break; + } + return SQLITE_OK; +} + +static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ + StatCursor *pCsr = (StatCursor *)pCursor; + *pRowid = pCsr->iPageno; + return SQLITE_OK; +} + +/* +** Invoke this routine to register the "dbstat" virtual table module +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_dbstat_register(sqlite3 *db){ + static sqlite3_module dbstat_module = { + 0, /* iVersion */ + statConnect, /* xCreate */ + statConnect, /* xConnect */ + statBestIndex, /* xBestIndex */ + statDisconnect, /* xDisconnect */ + statDisconnect, /* xDestroy */ + statOpen, /* xOpen - open a cursor */ + statClose, /* xClose - close a cursor */ + statFilter, /* xFilter - configure scan constraints */ + statNext, /* xNext - advance a cursor */ + statEof, /* xEof - check for end of scan */ + statColumn, /* xColumn - read data */ + statRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + }; + return sqlite3_create_module(db, "dbstat", &dbstat_module, 0); +} +#endif /* SQLITE_ENABLE_DBSTAT_VTAB */ + +/************** End of dbstat.c **********************************************/ diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h index bd64ec82c8e0e89a207d7c78ffa15d6c3a8bd6ad..d43b63c10785076dbc3dc39b7b72a4002d4ad4b7 100644 --- a/src/3rdparty/sqlite/sqlite3.h +++ b/src/3rdparty/sqlite/sqlite3.h @@ -43,16 +43,20 @@ extern "C" { /* -** Add the ability to override 'extern' +** Provide the ability to override linkage features of the interface. */ #ifndef SQLITE_EXTERN # define SQLITE_EXTERN extern #endif - #ifndef SQLITE_API # define SQLITE_API #endif - +#ifndef SQLITE_CDECL +# define SQLITE_CDECL +#endif +#ifndef SQLITE_STDCALL +# define SQLITE_STDCALL +#endif /* ** These no-op macros are used in front of interfaces to mark those @@ -107,9 +111,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.8.8.2" -#define SQLITE_VERSION_NUMBER 3008008 -#define SQLITE_SOURCE_ID "2015-01-30 14:30:45 7757fc721220e136620a89c9d28247f28bbbc098" +#define SQLITE_VERSION "3.8.10.2" +#define SQLITE_VERSION_NUMBER 3008010 +#define SQLITE_SOURCE_ID "2015-05-20 18:17:19 2ef4f3a5b1d1d0c4338f8243d40a2452cc1f7fe4" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -142,9 +146,9 @@ extern "C" { ** See also: [sqlite_version()] and [sqlite_source_id()]. */ SQLITE_API SQLITE_EXTERN const char sqlite3_version[]; -SQLITE_API const char *sqlite3_libversion(void); -SQLITE_API const char *sqlite3_sourceid(void); -SQLITE_API int sqlite3_libversion_number(void); +SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void); +SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void); +SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void); /* ** CAPI3REF: Run-Time Library Compilation Options Diagnostics @@ -169,8 +173,8 @@ SQLITE_API int sqlite3_libversion_number(void); ** [sqlite_compileoption_get()] and the [compile_options pragma]. */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS -SQLITE_API int sqlite3_compileoption_used(const char *zOptName); -SQLITE_API const char *sqlite3_compileoption_get(int N); +SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName); +SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N); #endif /* @@ -209,7 +213,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N); ** ** See the [threading mode] documentation for additional information. */ -SQLITE_API int sqlite3_threadsafe(void); +SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void); /* ** CAPI3REF: Database Connection Handle @@ -266,6 +270,7 @@ typedef sqlite_uint64 sqlite3_uint64; /* ** CAPI3REF: Closing A Database Connection +** DESTRUCTOR: sqlite3 ** ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors ** for the [sqlite3] object. @@ -305,8 +310,8 @@ typedef sqlite_uint64 sqlite3_uint64; ** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer ** argument is a harmless no-op. */ -SQLITE_API int sqlite3_close(sqlite3*); -SQLITE_API int sqlite3_close_v2(sqlite3*); +SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*); +SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*); /* ** The type for a callback function. @@ -317,6 +322,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); /* ** CAPI3REF: One-Step Query Execution Interface +** METHOD: sqlite3 ** ** The sqlite3_exec() interface is a convenience wrapper around ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], @@ -376,7 +382,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. ** </ul> */ -SQLITE_API int sqlite3_exec( +SQLITE_API int SQLITE_STDCALL sqlite3_exec( sqlite3*, /* An open database */ const char *sql, /* SQL to be evaluated */ int (*callback)(void*,int,char**,char**), /* Callback function */ @@ -756,14 +762,16 @@ struct sqlite3_io_methods { ** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()] ** interface. ** +** <ul> +** <li>[[SQLITE_FCNTL_LOCKSTATE]] ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This ** opcode causes the xFileControl method to write the current state of ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) ** into an integer that the pArg argument points to. This capability -** is used during testing and only needs to be supported when SQLITE_TEST -** is defined. -** <ul> +** is used during testing and is only available when the SQLITE_TEST +** compile-time option is used. +** ** <li>[[SQLITE_FCNTL_SIZE_HINT]] ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS ** layer a hint of how large the database file will grow to be during the @@ -888,7 +896,9 @@ struct sqlite3_io_methods { ** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA] ** file control returns [SQLITE_OK], then the parser assumes that the ** VFS has handled the PRAGMA itself and the parser generates a no-op -** prepared statement. ^If the [SQLITE_FCNTL_PRAGMA] file control returns +** prepared statement if result string is NULL, or that returns a copy +** of the result string if the string is non-NULL. +** ^If the [SQLITE_FCNTL_PRAGMA] file control returns ** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means ** that the VFS encountered an error while handling the [PRAGMA] and the ** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] @@ -946,12 +956,19 @@ struct sqlite3_io_methods { ** pointed to by the pArg argument. This capability is used during testing ** and only needs to be supported when SQLITE_TEST is defined. ** +** <li>[[SQLITE_FCNTL_WAL_BLOCK]] +** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might +** be advantageous to block on the next WAL lock if the lock is not immediately +** available. The WAL subsystem issues this signal during rare +** circumstances in order to fix a problem with priority inversion. +** Applications should <em>not</em> use this file-control. +** ** </ul> */ #define SQLITE_FCNTL_LOCKSTATE 1 -#define SQLITE_GET_LOCKPROXYFILE 2 -#define SQLITE_SET_LOCKPROXYFILE 3 -#define SQLITE_LAST_ERRNO 4 +#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 +#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 +#define SQLITE_FCNTL_LAST_ERRNO 4 #define SQLITE_FCNTL_SIZE_HINT 5 #define SQLITE_FCNTL_CHUNK_SIZE 6 #define SQLITE_FCNTL_FILE_POINTER 7 @@ -970,6 +987,13 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_SYNC 21 #define SQLITE_FCNTL_COMMIT_PHASETWO 22 #define SQLITE_FCNTL_WIN32_SET_HANDLE 23 +#define SQLITE_FCNTL_WAL_BLOCK 24 + +/* deprecated names */ +#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE +#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE +#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO + /* ** CAPI3REF: Mutex Handle @@ -1318,10 +1342,10 @@ struct sqlite3_vfs { ** must return [SQLITE_OK] on success and some other [error code] upon ** failure. */ -SQLITE_API int sqlite3_initialize(void); -SQLITE_API int sqlite3_shutdown(void); -SQLITE_API int sqlite3_os_init(void); -SQLITE_API int sqlite3_os_end(void); +SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void); +SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void); +SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void); +SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void); /* ** CAPI3REF: Configuring The SQLite Library @@ -1352,10 +1376,11 @@ SQLITE_API int sqlite3_os_end(void); ** ^If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. */ -SQLITE_API int sqlite3_config(int, ...); +SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...); /* ** CAPI3REF: Configure database connections +** METHOD: sqlite3 ** ** The sqlite3_db_config() interface is used to make configuration ** changes to a [database connection]. The interface is similar to @@ -1370,7 +1395,7 @@ SQLITE_API int sqlite3_config(int, ...); ** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if ** the call is considered successful. */ -SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); +SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...); /* ** CAPI3REF: Memory Allocation Routines @@ -1530,7 +1555,7 @@ struct sqlite3_mem_methods { ** <li> [sqlite3_memory_used()] ** <li> [sqlite3_memory_highwater()] ** <li> [sqlite3_soft_heap_limit64()] -** <li> [sqlite3_status()] +** <li> [sqlite3_status64()] ** </ul>)^ ** ^Memory allocation statistics are enabled by default unless SQLite is ** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory @@ -1741,7 +1766,6 @@ struct sqlite3_mem_methods { ** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro ** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value ** that specifies the maximum size of the created heap. -** </dl> ** ** [[SQLITE_CONFIG_PCACHE_HDRSZ]] ** <dt>SQLITE_CONFIG_PCACHE_HDRSZ @@ -1854,15 +1878,17 @@ struct sqlite3_mem_methods { /* ** CAPI3REF: Enable Or Disable Extended Result Codes +** METHOD: sqlite3 ** ** ^The sqlite3_extended_result_codes() routine enables or disables the ** [extended result codes] feature of SQLite. ^The extended result ** codes are disabled by default for historical compatibility. */ -SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); +SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff); /* ** CAPI3REF: Last Insert Rowid +** METHOD: sqlite3 ** ** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables) ** has a unique 64-bit signed @@ -1910,10 +1936,11 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); ** unpredictable and might not equal either the old or the new ** last insert [rowid]. */ -SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*); /* ** CAPI3REF: Count The Number Of Rows Modified +** METHOD: sqlite3 ** ** ^This function returns the number of rows modified, inserted or ** deleted by the most recently completed INSERT, UPDATE or DELETE @@ -1962,10 +1989,11 @@ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); ** while [sqlite3_changes()] is running then the value returned ** is unpredictable and not meaningful. */ -SQLITE_API int sqlite3_changes(sqlite3*); +SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*); /* ** CAPI3REF: Total Number Of Rows Modified +** METHOD: sqlite3 ** ** ^This function returns the total number of rows inserted, modified or ** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed @@ -1985,10 +2013,11 @@ SQLITE_API int sqlite3_changes(sqlite3*); ** while [sqlite3_total_changes()] is running then the value ** returned is unpredictable and not meaningful. */ -SQLITE_API int sqlite3_total_changes(sqlite3*); +SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*); /* ** CAPI3REF: Interrupt A Long-Running Query +** METHOD: sqlite3 ** ** ^This function causes any pending database operation to abort and ** return at its earliest opportunity. This routine is typically @@ -2024,7 +2053,7 @@ SQLITE_API int sqlite3_total_changes(sqlite3*); ** If the database connection closes while [sqlite3_interrupt()] ** is running then bad things will likely happen. */ -SQLITE_API void sqlite3_interrupt(sqlite3*); +SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*); /* ** CAPI3REF: Determine If An SQL Statement Is Complete @@ -2059,12 +2088,13 @@ SQLITE_API void sqlite3_interrupt(sqlite3*); ** The input to [sqlite3_complete16()] must be a zero-terminated ** UTF-16 string in native byte order. */ -SQLITE_API int sqlite3_complete(const char *sql); -SQLITE_API int sqlite3_complete16(const void *sql); +SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql); +SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql); /* ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors ** KEYWORDS: {busy-handler callback} {busy handler} +** METHOD: sqlite3 ** ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X ** that might be invoked with argument P whenever @@ -2120,10 +2150,11 @@ SQLITE_API int sqlite3_complete16(const void *sql); ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ -SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); +SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); /* ** CAPI3REF: Set A Busy Timeout +** METHOD: sqlite3 ** ** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps ** for a specified amount of time when a table is locked. ^The handler @@ -2142,10 +2173,11 @@ SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); ** ** See also: [PRAGMA busy_timeout] */ -SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); +SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms); /* ** CAPI3REF: Convenience Routines For Running Queries +** METHOD: sqlite3 ** ** This is a legacy interface that is preserved for backwards compatibility. ** Use of this interface is not recommended. @@ -2216,7 +2248,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); ** reflected in subsequent calls to [sqlite3_errcode()] or ** [sqlite3_errmsg()]. */ -SQLITE_API int sqlite3_get_table( +SQLITE_API int SQLITE_STDCALL sqlite3_get_table( sqlite3 *db, /* An open database */ const char *zSql, /* SQL to be evaluated */ char ***pazResult, /* Results of the query */ @@ -2224,13 +2256,17 @@ SQLITE_API int sqlite3_get_table( int *pnColumn, /* Number of result columns written here */ char **pzErrmsg /* Error msg written here */ ); -SQLITE_API void sqlite3_free_table(char **result); +SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result); /* ** CAPI3REF: Formatted String Printing Functions ** ** These routines are work-alikes of the "printf()" family of functions ** from the standard C library. +** These routines understand most of the common K&R formatting options, +** plus some additional non-standard formats, detailed below. +** Note that some of the more obscure formatting options from recent +** C-library standards are omitted from this implementation. ** ** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their ** results into memory obtained from [sqlite3_malloc()]. @@ -2263,7 +2299,7 @@ SQLITE_API void sqlite3_free_table(char **result); ** These routines all implement some additional formatting ** options that are useful for constructing SQL statements. ** All of the usual printf() formatting options apply. In addition, there -** is are "%q", "%Q", and "%z" options. +** is are "%q", "%Q", "%w" and "%z" options. ** ** ^(The %q option works like %s in that it substitutes a nul-terminated ** string from the argument list. But %q also doubles every '\'' character. @@ -2316,14 +2352,20 @@ SQLITE_API void sqlite3_free_table(char **result); ** The code above will render a correct SQL statement in the zSQL ** variable even if the zText variable is a NULL pointer. ** +** ^(The "%w" formatting option is like "%q" except that it expects to +** be contained within double-quotes instead of single quotes, and it +** escapes the double-quote character instead of the single-quote +** character.)^ The "%w" formatting option is intended for safely inserting +** table and column names into a constructed SQL statement. +** ** ^(The "%z" formatting option works like "%s" but with the ** addition that after the string has been read and copied into ** the result, [sqlite3_free()] is called on the input string.)^ */ -SQLITE_API char *sqlite3_mprintf(const char*,...); -SQLITE_API char *sqlite3_vmprintf(const char*, va_list); -SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...); -SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list); +SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...); +SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list); +SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...); +SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list); /* ** CAPI3REF: Memory Allocation Subsystem @@ -2413,12 +2455,12 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list); ** a block of memory after it has been released using ** [sqlite3_free()] or [sqlite3_realloc()]. */ -SQLITE_API void *sqlite3_malloc(int); -SQLITE_API void *sqlite3_malloc64(sqlite3_uint64); -SQLITE_API void *sqlite3_realloc(void*, int); -SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64); -SQLITE_API void sqlite3_free(void*); -SQLITE_API sqlite3_uint64 sqlite3_msize(void*); +SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int); +SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64); +SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int); +SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64); +SQLITE_API void SQLITE_STDCALL sqlite3_free(void*); +SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*); /* ** CAPI3REF: Memory Allocator Statistics @@ -2443,8 +2485,8 @@ SQLITE_API sqlite3_uint64 sqlite3_msize(void*); ** by [sqlite3_memory_highwater(1)] is the high-water mark ** prior to the reset. */ -SQLITE_API sqlite3_int64 sqlite3_memory_used(void); -SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag); /* ** CAPI3REF: Pseudo-Random Number Generator @@ -2467,10 +2509,11 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); ** internally and without recourse to the [sqlite3_vfs] xRandomness ** method. */ -SQLITE_API void sqlite3_randomness(int N, void *P); +SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P); /* ** CAPI3REF: Compile-Time Authorization Callbacks +** METHOD: sqlite3 ** ** ^This routine registers an authorizer callback with a particular ** [database connection], supplied in the first argument. @@ -2549,7 +2592,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** as stated in the previous paragraph, sqlite3_step() invokes ** sqlite3_prepare_v2() to reprepare a statement after a schema change. */ -SQLITE_API int sqlite3_set_authorizer( +SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer( sqlite3*, int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), void *pUserData @@ -2627,6 +2670,7 @@ SQLITE_API int sqlite3_set_authorizer( /* ** CAPI3REF: Tracing And Profiling Functions +** METHOD: sqlite3 ** ** These routines register callback functions that can be used for ** tracing and profiling the execution of SQL statements. @@ -2653,12 +2697,13 @@ SQLITE_API int sqlite3_set_authorizer( ** sqlite3_profile() function is considered experimental and is ** subject to change in future versions of SQLite. */ -SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); -SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, +SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_profile(sqlite3*, void(*xProfile)(void*,const char*,sqlite3_uint64), void*); /* ** CAPI3REF: Query Progress Callbacks +** METHOD: sqlite3 ** ** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback ** function X to be invoked periodically during long running calls to @@ -2688,10 +2733,11 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, ** database connections for the meaning of "modify" in this paragraph. ** */ -SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); +SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection +** CONSTRUCTOR: sqlite3 ** ** ^These routines open an SQLite database file as specified by the ** filename argument. ^The filename argument is interpreted as UTF-8 for @@ -2916,15 +2962,15 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** ** See also: [sqlite3_temp_directory] */ -SQLITE_API int sqlite3_open( +SQLITE_API int SQLITE_STDCALL sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */ ); -SQLITE_API int sqlite3_open16( +SQLITE_API int SQLITE_STDCALL sqlite3_open16( const void *filename, /* Database filename (UTF-16) */ sqlite3 **ppDb /* OUT: SQLite db handle */ ); -SQLITE_API int sqlite3_open_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_open_v2( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb, /* OUT: SQLite db handle */ int flags, /* Flags */ @@ -2970,19 +3016,22 @@ SQLITE_API int sqlite3_open_v2( ** VFS method, then the behavior of this routine is undefined and probably ** undesirable. */ -SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); -SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); -SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); +SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam); +SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const char*, sqlite3_int64); /* ** CAPI3REF: Error Codes And Messages -** -** ^The sqlite3_errcode() interface returns the numeric [result code] or -** [extended result code] for the most recent failed sqlite3_* API call -** associated with a [database connection]. If a prior API call failed -** but the most recent API call succeeded, the return value from -** sqlite3_errcode() is undefined. ^The sqlite3_extended_errcode() +** METHOD: sqlite3 +** +** ^If the most recent sqlite3_* API call associated with +** [database connection] D failed, then the sqlite3_errcode(D) interface +** returns the numeric [result code] or [extended result code] for that +** API call. +** If the most recent API call was successful, +** then the return value from sqlite3_errcode() is undefined. +** ^The sqlite3_extended_errcode() ** interface is the same except that it always returns the ** [extended result code] even when extended result codes are ** disabled. @@ -3013,40 +3062,41 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int ** was invoked incorrectly by the application. In that case, the ** error code and message may or may not be set. */ -SQLITE_API int sqlite3_errcode(sqlite3 *db); -SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); -SQLITE_API const char *sqlite3_errmsg(sqlite3*); -SQLITE_API const void *sqlite3_errmsg16(sqlite3*); -SQLITE_API const char *sqlite3_errstr(int); +SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db); +SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db); +SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*); +SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int); /* -** CAPI3REF: SQL Statement Object +** CAPI3REF: Prepared Statement Object ** KEYWORDS: {prepared statement} {prepared statements} ** -** An instance of this object represents a single SQL statement. -** This object is variously known as a "prepared statement" or a -** "compiled SQL statement" or simply as a "statement". +** An instance of this object represents a single SQL statement that +** has been compiled into binary form and is ready to be evaluated. ** -** The life of a statement object goes something like this: +** Think of each SQL statement as a separate computer program. The +** original SQL text is source code. A prepared statement object +** is the compiled object code. All SQL must be converted into a +** prepared statement before it can be run. +** +** The life-cycle of a prepared statement object usually goes like this: ** ** <ol> -** <li> Create the object using [sqlite3_prepare_v2()] or a related -** function. -** <li> Bind values to [host parameters] using the sqlite3_bind_*() +** <li> Create the prepared statement object using [sqlite3_prepare_v2()]. +** <li> Bind values to [parameters] using the sqlite3_bind_*() ** interfaces. ** <li> Run the SQL by calling [sqlite3_step()] one or more times. -** <li> Reset the statement using [sqlite3_reset()] then go back +** <li> Reset the prepared statement using [sqlite3_reset()] then go back ** to step 2. Do this zero or more times. ** <li> Destroy the object using [sqlite3_finalize()]. ** </ol> -** -** Refer to documentation on individual methods above for additional -** information. */ typedef struct sqlite3_stmt sqlite3_stmt; /* ** CAPI3REF: Run-time Limits +** METHOD: sqlite3 ** ** ^(This interface allows the size of various constructs to be limited ** on a connection by connection basis. The first parameter is the @@ -3084,7 +3134,7 @@ typedef struct sqlite3_stmt sqlite3_stmt; ** ** New run-time limit categories may be added in future releases. */ -SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); +SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal); /* ** CAPI3REF: Run-Time Limit Categories @@ -3158,6 +3208,8 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); /* ** CAPI3REF: Compiling An SQL Statement ** KEYWORDS: {SQL statement compiler} +** METHOD: sqlite3 +** CONSTRUCTOR: sqlite3_stmt ** ** To execute an SQL query, it must first be compiled into a byte-code ** program using one of these routines. @@ -3171,16 +3223,14 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2() ** use UTF-16. ** -** ^If the nByte argument is less than zero, then zSql is read up to the -** first zero terminator. ^If nByte is non-negative, then it is the maximum -** number of bytes read from zSql. ^When nByte is non-negative, the -** zSql string ends at either the first '\000' or '\u0000' character or -** the nByte-th byte, whichever comes first. If the caller knows -** that the supplied string is nul-terminated, then there is a small -** performance advantage to be gained by passing an nByte parameter that -** is equal to the number of bytes in the input string <i>including</i> -** the nul-terminator bytes as this saves SQLite from having to -** make a copy of the input string. +** ^If the nByte argument is negative, then zSql is read up to the +** first zero terminator. ^If nByte is positive, then it is the +** number of bytes read from zSql. ^If nByte is zero, then no prepared +** statement is generated. +** If the caller knows that the supplied string is nul-terminated, then +** there is a small performance advantage to passing an nByte parameter that +** is the number of bytes in the input string <i>including</i> +** the nul-terminator. ** ** ^If pzTail is not NULL then *pzTail is made to point to the first byte ** past the end of the first SQL statement in zSql. These routines only @@ -3236,28 +3286,28 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** </li> ** </ol> */ -SQLITE_API int sqlite3_prepare( +SQLITE_API int SQLITE_STDCALL sqlite3_prepare( sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); -SQLITE_API int sqlite3_prepare_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2( sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); -SQLITE_API int sqlite3_prepare16( +SQLITE_API int SQLITE_STDCALL sqlite3_prepare16( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); -SQLITE_API int sqlite3_prepare16_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ @@ -3267,15 +3317,17 @@ SQLITE_API int sqlite3_prepare16_v2( /* ** CAPI3REF: Retrieving Statement SQL +** METHOD: sqlite3_stmt ** ** ^This interface can be used to retrieve a saved copy of the original ** SQL text used to create a [prepared statement] if that statement was ** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. */ -SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); +SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt); /* ** CAPI3REF: Determine If An SQL Statement Writes The Database +** METHOD: sqlite3_stmt ** ** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if ** and only if the [prepared statement] X makes no direct changes to @@ -3303,10 +3355,11 @@ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); ** change the configuration of a database connection, they do not make ** changes to the content of the database files on disk. */ -SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt); /* ** CAPI3REF: Determine If A Prepared Statement Has Been Reset +** METHOD: sqlite3_stmt ** ** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the ** [prepared statement] S has been stepped at least once using @@ -3322,7 +3375,7 @@ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); ** for example, in diagnostic routines to search for prepared ** statements that are holding a transaction open. */ -SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*); /* ** CAPI3REF: Dynamically Typed Value Object @@ -3381,6 +3434,7 @@ typedef struct sqlite3_context sqlite3_context; ** CAPI3REF: Binding Values To Prepared Statements ** KEYWORDS: {host parameter} {host parameters} {host parameter name} ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} +** METHOD: sqlite3_stmt ** ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, ** literals may be replaced by a [parameter] that matches one of following @@ -3483,22 +3537,23 @@ typedef struct sqlite3_context sqlite3_context; ** See also: [sqlite3_bind_parameter_count()], ** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. */ -SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); -SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, +SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, void(*)(void*)); -SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double); -SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int); -SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); -SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int); -SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); -SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); -SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, +SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, void(*)(void*), unsigned char encoding); -SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); -SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); /* ** CAPI3REF: Number Of SQL Parameters +** METHOD: sqlite3_stmt ** ** ^This routine can be used to find the number of [SQL parameters] ** in a [prepared statement]. SQL parameters are tokens of the @@ -3515,10 +3570,11 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); ** [sqlite3_bind_parameter_name()], and ** [sqlite3_bind_parameter_index()]. */ -SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*); /* ** CAPI3REF: Name Of A Host Parameter +** METHOD: sqlite3_stmt ** ** ^The sqlite3_bind_parameter_name(P,N) interface returns ** the name of the N-th [SQL parameter] in the [prepared statement] P. @@ -3542,10 +3598,11 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); ** [sqlite3_bind_parameter_count()], and ** [sqlite3_bind_parameter_index()]. */ -SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); +SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int); /* ** CAPI3REF: Index Of A Parameter With A Given Name +** METHOD: sqlite3_stmt ** ** ^Return the index of an SQL parameter given its name. ^The ** index value returned is suitable for use as the second @@ -3558,19 +3615,21 @@ SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); ** [sqlite3_bind_parameter_count()], and ** [sqlite3_bind_parameter_index()]. */ -SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); /* ** CAPI3REF: Reset All Bindings On A Prepared Statement +** METHOD: sqlite3_stmt ** ** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset ** the [sqlite3_bind_blob | bindings] on a [prepared statement]. ** ^Use this routine to reset all host parameters to NULL. */ -SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); +SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*); /* ** CAPI3REF: Number Of Columns In A Result Set +** METHOD: sqlite3_stmt ** ** ^Return the number of columns in the result set returned by the ** [prepared statement]. ^This routine returns 0 if pStmt is an SQL @@ -3578,10 +3637,11 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); ** ** See also: [sqlite3_data_count()] */ -SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); +SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt); /* ** CAPI3REF: Column Names In A Result Set +** METHOD: sqlite3_stmt ** ** ^These routines return the name assigned to a particular column ** in the result set of a [SELECT] statement. ^The sqlite3_column_name() @@ -3606,11 +3666,12 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); ** then the name of the column is unspecified and may change from ** one release of SQLite to the next. */ -SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N); -SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N); /* ** CAPI3REF: Source Of Data In A Query Result +** METHOD: sqlite3_stmt ** ** ^These routines provide a means to determine the database, table, and ** table column that is the origin of a particular result column in @@ -3654,15 +3715,16 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); ** for the same [prepared statement] and result column ** at the same time then the results are undefined. */ -SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int); -SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int); -SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int); -SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int); -SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int); -SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int); +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int); +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int); /* ** CAPI3REF: Declared Datatype Of A Query Result +** METHOD: sqlite3_stmt ** ** ^(The first parameter is a [prepared statement]. ** If this statement is a [SELECT] statement and the Nth column of the @@ -3690,11 +3752,12 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); ** is associated with individual values, not with the containers ** used to hold those values. */ -SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int); -SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int); /* ** CAPI3REF: Evaluate An SQL Statement +** METHOD: sqlite3_stmt ** ** After a [prepared statement] has been prepared using either ** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy @@ -3770,10 +3833,11 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** then the more specific [error codes] are returned directly ** by sqlite3_step(). The use of the "v2" interface is recommended. */ -SQLITE_API int sqlite3_step(sqlite3_stmt*); +SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*); /* ** CAPI3REF: Number of columns in a result set +** METHOD: sqlite3_stmt ** ** ^The sqlite3_data_count(P) interface returns the number of columns in the ** current row of the result set of [prepared statement] P. @@ -3790,7 +3854,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt*); ** ** See also: [sqlite3_column_count()] */ -SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); +SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt); /* ** CAPI3REF: Fundamental Datatypes @@ -3827,6 +3891,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); /* ** CAPI3REF: Result Values From A Query ** KEYWORDS: {column access functions} +** METHOD: sqlite3_stmt ** ** These routines form the "result set" interface. ** @@ -3986,19 +4051,20 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** pointer. Subsequent calls to [sqlite3_errcode()] will return ** [SQLITE_NOMEM].)^ */ -SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); -SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); -SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); -SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); -SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); -SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol); +SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol); /* ** CAPI3REF: Destroy A Prepared Statement Object +** DESTRUCTOR: sqlite3_stmt ** ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. ** ^If the most recent evaluation of the statement encountered no errors @@ -4022,10 +4088,11 @@ SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); ** statement after it has been finalized can result in undefined and ** undesirable behavior such as segfaults and heap corruption. */ -SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); +SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt); /* ** CAPI3REF: Reset A Prepared Statement Object +** METHOD: sqlite3_stmt ** ** The sqlite3_reset() function is called to reset a [prepared statement] ** object back to its initial state, ready to be re-executed. @@ -4048,13 +4115,14 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); ** ^The [sqlite3_reset(S)] interface does not change the values ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. */ -SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); +SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt); /* ** CAPI3REF: Create Or Redefine SQL Functions ** KEYWORDS: {function creation routines} ** KEYWORDS: {application-defined SQL function} ** KEYWORDS: {application-defined SQL functions} +** METHOD: sqlite3 ** ** ^These functions (collectively known as "function creation routines") ** are used to add SQL functions or aggregates or to redefine the behavior @@ -4147,7 +4215,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** close the database connection nor finalize or reset the prepared ** statement in which the function is running. */ -SQLITE_API int sqlite3_create_function( +SQLITE_API int SQLITE_STDCALL sqlite3_create_function( sqlite3 *db, const char *zFunctionName, int nArg, @@ -4157,7 +4225,7 @@ SQLITE_API int sqlite3_create_function( void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); -SQLITE_API int sqlite3_create_function16( +SQLITE_API int SQLITE_STDCALL sqlite3_create_function16( sqlite3 *db, const void *zFunctionName, int nArg, @@ -4167,7 +4235,7 @@ SQLITE_API int sqlite3_create_function16( void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); -SQLITE_API int sqlite3_create_function_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2( sqlite3 *db, const char *zFunctionName, int nArg, @@ -4209,21 +4277,22 @@ SQLITE_API int sqlite3_create_function_v2( ** These functions are [deprecated]. In order to maintain ** backwards compatibility with older code, these functions continue ** to be supported. However, new applications should avoid -** the use of these functions. To help encourage people to avoid -** using these functions, we are not going to tell you what they do. +** the use of these functions. To encourage programmers to avoid +** these functions, we will not explain what they do. */ #ifndef SQLITE_OMIT_DEPRECATED -SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*); -SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); -SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); -SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void); -SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); -SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void); +SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), void*,sqlite3_int64); #endif /* ** CAPI3REF: Obtaining SQL Function Parameter Values +** METHOD: sqlite3_value ** ** The C-language implementation of SQL functions and aggregates uses ** this set of interface routines to access the parameter values on @@ -4267,21 +4336,22 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 ** These routines must be called from the same thread as ** the SQL function that supplied the [sqlite3_value*] parameters. */ -SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); -SQLITE_API int sqlite3_value_bytes(sqlite3_value*); -SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); -SQLITE_API double sqlite3_value_double(sqlite3_value*); -SQLITE_API int sqlite3_value_int(sqlite3_value*); -SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); -SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); -SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); -SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); -SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); -SQLITE_API int sqlite3_value_type(sqlite3_value*); -SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*); +SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*); +SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*); /* ** CAPI3REF: Obtain Aggregate Function Context +** METHOD: sqlite3_context ** ** Implementations of aggregate SQL functions use this ** routine to allocate memory for storing their state. @@ -4322,10 +4392,11 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); ** This routine must be called from the same thread in which ** the aggregate SQL function is running. */ -SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); +SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes); /* ** CAPI3REF: User Data For Functions +** METHOD: sqlite3_context ** ** ^The sqlite3_user_data() interface returns a copy of ** the pointer that was the pUserData parameter (the 5th parameter) @@ -4336,10 +4407,11 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); ** This routine must be called from the same thread in which ** the application-defined function is running. */ -SQLITE_API void *sqlite3_user_data(sqlite3_context*); +SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*); /* ** CAPI3REF: Database Connection For Functions +** METHOD: sqlite3_context ** ** ^The sqlite3_context_db_handle() interface returns a copy of ** the pointer to the [database connection] (the 1st parameter) @@ -4347,10 +4419,11 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context*); ** and [sqlite3_create_function16()] routines that originally ** registered the application defined function. */ -SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); +SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*); /* ** CAPI3REF: Function Auxiliary Data +** METHOD: sqlite3_context ** ** These functions may be used by (non-aggregate) SQL functions to ** associate metadata with argument values. If the same value is passed to @@ -4399,8 +4472,8 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** These routines must be called from the same thread in which ** the SQL function is running. */ -SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); -SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); +SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N); +SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); /* @@ -4423,6 +4496,7 @@ typedef void (*sqlite3_destructor_type)(void*); /* ** CAPI3REF: Setting The Result Of An SQL Function +** METHOD: sqlite3_context ** ** These routines are used by the xFunc or xFinal callbacks that ** implement SQL functions and aggregates. See @@ -4535,29 +4609,30 @@ typedef void (*sqlite3_destructor_type)(void*); ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. */ -SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); -SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*, +SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*, sqlite3_uint64,void(*)(void*)); -SQLITE_API void sqlite3_result_double(sqlite3_context*, double); -SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); -SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); -SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); -SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); -SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int); -SQLITE_API void sqlite3_result_int(sqlite3_context*, int); -SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); -SQLITE_API void sqlite3_result_null(sqlite3_context*); -SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); -SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, +SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, void(*)(void*), unsigned char encoding); -SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); -SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); -SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); -SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); -SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n); /* ** CAPI3REF: Define New Collating Sequences +** METHOD: sqlite3 ** ** ^These functions add, remove, or modify a [collation] associated ** with the [database connection] specified as the first argument. @@ -4635,14 +4710,14 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); ** ** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. */ -SQLITE_API int sqlite3_create_collation( +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation( sqlite3*, const char *zName, int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*) ); -SQLITE_API int sqlite3_create_collation_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2( sqlite3*, const char *zName, int eTextRep, @@ -4650,7 +4725,7 @@ SQLITE_API int sqlite3_create_collation_v2( int(*xCompare)(void*,int,const void*,int,const void*), void(*xDestroy)(void*) ); -SQLITE_API int sqlite3_create_collation16( +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16( sqlite3*, const void *zName, int eTextRep, @@ -4660,6 +4735,7 @@ SQLITE_API int sqlite3_create_collation16( /* ** CAPI3REF: Collation Needed Callbacks +** METHOD: sqlite3 ** ** ^To avoid having to register all collation sequences before a database ** can be used, a single callback function may be registered with the @@ -4684,12 +4760,12 @@ SQLITE_API int sqlite3_create_collation16( ** [sqlite3_create_collation()], [sqlite3_create_collation16()], or ** [sqlite3_create_collation_v2()]. */ -SQLITE_API int sqlite3_collation_needed( +SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed( sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const char*) ); -SQLITE_API int sqlite3_collation_needed16( +SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16( sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const void*) @@ -4703,11 +4779,11 @@ SQLITE_API int sqlite3_collation_needed16( ** The code to implement this API is not available in the public release ** of SQLite. */ -SQLITE_API int sqlite3_key( +SQLITE_API int SQLITE_STDCALL sqlite3_key( sqlite3 *db, /* Database to be rekeyed */ const void *pKey, int nKey /* The key */ ); -SQLITE_API int sqlite3_key_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_key_v2( sqlite3 *db, /* Database to be rekeyed */ const char *zDbName, /* Name of the database */ const void *pKey, int nKey /* The key */ @@ -4721,11 +4797,11 @@ SQLITE_API int sqlite3_key_v2( ** The code to implement this API is not available in the public release ** of SQLite. */ -SQLITE_API int sqlite3_rekey( +SQLITE_API int SQLITE_STDCALL sqlite3_rekey( sqlite3 *db, /* Database to be rekeyed */ const void *pKey, int nKey /* The new key */ ); -SQLITE_API int sqlite3_rekey_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2( sqlite3 *db, /* Database to be rekeyed */ const char *zDbName, /* Name of the database */ const void *pKey, int nKey /* The new key */ @@ -4735,7 +4811,7 @@ SQLITE_API int sqlite3_rekey_v2( ** Specify the activation key for a SEE database. Unless ** activated, none of the SEE routines will work. */ -SQLITE_API void sqlite3_activate_see( +SQLITE_API void SQLITE_STDCALL sqlite3_activate_see( const char *zPassPhrase /* Activation phrase */ ); #endif @@ -4745,7 +4821,7 @@ SQLITE_API void sqlite3_activate_see( ** Specify the activation key for a CEROD database. Unless ** activated, none of the CEROD routines will work. */ -SQLITE_API void sqlite3_activate_cerod( +SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod( const char *zPassPhrase /* Activation phrase */ ); #endif @@ -4767,7 +4843,7 @@ SQLITE_API void sqlite3_activate_cerod( ** all, then the behavior of sqlite3_sleep() may deviate from the description ** in the previous paragraphs. */ -SQLITE_API int sqlite3_sleep(int); +SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int); /* ** CAPI3REF: Name Of The Folder Holding Temporary Files @@ -4867,6 +4943,7 @@ SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory; /* ** CAPI3REF: Test For Auto-Commit Mode ** KEYWORDS: {autocommit mode} +** METHOD: sqlite3 ** ** ^The sqlite3_get_autocommit() interface returns non-zero or ** zero if the given database connection is or is not in autocommit mode, @@ -4885,10 +4962,11 @@ SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory; ** connection while this routine is running, then the return value ** is undefined. */ -SQLITE_API int sqlite3_get_autocommit(sqlite3*); +SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*); /* ** CAPI3REF: Find The Database Handle Of A Prepared Statement +** METHOD: sqlite3_stmt ** ** ^The sqlite3_db_handle interface returns the [database connection] handle ** to which a [prepared statement] belongs. ^The [database connection] @@ -4897,10 +4975,11 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3*); ** to the [sqlite3_prepare_v2()] call (or its variants) that was used to ** create the statement in the first place. */ -SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); +SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*); /* ** CAPI3REF: Return The Filename For A Database Connection +** METHOD: sqlite3 ** ** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename ** associated with database N of connection D. ^The main database file @@ -4913,19 +4992,21 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); ** will be an absolute pathname, even if the filename used ** to open the database originally was a URI or relative pathname. */ -SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); +SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName); /* ** CAPI3REF: Determine if a database is read-only +** METHOD: sqlite3 ** ** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N ** of connection D is read-only, 0 if it is read/write, or -1 if N is not ** the name of a database on connection D. */ -SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); +SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName); /* ** CAPI3REF: Find the next prepared statement +** METHOD: sqlite3 ** ** ^This interface returns a pointer to the next [prepared statement] after ** pStmt associated with the [database connection] pDb. ^If pStmt is NULL @@ -4937,10 +5018,11 @@ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); ** [sqlite3_next_stmt(D,S)] must refer to an open database ** connection and in particular must not be a NULL pointer. */ -SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); +SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); /* ** CAPI3REF: Commit And Rollback Notification Callbacks +** METHOD: sqlite3 ** ** ^The sqlite3_commit_hook() interface registers a callback ** function to be invoked whenever a transaction is [COMMIT | committed]. @@ -4985,11 +5067,12 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); ** ** See also the [sqlite3_update_hook()] interface. */ -SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); -SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); +SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); /* ** CAPI3REF: Data Change Notification Callbacks +** METHOD: sqlite3 ** ** ^The sqlite3_update_hook() interface registers a callback function ** with the [database connection] identified by the first argument @@ -5036,7 +5119,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()] ** interfaces. */ -SQLITE_API void *sqlite3_update_hook( +SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook( sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* @@ -5066,12 +5149,17 @@ SQLITE_API void *sqlite3_update_hook( ** future releases of SQLite. Applications that care about shared ** cache setting should set it explicitly. ** +** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0 +** and will always return SQLITE_MISUSE. On those systems, +** shared cache mode should be enabled per-database connection via +** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. +** ** This interface is threadsafe on processors where writing a ** 32-bit integer is atomic. ** ** See Also: [SQLite Shared-Cache Mode] */ -SQLITE_API int sqlite3_enable_shared_cache(int); +SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int); /* ** CAPI3REF: Attempt To Free Heap Memory @@ -5087,10 +5175,11 @@ SQLITE_API int sqlite3_enable_shared_cache(int); ** ** See also: [sqlite3_db_release_memory()] */ -SQLITE_API int sqlite3_release_memory(int); +SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int); /* ** CAPI3REF: Free Memory Used By A Database Connection +** METHOD: sqlite3 ** ** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap ** memory as possible from database connection D. Unlike the @@ -5100,7 +5189,7 @@ SQLITE_API int sqlite3_release_memory(int); ** ** See also: [sqlite3_release_memory()] */ -SQLITE_API int sqlite3_db_release_memory(sqlite3*); +SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*); /* ** CAPI3REF: Impose A Limit On Heap Size @@ -5152,7 +5241,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); ** The circumstances under which SQLite will enforce the soft heap limit may ** changes in future releases of SQLite. */ -SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N); /* ** CAPI3REF: Deprecated Soft Heap Limit Interface @@ -5163,11 +5252,12 @@ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); ** only. All new applications should use the ** [sqlite3_soft_heap_limit64()] interface rather than this one. */ -SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); +SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N); /* ** CAPI3REF: Extract Metadata About A Column Of A Table +** METHOD: sqlite3 ** ** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns ** information about column C of table T in database D @@ -5232,7 +5322,7 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); ** parsed, if that has not already been done, and returns an error if ** any errors are encountered while loading the schema. */ -SQLITE_API int sqlite3_table_column_metadata( +SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata( sqlite3 *db, /* Connection handle */ const char *zDbName, /* Database name or NULL */ const char *zTableName, /* Table name */ @@ -5246,6 +5336,7 @@ SQLITE_API int sqlite3_table_column_metadata( /* ** CAPI3REF: Load An Extension +** METHOD: sqlite3 ** ** ^This interface loads an SQLite extension library from the named file. ** @@ -5278,7 +5369,7 @@ SQLITE_API int sqlite3_table_column_metadata( ** ** See also the [load_extension() SQL function]. */ -SQLITE_API int sqlite3_load_extension( +SQLITE_API int SQLITE_STDCALL sqlite3_load_extension( sqlite3 *db, /* Load the extension into this database connection */ const char *zFile, /* Name of the shared library containing extension */ const char *zProc, /* Entry point. Derived from zFile if 0 */ @@ -5287,6 +5378,7 @@ SQLITE_API int sqlite3_load_extension( /* ** CAPI3REF: Enable Or Disable Extension Loading +** METHOD: sqlite3 ** ** ^So as not to open security holes in older applications that are ** unprepared to deal with [extension loading], and as a means of disabling @@ -5298,7 +5390,7 @@ SQLITE_API int sqlite3_load_extension( ** to turn extension loading on and call it with onoff==0 to turn ** it back off again. */ -SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); +SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff); /* ** CAPI3REF: Automatically Load Statically Linked Extensions @@ -5336,7 +5428,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); ** See also: [sqlite3_reset_auto_extension()] ** and [sqlite3_cancel_auto_extension()] */ -SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void)); +SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xEntryPoint)(void)); /* ** CAPI3REF: Cancel Automatic Extension Loading @@ -5348,7 +5440,7 @@ SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void)); ** unregistered and it returns 0 if X was not on the list of initialization ** routines. */ -SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void)); +SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xEntryPoint)(void)); /* ** CAPI3REF: Reset Automatic Extension Loading @@ -5356,7 +5448,7 @@ SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void)); ** ^This interface disables all automatic extensions previously ** registered using [sqlite3_auto_extension()]. */ -SQLITE_API void sqlite3_reset_auto_extension(void); +SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void); /* ** The interface to the virtual-table mechanism is currently considered @@ -5536,6 +5628,7 @@ struct sqlite3_index_info { /* ** CAPI3REF: Register A Virtual Table Implementation +** METHOD: sqlite3 ** ** ^These routines are used to register a new [virtual table module] name. ** ^Module names must be registered before @@ -5559,13 +5652,13 @@ struct sqlite3_index_info { ** interface is equivalent to sqlite3_create_module_v2() with a NULL ** destructor. */ -SQLITE_API int sqlite3_create_module( +SQLITE_API int SQLITE_STDCALL sqlite3_create_module( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ void *pClientData /* Client data for xCreate/xConnect */ ); -SQLITE_API int sqlite3_create_module_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ @@ -5593,7 +5686,7 @@ SQLITE_API int sqlite3_create_module_v2( */ struct sqlite3_vtab { const sqlite3_module *pModule; /* The module for this virtual table */ - int nRef; /* NO LONGER USED */ + int nRef; /* Number of open cursors */ char *zErrMsg; /* Error message from sqlite3_mprintf() */ /* Virtual table implementations will typically add additional fields */ }; @@ -5628,10 +5721,11 @@ struct sqlite3_vtab_cursor { ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. */ -SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); +SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL); /* ** CAPI3REF: Overload A Function For A Virtual Table +** METHOD: sqlite3 ** ** ^(Virtual tables can provide alternative implementations of functions ** using the [xFindFunction] method of the [virtual table module]. @@ -5646,7 +5740,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); ** purpose is to be a placeholder function that can be overloaded ** by a [virtual table]. */ -SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); +SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); /* ** The interface to the virtual-table mechanism defined above (back up @@ -5674,6 +5768,8 @@ typedef struct sqlite3_blob sqlite3_blob; /* ** CAPI3REF: Open A BLOB For Incremental I/O +** METHOD: sqlite3 +** CONSTRUCTOR: sqlite3_blob ** ** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located ** in row iRow, column zColumn, table zTable in database zDb; @@ -5743,7 +5839,7 @@ typedef struct sqlite3_blob sqlite3_blob; ** To avoid a resource leak, every open [BLOB handle] should eventually ** be released by a call to [sqlite3_blob_close()]. */ -SQLITE_API int sqlite3_blob_open( +SQLITE_API int SQLITE_STDCALL sqlite3_blob_open( sqlite3*, const char *zDb, const char *zTable, @@ -5755,6 +5851,7 @@ SQLITE_API int sqlite3_blob_open( /* ** CAPI3REF: Move a BLOB Handle to a New Row +** METHOD: sqlite3_blob ** ** ^This function is used to move an existing blob handle so that it points ** to a different row of the same database table. ^The new row is identified @@ -5775,10 +5872,11 @@ SQLITE_API int sqlite3_blob_open( ** ** ^This function sets the database handle error code and message. */ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); +SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); /* ** CAPI3REF: Close A BLOB Handle +** DESTRUCTOR: sqlite3_blob ** ** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed ** unconditionally. Even if this routine returns an error code, the @@ -5797,10 +5895,11 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_i ** is passed a valid open blob handle, the values returned by the ** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning. */ -SQLITE_API int sqlite3_blob_close(sqlite3_blob *); +SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *); /* ** CAPI3REF: Return The Size Of An Open BLOB +** METHOD: sqlite3_blob ** ** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The @@ -5812,10 +5911,11 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *); ** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. */ -SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); +SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *); /* ** CAPI3REF: Read Data From A BLOB Incrementally +** METHOD: sqlite3_blob ** ** ^(This function is used to read data from an open [BLOB handle] into a ** caller-supplied buffer. N bytes of data are copied into buffer Z @@ -5840,10 +5940,11 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); ** ** See also: [sqlite3_blob_write()]. */ -SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); +SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); /* ** CAPI3REF: Write Data Into A BLOB Incrementally +** METHOD: sqlite3_blob ** ** ^(This function is used to write data into an open [BLOB handle] from a ** caller-supplied buffer. N bytes of data are copied from the buffer Z @@ -5881,7 +5982,7 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); ** ** See also: [sqlite3_blob_read()]. */ -SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); +SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); /* ** CAPI3REF: Virtual File System Objects @@ -5912,9 +6013,9 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOff ** ^(If the default VFS is unregistered, another VFS is chosen as ** the default. The choice for the new VFS is arbitrary.)^ */ -SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); -SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); -SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); +SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName); +SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*); /* ** CAPI3REF: Mutexes @@ -6027,11 +6128,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. */ -SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int); -SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*); -SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*); -SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*); -SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); +SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int); +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*); +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*); +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*); +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*); /* ** CAPI3REF: Mutex Methods Object @@ -6141,8 +6242,8 @@ struct sqlite3_mutex_methods { ** interface should also return 1 when given a NULL pointer. */ #ifndef NDEBUG -SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); -SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*); +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*); #endif /* @@ -6171,6 +6272,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); /* ** CAPI3REF: Retrieve the mutex for a database connection +** METHOD: sqlite3 ** ** ^This interface returns a pointer the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument @@ -6178,10 +6280,11 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); ** ^If the [threading mode] is Single-thread or Multi-thread then this ** routine returns a NULL pointer. */ -SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); +SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*); /* ** CAPI3REF: Low-Level Control Of Database Files +** METHOD: sqlite3 ** ** ^The [sqlite3_file_control()] interface makes a direct call to the ** xFileControl method for the [sqlite3_io_methods] object associated @@ -6212,7 +6315,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); ** ** See also: [SQLITE_FCNTL_LOCKSTATE] */ -SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); +SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); /* ** CAPI3REF: Testing Interface @@ -6231,7 +6334,7 @@ SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void* ** Unlike most of the SQLite API, this function is not guaranteed to ** operate consistently from one release to the next. */ -SQLITE_API int sqlite3_test_control(int op, ...); +SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...); /* ** CAPI3REF: Testing Interface Operation Codes @@ -6265,12 +6368,13 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_BYTEORDER 22 #define SQLITE_TESTCTRL_ISINIT 23 #define SQLITE_TESTCTRL_SORTER_MMAP 24 -#define SQLITE_TESTCTRL_LAST 24 +#define SQLITE_TESTCTRL_IMPOSTER 25 +#define SQLITE_TESTCTRL_LAST 25 /* ** CAPI3REF: SQLite Runtime Status ** -** ^This interface is used to retrieve runtime status information +** ^These interfaces are used to retrieve runtime status information ** about the performance of SQLite, and optionally to reset various ** highwater marks. ^The first argument is an integer code for ** the specific parameter to measure. ^(Recognized integer codes @@ -6284,19 +6388,22 @@ SQLITE_API int sqlite3_test_control(int op, ...); ** ^(Other parameters record only the highwater mark and not the current ** value. For these latter parameters nothing is written into *pCurrent.)^ ** -** ^The sqlite3_status() routine returns SQLITE_OK on success and a -** non-zero [error code] on failure. +** ^The sqlite3_status() and sqlite3_status64() routines return +** SQLITE_OK on success and a non-zero [error code] on failure. ** -** This routine is threadsafe but is not atomic. This routine can be -** called while other threads are running the same or different SQLite -** interfaces. However the values returned in *pCurrent and -** *pHighwater reflect the status of SQLite at different points in time -** and it is possible that another thread might change the parameter -** in between the times when *pCurrent and *pHighwater are written. +** If either the current value or the highwater mark is too large to +** be represented by a 32-bit integer, then the values returned by +** sqlite3_status() are undefined. ** ** See also: [sqlite3_db_status()] */ -SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); +SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); +SQLITE_API int SQLITE_STDCALL sqlite3_status64( + int op, + sqlite3_int64 *pCurrent, + sqlite3_int64 *pHighwater, + int resetFlag +); /* @@ -6394,6 +6501,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF /* ** CAPI3REF: Database Connection Status +** METHOD: sqlite3 ** ** ^This interface is used to retrieve runtime status information ** about a single [database connection]. ^The first argument is the @@ -6414,7 +6522,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF ** ** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. */ -SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); +SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); /* ** CAPI3REF: Status Parameters for database connections @@ -6522,6 +6630,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r /* ** CAPI3REF: Prepared Statement Status +** METHOD: sqlite3_stmt ** ** ^(Each prepared statement maintains various ** [SQLITE_STMTSTATUS counters] that measure the number @@ -6543,7 +6652,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** ** See also: [sqlite3_status()] and [sqlite3_db_status()]. */ -SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); /* ** CAPI3REF: Status Parameters for prepared statements @@ -6966,20 +7075,20 @@ typedef struct sqlite3_backup sqlite3_backup; ** is not a permanent error and does not affect the return value of ** sqlite3_backup_finish(). ** -** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]] +** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]] ** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b> ** -** ^Each call to sqlite3_backup_step() sets two values inside -** the [sqlite3_backup] object: the number of pages still to be backed -** up and the total number of pages in the source database file. -** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces -** retrieve these two values, respectively. -** -** ^The values returned by these functions are only updated by -** sqlite3_backup_step(). ^If the source database is modified during a backup -** operation, then the values are not updated to account for any extra -** pages that need to be updated or the size of the source database file -** changing. +** ^The sqlite3_backup_remaining() routine returns the number of pages still +** to be backed up at the conclusion of the most recent sqlite3_backup_step(). +** ^The sqlite3_backup_pagecount() routine returns the total number of pages +** in the source database at the conclusion of the most recent +** sqlite3_backup_step(). +** ^(The values returned by these functions are only updated by +** sqlite3_backup_step(). If the source database is modified in a way that +** changes the size of the source database or the number of pages remaining, +** those changes are not reflected in the output of sqlite3_backup_pagecount() +** and sqlite3_backup_remaining() until after the next +** sqlite3_backup_step().)^ ** ** <b>Concurrent Usage of Database Handles</b> ** @@ -7012,19 +7121,20 @@ typedef struct sqlite3_backup sqlite3_backup; ** same time as another thread is invoking sqlite3_backup_step() it is ** possible that they return invalid values. */ -SQLITE_API sqlite3_backup *sqlite3_backup_init( +SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init( sqlite3 *pDest, /* Destination database handle */ const char *zDestName, /* Destination database name */ sqlite3 *pSource, /* Source database handle */ const char *zSourceName /* Source database name */ ); -SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage); -SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p); -SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p); -SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p); /* ** CAPI3REF: Unlock Notification +** METHOD: sqlite3 ** ** ^When running in shared-cache mode, a database operation may fail with ** an [SQLITE_LOCKED] error if the required locks on the shared-cache or @@ -7137,7 +7247,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** the special "DROP TABLE/INDEX" case, the extended error code is just ** SQLITE_LOCKED.)^ */ -SQLITE_API int sqlite3_unlock_notify( +SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify( sqlite3 *pBlocked, /* Waiting connection */ void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ void *pNotifyArg /* Argument to pass to xNotify */ @@ -7152,8 +7262,8 @@ SQLITE_API int sqlite3_unlock_notify( ** strings in a case-independent fashion, using the same definition of "case ** independence" that SQLite uses internally when comparing identifiers. */ -SQLITE_API int sqlite3_stricmp(const char *, const char *); -SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); +SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *); +SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int); /* ** CAPI3REF: String Globbing @@ -7168,7 +7278,7 @@ SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); ** Note that this routine returns zero on a match and non-zero if the strings ** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. */ -SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr); +SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr); /* ** CAPI3REF: Error Logging Interface @@ -7191,10 +7301,11 @@ SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr); ** a few hundred characters, it will be truncated to the length of the ** buffer. */ -SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); +SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...); /* ** CAPI3REF: Write-Ahead Log Commit Hook +** METHOD: sqlite3 ** ** ^The [sqlite3_wal_hook()] function is used to register a callback that ** is invoked each time data is committed to a database in wal mode. @@ -7226,7 +7337,7 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will ** those overwrite any prior [sqlite3_wal_hook()] settings. */ -SQLITE_API void *sqlite3_wal_hook( +SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook( sqlite3*, int(*)(void *,sqlite3*,const char*,int), void* @@ -7234,6 +7345,7 @@ SQLITE_API void *sqlite3_wal_hook( /* ** CAPI3REF: Configure an auto-checkpoint +** METHOD: sqlite3 ** ** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around ** [sqlite3_wal_hook()] that causes any database on [database connection] D @@ -7260,10 +7372,11 @@ SQLITE_API void *sqlite3_wal_hook( ** is only necessary if the default setting is found to be suboptimal ** for a particular application. */ -SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); +SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N); /* ** CAPI3REF: Checkpoint a database +** METHOD: sqlite3 ** ** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to ** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ @@ -7281,10 +7394,11 @@ SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); ** start a callback but which do not need the full power (and corresponding ** complication) of [sqlite3_wal_checkpoint_v2()]. */ -SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); +SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); /* ** CAPI3REF: Checkpoint a database +** METHOD: sqlite3 ** ** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint ** operation on database X of [database connection] D in mode M. Status @@ -7374,7 +7488,7 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); ** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface ** from SQL. */ -SQLITE_API int sqlite3_wal_checkpoint_v2( +SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2( sqlite3 *db, /* Database handle */ const char *zDb, /* Name of attached database (or NULL) */ int eMode, /* SQLITE_CHECKPOINT_* value */ @@ -7410,7 +7524,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( ** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options ** may be added in the future. */ -SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); +SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...); /* ** CAPI3REF: Virtual Table Configuration Options @@ -7463,7 +7577,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); ** of the SQL statement that triggered the call to the [xUpdate] method of the ** [virtual table]. */ -SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); +SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *); /* ** CAPI3REF: Conflict resolution modes @@ -7539,6 +7653,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); /* ** CAPI3REF: Prepared Statement Scan Status +** METHOD: sqlite3_stmt ** ** This interface returns information about the predicted and measured ** performance for pStmt. Advanced applications can use this @@ -7567,7 +7682,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); ** ** See also: [sqlite3_stmt_scanstatus_reset()] */ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus( +SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ @@ -7576,13 +7691,14 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus( /* ** CAPI3REF: Zero Scan-Status Counters +** METHOD: sqlite3_stmt ** ** ^Zero all [sqlite3_stmt_scanstatus()] related event counters. ** ** This API is only available if the library is built with pre-processor ** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined. */ -SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); +SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); /* @@ -7637,7 +7753,7 @@ typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ -SQLITE_API int sqlite3_rtree_geometry_callback( +SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback( sqlite3 *db, const char *zGeom, int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), @@ -7663,7 +7779,7 @@ struct sqlite3_rtree_geometry { ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...) */ -SQLITE_API int sqlite3_rtree_query_callback( +SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback( sqlite3 *db, const char *zQueryFunc, int (*xQueryFunc)(sqlite3_rtree_query_info*), diff --git a/src/3rdparty/zlib.pri b/src/3rdparty/zlib.pri index 868d1c71bb7f266d8b08f0eba6618ba22d28a850..363461220b66c7b969e906234adf88f8bcd2f188 100644 --- a/src/3rdparty/zlib.pri +++ b/src/3rdparty/zlib.pri @@ -1,4 +1,4 @@ -wince*: DEFINES += NO_ERRNO_H +wince: DEFINES += NO_ERRNO_H INCLUDEPATH = $$PWD/zlib $$INCLUDEPATH SOURCES+= \ $$PWD/zlib/adler32.c \ diff --git a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java index 56e7543415a518a1c6b1b8cee938c02ae855c44e..6f9567559759c19e290ee78d0084f95984de695d 100644 --- a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java +++ b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java @@ -107,10 +107,6 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate if (m_manager.isEnabled()) accServiceListener.onAccessibilityStateChanged(true); } - - - // Enable Qt Accessibility so that notifications are enabled - QtNativeAccessibility.setActive(true); } private class AccessibilityManagerListener implements AccessibilityManager.AccessibilityStateChangeListener @@ -119,8 +115,6 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate public void onAccessibilityStateChanged(boolean enabled) { if (enabled) { - // The accessibility code depends on android API level 16, so dynamically resolve it - if (android.os.Build.VERSION.SDK_INT >= 16) { try { View view = m_view; if (view == null) { @@ -147,13 +141,14 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate // Unknown exception means something went wrong. Log.w("Qt A11y", "Unknown exception: " + e.toString()); } - } } else { if (m_view != null) { m_layout.removeView(m_view); m_view = null; } } + + QtNativeAccessibility.setActive(enabled); } } diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index d6cd49f44c40a555751e94c1a5bbd3163c8b395d..f4d2645e9a76e295352afb59fd338c38cc9a2d19 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -794,7 +794,25 @@ public class QtActivityDelegate m_surfaces = new HashMap<Integer, QtSurface>(); m_nativeViews = new HashMap<Integer, View>(); m_activity.registerForContextMenu(m_layout); + m_activity.setContentView(m_layout, + new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + int orientation = m_activity.getResources().getConfiguration().orientation; + int rotation = m_activity.getWindowManager().getDefaultDisplay().getRotation(); + boolean rot90 = (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270); + boolean currentlyLandscape = (orientation == Configuration.ORIENTATION_LANDSCAPE); + if ((currentlyLandscape && !rot90) || (!currentlyLandscape && rot90)) + m_nativeOrientation = Configuration.ORIENTATION_LANDSCAPE; + else + m_nativeOrientation = Configuration.ORIENTATION_PORTRAIT; + + QtNative.handleOrientationChanged(rotation, m_nativeOrientation); + m_currentRotation = rotation; + } + + public void initializeAccessibility() + { // Initialize accessibility try { final String a11yDelegateClassName = "org.qtproject.qt5.android.accessibility.QtAccessibilityDelegate"; @@ -810,22 +828,6 @@ public class QtActivityDelegate // Unknown exception means something went wrong. Log.w("Qt A11y", "Unknown exception: " + e.toString()); } - - m_activity.setContentView(m_layout, - new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - - int orientation = m_activity.getResources().getConfiguration().orientation; - int rotation = m_activity.getWindowManager().getDefaultDisplay().getRotation(); - boolean rot90 = (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270); - boolean currentlyLandscape = (orientation == Configuration.ORIENTATION_LANDSCAPE); - if ((currentlyLandscape && !rot90) || (!currentlyLandscape && rot90)) - m_nativeOrientation = Configuration.ORIENTATION_LANDSCAPE; - else - m_nativeOrientation = Configuration.ORIENTATION_PORTRAIT; - - QtNative.handleOrientationChanged(rotation, m_nativeOrientation); - m_currentRotation = rotation; } public void onConfigurationChanged(Configuration configuration) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 80f7fb5c8551da729facfd3873a92b009732c405..5d7918ea54e53c0539a2ad3427104821ceafa729 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -589,6 +589,16 @@ public class QtNative }); } + private static void initializeAccessibility() + { + runAction(new Runnable() { + @Override + public void run() { + m_activityDelegate.initializeAccessibility(); + } + }); + } + // screen methods public static native void setDisplayMetrics(int screenWidthPixels, int screenHeightPixels, diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml index 60c612976f97dec23177bfae09c586340c323e00..ad240956ef48435c2143bc451aed6c84dedfa810 100644 --- a/src/android/templates/AndroidManifest.xml +++ b/src/android/templates/AndroidManifest.xml @@ -1,7 +1,7 @@ <?xml version='1.0' encoding='utf-8'?> <manifest package="org.qtproject.example" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto"> <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --"> - <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation" + <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="unspecified" diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h index da78341d90780e3a7c0bf2c31265ef46bc754051..7085a9fc5ec8915c06157f3d1c2674296deba41f 100644 --- a/src/corelib/animation/qabstractanimation.h +++ b/src/corelib/animation/qabstractanimation.h @@ -76,7 +76,7 @@ public: DeleteWhenStopped }; - QAbstractAnimation(QObject *parent = 0); + QAbstractAnimation(QObject *parent = Q_NULLPTR); virtual ~QAbstractAnimation(); State state() const; @@ -111,7 +111,7 @@ public Q_SLOTS: void setCurrentTime(int msecs); protected: - QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent = 0); + QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent = Q_NULLPTR); bool event(QEvent *event) Q_DECL_OVERRIDE; virtual void updateCurrentTime(int currentTime) = 0; @@ -130,7 +130,7 @@ class Q_CORE_EXPORT QAnimationDriver : public QObject Q_DECLARE_PRIVATE(QAnimationDriver) public: - QAnimationDriver(QObject *parent = 0); + QAnimationDriver(QObject *parent = Q_NULLPTR); ~QAnimationDriver(); virtual void advance(); @@ -156,7 +156,7 @@ protected: virtual void start(); virtual void stop(); - QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent = 0); + QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent = Q_NULLPTR); private: friend class QUnifiedTimer; diff --git a/src/corelib/animation/qanimationgroup.h b/src/corelib/animation/qanimationgroup.h index 9b180b1704ab226ebbcca1bb5e01501739d3776b..b668b503b4dabef9e4c79e41fd1a673c8b610025 100644 --- a/src/corelib/animation/qanimationgroup.h +++ b/src/corelib/animation/qanimationgroup.h @@ -47,7 +47,7 @@ class Q_CORE_EXPORT QAnimationGroup : public QAbstractAnimation Q_OBJECT public: - QAnimationGroup(QObject *parent = 0); + QAnimationGroup(QObject *parent = Q_NULLPTR); ~QAnimationGroup(); QAbstractAnimation *animationAt(int index) const; diff --git a/src/corelib/animation/qparallelanimationgroup.h b/src/corelib/animation/qparallelanimationgroup.h index 52a61dafcd0cc8c6a789235b81f85598597efbc8..7ce05d6344255d3637a3fef115a6de8b4b5a980d 100644 --- a/src/corelib/animation/qparallelanimationgroup.h +++ b/src/corelib/animation/qparallelanimationgroup.h @@ -47,7 +47,7 @@ class Q_CORE_EXPORT QParallelAnimationGroup : public QAnimationGroup Q_OBJECT public: - QParallelAnimationGroup(QObject *parent = 0); + QParallelAnimationGroup(QObject *parent = Q_NULLPTR); ~QParallelAnimationGroup(); int duration() const Q_DECL_OVERRIDE; diff --git a/src/corelib/animation/qpauseanimation.h b/src/corelib/animation/qpauseanimation.h index 159d82f9696730e48f1ba980d3ffd39fb9c69b50..520747262307d6a01dcc341848cd82d62271b18e 100644 --- a/src/corelib/animation/qpauseanimation.h +++ b/src/corelib/animation/qpauseanimation.h @@ -48,8 +48,8 @@ class Q_CORE_EXPORT QPauseAnimation : public QAbstractAnimation Q_OBJECT Q_PROPERTY(int duration READ duration WRITE setDuration) public: - QPauseAnimation(QObject *parent = 0); - QPauseAnimation(int msecs, QObject *parent = 0); + QPauseAnimation(QObject *parent = Q_NULLPTR); + QPauseAnimation(int msecs, QObject *parent = Q_NULLPTR); ~QPauseAnimation(); int duration() const Q_DECL_OVERRIDE; diff --git a/src/corelib/animation/qpropertyanimation.h b/src/corelib/animation/qpropertyanimation.h index 8d06a9f354a25c4e311d12e5da089158735e75ee..c0d30ba0fd527282a0b0ea2a58c779ec3f7bc7a3 100644 --- a/src/corelib/animation/qpropertyanimation.h +++ b/src/corelib/animation/qpropertyanimation.h @@ -49,8 +49,8 @@ class Q_CORE_EXPORT QPropertyAnimation : public QVariantAnimation Q_PROPERTY(QObject* targetObject READ targetObject WRITE setTargetObject) public: - QPropertyAnimation(QObject *parent = 0); - QPropertyAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = 0); + QPropertyAnimation(QObject *parent = Q_NULLPTR); + QPropertyAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = Q_NULLPTR); ~QPropertyAnimation(); QObject *targetObject() const; diff --git a/src/corelib/animation/qsequentialanimationgroup.h b/src/corelib/animation/qsequentialanimationgroup.h index 1a4ead90d400c6b3462b0cec63cf2d6c73c1d3f6..c8a84a122082a7985fc8ee1fa594e073b1d7fd63 100644 --- a/src/corelib/animation/qsequentialanimationgroup.h +++ b/src/corelib/animation/qsequentialanimationgroup.h @@ -50,7 +50,7 @@ class Q_CORE_EXPORT QSequentialAnimationGroup : public QAnimationGroup Q_PROPERTY(QAbstractAnimation* currentAnimation READ currentAnimation NOTIFY currentAnimationChanged) public: - QSequentialAnimationGroup(QObject *parent = 0); + QSequentialAnimationGroup(QObject *parent = Q_NULLPTR); ~QSequentialAnimationGroup(); QPauseAnimation *addPause(int msecs); diff --git a/src/corelib/animation/qsequentialanimationgroup_p.h b/src/corelib/animation/qsequentialanimationgroup_p.h index 035a5537995631c88c4dd6cc5606381e91a253b8..fdb97ca83ca23d5a38afb238ac72f0c7d26684e1 100644 --- a/src/corelib/animation/qsequentialanimationgroup_p.h +++ b/src/corelib/animation/qsequentialanimationgroup_p.h @@ -86,7 +86,7 @@ public: // this is the actual duration of uncontrolled animations // it helps seeking and even going forward - QList<int> actualDuration; + QVector<int> actualDuration; void restart(); int lastLoop; diff --git a/src/corelib/animation/qvariantanimation.h b/src/corelib/animation/qvariantanimation.h index 8a6524a594732ad8058f540ee10ce10d7234832a..4340a187a2e877e985e1dddde56f7ac3d7a9b272 100644 --- a/src/corelib/animation/qvariantanimation.h +++ b/src/corelib/animation/qvariantanimation.h @@ -59,7 +59,7 @@ public: typedef QPair<qreal, QVariant> KeyValue; typedef QVector<KeyValue> KeyValues; - QVariantAnimation(QObject *parent = 0); + QVariantAnimation(QObject *parent = Q_NULLPTR); ~QVariantAnimation(); QVariant startValue() const; @@ -88,7 +88,7 @@ Q_SIGNALS: void valueChanged(const QVariant &value); protected: - QVariantAnimation(QVariantAnimationPrivate &dd, QObject *parent = 0); + QVariantAnimation(QVariantAnimationPrivate &dd, QObject *parent = Q_NULLPTR); bool event(QEvent *event) Q_DECL_OVERRIDE; void updateCurrentTime(int) Q_DECL_OVERRIDE; diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h index b14ab3d6369cdb922a40d1e0e06e9f3c2658fe2d..b2ea85ada277261ce5c0eb6a18d57b4ba86b34a0 100644 --- a/src/corelib/arch/qatomic_armv6.h +++ b/src/corelib/arch/qatomic_armv6.h @@ -90,7 +90,10 @@ private: template <typename T> struct QAtomicOps : QBasicAtomicOps<sizeof(T)> { - typedef T Type; + // this is GCC or GCC-like, so we can use extensions: + // force the alignment to be the size of the type, as on some ABIs the alignment + // of 64-bit types is 32-bit. We need proper alignment for LDREX / STREX. + typedef __attribute__((__aligned__(sizeof(T)))) T Type; }; #ifndef Q_CC_RVCT diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 8fef333a77389129843eab1ecb3de8cc248d4676..88987865c4c66e356af47e2275f1ccb423a69d85 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -1153,16 +1153,6 @@ QTextCodec *QTextCodec::codecForUtfText(const QByteArray &ba) Returns the codec used by QObject::tr() on its argument. If this function returns 0 (the default), tr() assumes Latin-1. - - \sa setCodecForTr() -*/ - -/*! - \fn QTextCodec::setCodecForTr ( QTextCodec * c ) - \obsolete - - Sets the codec used by QObject::tr() on its argument to c. If c - is 0 (the default), tr() assumes Latin-1. */ /*! diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h index 1d5e25efcc4a420d70221602cc7c66a8bc0636b4..3e73872d649f3cfc4bd7d836cd44cf0bab8021f1 100644 --- a/src/corelib/codecs/qtextcodec.h +++ b/src/corelib/codecs/qtextcodec.h @@ -88,7 +88,7 @@ public: struct Q_CORE_EXPORT ConverterState { ConverterState(ConversionFlags f = DefaultConversion) - : flags(f), remainingChars(0), invalidChars(0), d(0) { state_data[0] = state_data[1] = state_data[2] = 0; } + : flags(f), remainingChars(0), invalidChars(0), d(Q_NULLPTR) { state_data[0] = state_data[1] = state_data[2] = 0; } ~ConverterState(); ConversionFlags flags; int remainingChars; @@ -99,9 +99,9 @@ public: Q_DISABLE_COPY(ConverterState) }; - QString toUnicode(const char *in, int length, ConverterState *state = 0) const + QString toUnicode(const char *in, int length, ConverterState *state = Q_NULLPTR) const { return convertToUnicode(in, length, state); } - QByteArray fromUnicode(const QChar *in, int length, ConverterState *state = 0) const + QByteArray fromUnicode(const QChar *in, int length, ConverterState *state = Q_NULLPTR) const { return convertFromUnicode(in, length, state); } QTextDecoder* makeDecoder(ConversionFlags flags = DefaultConversion) const; diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 46154bac5971c44efc4d2cc95d85feb718b4065e..9fbe8df773507835ea5994229f7e6f6eeae762bd 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -13,9 +13,6 @@ irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused CONFIG += optimize_full -# otherwise mingw headers do not declare common functions like putenv -mingw:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x - QMAKE_DOCS = $$PWD/doc/qtcore.qdocconf ANDROID_JAR_DEPENDENCIES = \ @@ -51,6 +48,9 @@ pepper { include(platform/pepper/peppercore.pri) } +# otherwise mingw headers do not declare common functions like putenv +mingw: CONFIG -= strict_c++ + mac|darwin { !ios { LIBS_PRIVATE += -framework ApplicationServices diff --git a/src/corelib/doc/snippets/code/src_corelib_codecs_qtextcodec.cpp b/src/corelib/doc/snippets/code/src_corelib_codecs_qtextcodec.cpp index e2cf761ff854c794aec1a18c043a0c216f815040..eacc94b19f67404152faab5bfcdcf1324a0cb418 100644 --- a/src/corelib/doc/snippets/code/src_corelib_codecs_qtextcodec.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_codecs_qtextcodec.cpp @@ -63,13 +63,3 @@ while (new_data_available()) { } delete decoder; //! [2] - - -//! [3] -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - QTextCodec::setCodecForTr(QTextCodec::codecForName("eucKR")); - ... -} -//! [3] diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qtextstream.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qtextstream.cpp index c76a0f1f3bd2c3bf9694e915a02217010a360e33..ab91a00f5fe64bad15b7b18b34237aa4cad0c78b 100644 --- a/src/corelib/doc/snippets/code/src_corelib_io_qtextstream.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_io_qtextstream.cpp @@ -51,7 +51,7 @@ if (data.open(QFile::WriteOnly | QFile::Truncate)) { //! [1] QTextStream stream(stdin); QString line; -while (stream.readLine(&line)) { +while (stream.readLineInto(&line)) { ... } //! [1] diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp index b0048014a427accafad5e1ff17ba8d9dc6c89e52..8ff44c9dcab4f41e3c7343123b49b8ce59e1f1bb 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp @@ -418,17 +418,17 @@ QString example = tr("Example"); //! [40] //! [41] -QPushButton *button = parentWidget->findChild<QPushButton *>("button1", Qt::FindDirectChildOnly); +QPushButton *button = parentWidget->findChild<QPushButton *>("button1", Qt::FindDirectChildrenOnly); //! [41] //! [42] -QListWidget *list = parentWidget->findChild<QListWidget *>(QString(), Qt::FindDirectChildOnly); +QListWidget *list = parentWidget->findChild<QListWidget *>(QString(), Qt::FindDirectChildrenOnly); //! [42] //! [43] -QList<QPushButton *> childButtons = parentWidget.findChildren<QPushButton *>(QString(), Qt::FindDirectChildOnly); +QList<QPushButton *> childButtons = parentWidget.findChildren<QPushButton *>(QString(), Qt::FindDirectChildrenOnly); //! [43] //! [44] diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp index 43d64fc08e953692391504c832dd3bea87dde1d5..0ac7cb5769c43c05fc5db9420158f5d0549c2cce 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp @@ -298,6 +298,25 @@ while (i != hash.end() && i.key() == "plenty") { } //! [26] +//! [27] +for (QHash<int, QString>::const_iterator it = hash.cbegin(), end = hash.cend(); it != end; ++it) { + cout << "The key: " << it.key() << endl + cout << "The value: " << it.value() << endl; + cout << "Also the value: " << (*it) << endl; +} +//! [27] + +//! [28] +// Inefficient, keys() is expensive +QList<int> keys = hash.keys(); +int numPrimes = std::count_if(keys.cbegin(), keys.cend(), isPrimeNumber); +qDeleteAll(hash2.keys()); + +// Efficient, no memory allocation needed +int numPrimes = std::count_if(hash.keyBegin(), hash.keyEnd(), isPrimeNumber); +qDeleteAll(hash2.keyBegin(), hash2.keyEnd()); +//! [28] + //! [qhashbits] inline uint qHash(const std::vector<int> &key, uint seed = 0) { diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp index 7580b6bbaf80f0e7fa747c99adc489d77a68157d..29e53fc700e88f01d3d590159754fe6e43f9fb5d 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp @@ -311,3 +311,22 @@ while (i != map.end() && i.key() == "plenty") { ++i; } //! [27] + +//! [keyiterator1] +for (QMap<int, QString>::const_iterator it = map.cbegin(), end = map.cend(); it != end; ++it) { + cout << "The key: " << it.key() << endl + cout << "The value: " << it.value() << endl; + cout << "Also the value: " << (*it) << endl; +} +//! [keyiterator1] + +//! [keyiterator2] +// Inefficient, keys() is expensive +QList<int> keys = map.keys(); +int numPrimes = std::count_if(map.cbegin(), map.cend(), isPrimeNumber); +qDeleteAll(map2.keys()); + +// Efficient, no memory allocation needed +int numPrimes = std::count_if(map.keyBegin(), map.keyEnd(), isPrimeNumber); +qDeleteAll(map2.keyBegin(), map2.keyEnd()); +//! [keyiterator2] diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qvector.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qvector.cpp index 77b34c95fcb63d7b03d3149828b67871678ddae7..5def361b83968e0ac78799dbac19e92cc38bd3d5 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qvector.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qvector.cpp @@ -84,14 +84,27 @@ for (int i = 0; i < 10; ++i) //! [7] -QVector<QString> vector(0); +QVector<QString> vector; vector.append("one"); vector.append("two"); -vector.append("three"); +QString three = "three"; +vector.append(three); // vector: ["one", "two", "three"] +// three: "three" //! [7] +//! [move-append] +QVector<QString> vector; +vector.append("one"); +vector.append("two"); +QString three = "three"; +vector.append(std::move(three)); +// vector: ["one", "two", "three"] +// three: "" +//! [move-append] + + //! [8] QVector<QString> vector; vector.prepend("one"); diff --git a/src/corelib/doc/snippets/hellotrmain.cpp b/src/corelib/doc/snippets/hellotrmain.cpp index 201202b7b38aa1c00bdf10fb8ad58b4cc8b775f5..dcf5805a8a1d71b235af7c671a51bdc8460dbf43 100644 --- a/src/corelib/doc/snippets/hellotrmain.cpp +++ b/src/corelib/doc/snippets/hellotrmain.cpp @@ -44,10 +44,11 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); QTranslator translator; - translator.load("hellotr_la"); - app.installTranslator(&translator); + // look up e.g. :/translations/myapp_de.qm + if (translator.load(QLocale(), QLatin1String("myapp"), QLatin1String("_"), QLatin1String(":/translations"))) + app.installTranslator(&translator); - QPushButton hello(QPushButton::tr("Hello world!")); + QPushButton hello(QCoreApplication::translate("main", "Hello world!")); hello.resize(100, 30); hello.show(); diff --git a/src/corelib/doc/snippets/qstring/main.cpp b/src/corelib/doc/snippets/qstring/main.cpp index 4687d52e541350152ef793880f38950b8a105a35..e03e705a0b29eea0b2284bccf4b92b5744fff1c1 100644 --- a/src/corelib/doc/snippets/qstring/main.cpp +++ b/src/corelib/doc/snippets/qstring/main.cpp @@ -261,6 +261,19 @@ void Widget::argFunction() str.arg("%1f").arg("Hello"); // returns "Hellof %2" //! [13] + //! [97] + str = "%1%3%2"; + str.arg("Hello").arg(20).arg(50); // returns "Hello500" + + str = "%1%2%3"; + str.arg("Hello").arg(50).arg(20); // returns "Hello5020" + //! [97] + + //! [98] + str = "%1%2%3"; + str.arg("Hello", QString::number(20), QString::number(50)); // returns "Hello5020" + //! [98] + //! [14] str = QString("Decimal 63 is %1 in hexadecimal") .arg(63, 0, 16); diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc index 1979c45e1791861c41a4a03c4db78f193ba4a16e..f8d0d3eb052c02368f1b53e59290b34d728a4af6 100644 --- a/src/corelib/doc/src/containers.qdoc +++ b/src/corelib/doc/src/containers.qdoc @@ -601,6 +601,13 @@ container. It only affects the copy, which is probably not what you want. + An alternative to Qt's \c foreach loop is the range-based \c for that is + part of C++ 11 and newer. However, keep in mind that the range-based + \c for might force a Qt container to \l{Implicit Sharing}{detach}, whereas + \c foreach would not. But using \c foreach always copies the container, + which is usually not cheap for STL containers. If in doubt, prefer + \c foreach for Qt containers, and range based \c for for STL ones. + In addition to \c foreach, Qt also provides a \c forever pseudo-keyword for infinite loops: diff --git a/src/corelib/doc/src/external-resources.qdoc b/src/corelib/doc/src/external-resources.qdoc index ec4715c9339bd280c9877521da23ea5354f8bd2b..d612ce828052cf563e3892ff0b1941ac04854939 100644 --- a/src/corelib/doc/src/external-resources.qdoc +++ b/src/corelib/doc/src/external-resources.qdoc @@ -65,4 +65,13 @@ \externalpage http://doc-snapshot.qt-project.org/qt5-5.4/designer-widget-mode.html#the-property-editor \title Qt Designer's Widget Editing Mode#The Property Editor */ + +/*! + \externalpage http://marcmutz.wordpress.com/effective-qt/containers/#containers-qlist + \title Pros and Cons of Using QList +*/ + +/*! + \externalpage http://marcmutz.wordpress.com/effective-qt/containers/ + \title Understand the Qt Containers */ diff --git a/src/corelib/doc/src/objectmodel/properties.qdoc b/src/corelib/doc/src/objectmodel/properties.qdoc index abb0720fe945751ed4f5e98bc7d58ff14cfe3095..55622dd56b9d60daecb5ff2e81a68a21ca379cce 100644 --- a/src/corelib/doc/src/objectmodel/properties.qdoc +++ b/src/corelib/doc/src/objectmodel/properties.qdoc @@ -160,13 +160,8 @@ Because QDate is user-defined, you must include the \c{<QDate>} header file with the property declaration. - For QMap, QList, and QValueList properties, the property value is - a QVariant whose value is the entire list or map. Note that the - Q_PROPERTY string cannot contain commas, because commas separate - macro arguments. Therefore, you must use \c QMap as the property - type instead of \c QMap<QString,QVariant>. For consistency, also - use \c QList and \c QValueList instead of \c QList<QVariant> and - \c QValueList<QVariant>. + For historical reasons, \a QMap and \a QList as property types + are synonym of \a QVariantMap and \a QVariantList. \section1 Reading and Writing Properties with the Meta-Object System diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index bc11c77d8831ebc16ec56909494888c1c21bf8b4..6a8104bee2c129778efb86368a71392132dd2e22 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -41,7 +41,7 @@ LIBS_PRIVATE += $$QMAKE_LIBS_EXECINFO if(linux*|hurd*):!cross_compile:!static:!*-armcc* { QMAKE_LFLAGS += -Wl,-e,qt_core_boilerplate prog=$$quote(if (/program interpreter: (.*)]/) { print $1; }) - DEFINES += ELF_INTERPRETER=\\\"$$system(readelf -l /bin/ls | perl -n -e \'$$prog\')\\\" + DEFINES += ELF_INTERPRETER=\\\"$$system(LC_ALL=C readelf -l /bin/ls | perl -n -e \'$$prog\')\\\" } slog2 { diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index f8a8a436bec0d607a0bb58bf6bd455ac79afb0f7..c582b1f238561074caa769bdcd4cab819d19f2ed 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -97,7 +97,7 @@ /* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */ # if defined(__INTEL_COMPILER) # define Q_DECL_VARIABLE_DEPRECATED -# define Q_CC_INTEL +# define Q_CC_INTEL __INTEL_COMPILER # endif /* only defined for MSVC since that's the only compiler that actually optimizes for this */ @@ -155,7 +155,9 @@ /* Clang also masquerades as GCC */ # if defined(__apple_build_version__) # /* http://en.wikipedia.org/wiki/Xcode#Toolchain_Versions */ -# if __apple_build_version__ >= 6000051 +# if __apple_build_version__ >= 7000053 +# define Q_CC_CLANG 306 +# elif __apple_build_version__ >= 6000051 # define Q_CC_CLANG 305 # elif __apple_build_version__ >= 5030038 # define Q_CC_CLANG 304 @@ -556,9 +558,22 @@ # define Q_COMPILER_ALIGNAS # define Q_COMPILER_ALIGNOF # define Q_COMPILER_INHERITING_CONSTRUCTORS -# define Q_COMPILER_THREAD_LOCAL +# ifndef Q_OS_OSX +// C++11 thread_local is broken on OS X (Clang doesn't support it either) +# define Q_COMPILER_THREAD_LOCAL +# endif # define Q_COMPILER_UDL # endif +# ifdef _MSC_VER +# if _MSC_VER == 1700 +// <initializer_list> is missing with MSVC 2012 (it's present in 2010, 2013 and up) +# undef Q_COMPILER_INITIALIZER_LISTS +# endif +# if _MSC_VER < 1900 +// ICC disables unicode string support when compatibility mode with MSVC 2013 or lower is active +# undef Q_COMPILER_UNICODE_STRINGS +# endif +# endif # endif #endif @@ -613,7 +628,7 @@ # if __has_feature(cxx_strong_enums) # define Q_COMPILER_CLASS_ENUM # endif -# if __has_feature(cxx_constexpr) +# if __has_feature(cxx_constexpr) && Q_CC_CLANG > 302 /* CLANG 3.2 has bad/partial support */ # define Q_COMPILER_CONSTEXPR # endif # if __has_feature(cxx_decltype) /* && __has_feature(cxx_decltype_incomplete_return_types) */ @@ -885,7 +900,8 @@ # define Q_COMPILER_RANGE_FOR # define Q_COMPILER_REF_QUALIFIERS # define Q_COMPILER_THREAD_LOCAL -# define Q_COMPILER_THREADSAFE_STATICS +// Broken, see QTBUG-47224 and https://connect.microsoft.com/VisualStudio/feedback/details/1549785 +//# define Q_COMPILER_THREADSAFE_STATICS # define Q_COMPILER_UDL # define Q_COMPILER_UNICODE_STRINGS // Uniform initialization is not working yet -- build errors with QUuid diff --git a/src/corelib/global/qflags.h b/src/corelib/global/qflags.h index d3b9c3f5a77c48d116d7cb5ef5320807c09be376..f434e87c8536be5ffaed04cc85806d47fc97049e 100644 --- a/src/corelib/global/qflags.h +++ b/src/corelib/global/qflags.h @@ -109,7 +109,7 @@ public: inline QFlags &operator=(const QFlags &other); #endif Q_DECL_CONSTEXPR inline QFlags(Enum f) Q_DECL_NOTHROW : i(Int(f)) {} - Q_DECL_CONSTEXPR inline QFlags(Zero = 0) Q_DECL_NOTHROW : i(0) {} + Q_DECL_CONSTEXPR inline QFlags(Zero = Q_NULLPTR) Q_DECL_NOTHROW : i(0) {} Q_DECL_CONSTEXPR inline QFlags(QFlag f) Q_DECL_NOTHROW : i(f) {} #ifdef Q_COMPILER_INITIALIZER_LISTS diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 7045d962d3f0b74e9501c68365ca75b98a423bae..5f530a6d792e289ce39b36bd2864f4fb8c55b9cf 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1127,10 +1127,11 @@ bool qSharedBuild() Q_DECL_NOTHROW \value MV_10_4 Mac OS X 10.4 (unsupported) \value MV_10_5 Mac OS X 10.5 (unsupported) \value MV_10_6 Mac OS X 10.6 - \value MV_10_7 OS X 10.7 + \value MV_10_7 Mac OS X 10.7 \value MV_10_8 OS X 10.8 \value MV_10_9 OS X 10.9 \value MV_10_10 OS X 10.10 + \value MV_10_11 OS X 10.11 \value MV_Unknown An unknown and currently unsupported platform \value MV_CHEETAH Apple codename for MV_10_0 @@ -1144,6 +1145,7 @@ bool qSharedBuild() Q_DECL_NOTHROW \value MV_MOUNTAINLION Apple codename for MV_10_8 \value MV_MAVERICKS Apple codename for MV_10_9 \value MV_YOSEMITE Apple codename for MV_10_10 + \value MV_ELCAPITAN Apple codename for MV_10_11 \value MV_IOS iOS (any) \value MV_IOS_4_3 iOS 4.3 @@ -1157,6 +1159,8 @@ bool qSharedBuild() Q_DECL_NOTHROW \value MV_IOS_8_1 iOS 8.1 \value MV_IOS_8_2 iOS 8.2 \value MV_IOS_8_3 iOS 8.3 + \value MV_IOS_8_4 iOS 8.4 + \value MV_IOS_9_0 iOS 9.0 \value MV_None Not a Darwin operating system @@ -2052,32 +2056,27 @@ QSysInfo::WinVersion QSysInfo::windowsVersion() #ifdef QT_DEBUG { - QByteArray override = qgetenv("QT_WINVER_OVERRIDE"); - if (override.isEmpty()) - return winver; - - if (override == "Me") - winver = QSysInfo::WV_Me; - if (override == "95") - winver = QSysInfo::WV_95; - else if (override == "98") - winver = QSysInfo::WV_98; - else if (override == "NT") - winver = QSysInfo::WV_NT; - else if (override == "2000") - winver = QSysInfo::WV_2000; - else if (override == "2003") - winver = QSysInfo::WV_2003; - else if (override == "XP") - winver = QSysInfo::WV_XP; - else if (override == "VISTA") - winver = QSysInfo::WV_VISTA; - else if (override == "WINDOWS7") - winver = QSysInfo::WV_WINDOWS7; - else if (override == "WINDOWS8") - winver = QSysInfo::WV_WINDOWS8; - else if (override == "WINDOWS8_1") - winver = QSysInfo::WV_WINDOWS8_1; + if (Q_UNLIKELY(qEnvironmentVariableIsSet("QT_WINVER_OVERRIDE"))) { + const QByteArray winVerOverride = qgetenv("QT_WINVER_OVERRIDE"); + if (winVerOverride == "NT") + winver = QSysInfo::WV_NT; + else if (winVerOverride == "2000") + winver = QSysInfo::WV_2000; + else if (winVerOverride == "2003") + winver = QSysInfo::WV_2003; + else if (winVerOverride == "XP") + winver = QSysInfo::WV_XP; + else if (winVerOverride == "VISTA") + winver = QSysInfo::WV_VISTA; + else if (winVerOverride == "WINDOWS7") + winver = QSysInfo::WV_WINDOWS7; + else if (winVerOverride == "WINDOWS8") + winver = QSysInfo::WV_WINDOWS8; + else if (winVerOverride == "WINDOWS8_1") + winver = QSysInfo::WV_WINDOWS8_1; + else if (winVerOverride == "WINDOWS10") + winver = QSysInfo::WV_WINDOWS10; + } } #endif #endif // !Q_OS_WINRT @@ -2104,6 +2103,8 @@ static const char *winVer_helper() return "8"; case QSysInfo::WV_WINDOWS8_1: return "8.1"; + case QSysInfo::WV_WINDOWS10: + return "10"; case QSysInfo::WV_CE: return "CE"; @@ -2263,7 +2264,8 @@ static bool readEtcRedHatRelease(QUnixOSVersion &v) int releaseIndex = line.indexOf(keyword); v.productType = QString::fromLatin1(line.mid(0, releaseIndex)).remove(QLatin1Char(' ')); int spaceIndex = line.indexOf(' ', releaseIndex + strlen(keyword)); - v.productVersion = QString::fromLatin1(line.mid(releaseIndex + strlen(keyword), spaceIndex > -1 ? spaceIndex - releaseIndex - strlen(keyword) : -1)); + v.productVersion = QString::fromLatin1(line.mid(releaseIndex + strlen(keyword), + spaceIndex > -1 ? spaceIndex - releaseIndex - int(strlen(keyword)) : -1)); return true; } @@ -2741,7 +2743,7 @@ QString QSysInfo::prettyProductName() basename = "Mac OS X Snow Leopard ("; break; case MV_LION: - basename = "Mac OS X Lion ("; + basename = "OS X Lion ("; break; case MV_MOUNTAINLION: basename = "OS X Mountain Lion ("; @@ -2752,6 +2754,9 @@ QString QSysInfo::prettyProductName() case MV_YOSEMITE: basename = "OS X Yosemite ("; break; + case MV_ELCAPITAN: + basename = "OS X El Capitan ("; + break; } if (basename) return QLatin1String(basename) + productVersion() + QLatin1Char(')'); diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index f943016f370d5ef6d65819757b9b87e696249aa0..20b43deb66b1324e9b5b3d0ec1d157fc6e097df3 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -585,7 +585,9 @@ Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max # define QT_OSX_DEPLOYMENT_TARGET_BELOW(osx) \ QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, __IPHONE_NA) +QT_END_NAMESPACE Q_FORWARD_DECLARE_OBJC_CLASS(NSAutoreleasePool); +QT_BEGIN_NAMESPACE // Implemented in qcore_mac_objc.mm class Q_CORE_EXPORT QMacAutoReleasePool @@ -1077,7 +1079,7 @@ Q_CORE_EXPORT bool qunsetenv(const char *varName); Q_CORE_EXPORT bool qEnvironmentVariableIsEmpty(const char *varName) Q_DECL_NOEXCEPT; Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) Q_DECL_NOEXCEPT; -Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=0) Q_DECL_NOEXCEPT; +Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=Q_NULLPTR) Q_DECL_NOEXCEPT; inline int qIntCast(double f) { return int(f); } inline int qIntCast(float f) { return int(f); } diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index f9459f0a4cac6405325be4f90130fed2db7787d1..177b411defc04eb3e18b06f69b967eac55613cfe 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -651,11 +651,9 @@ void qt_core_boilerplate() "Copyright (C) 2015 The Qt Company Ltd.\n" "Contact: http://www.qt.io/licensing/\n" "\n" - "Build date: %s\n" "Installation prefix: %s\n" "Library path: %s\n" "Include path: %s\n", - qt_configure_installation + 12, qt_configure_prefix_path_str + 12, qt_configure_strs + qt_configure_str_offsets[QT_PREPEND_NAMESPACE(QLibraryInfo)::LibrariesPath - 1], qt_configure_strs + qt_configure_str_offsets[QT_PREPEND_NAMESPACE(QLibraryInfo)::HeadersPath - 1]); diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index a939c5ee19873aba0f2a9a8ce56717ed6fc17319..970e917478559dd4721e22237006d0f99037a190 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -87,6 +87,10 @@ # endif #endif +#if defined(QT_USE_SLOG2) +extern char *__progname; +#endif + #if defined(Q_OS_LINUX) && (defined(__GLIBC__) || __has_include(<sys/syscall.h>)) # include <sys/syscall.h> static long qt_gettid() @@ -1175,8 +1179,6 @@ void QMessagePattern::setPattern(const QString &pattern) #define QT_LOG_CODE 9000 #endif -extern char *__progname; - static void slog2_default_handler(QtMsgType msgType, const char *message) { if (slog2_set_default_buffer((slog2_buffer_t)-1) == 0) { @@ -1359,8 +1361,9 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con } else if (pattern->timeFormat == QLatin1String("boot")) { // just print the milliseconds since the elapsed timer reference // like the Linux kernel does - pattern->timer.elapsed(); - uint ms = pattern->timer.msecsSinceReference(); + QElapsedTimer now; + now.start(); + uint ms = now.msecsSinceReference(); message.append(QString::asprintf("%6d.%03d", uint(ms / 1000), uint(ms % 1000))); } else if (pattern->timeFormat.isEmpty()) { message.append(QDateTime::currentDateTime().toString(Qt::ISODate)); diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h index 679afddb204377b84af426d3268a1899652a531c..c63346086ad6ea2ba645da876227e364ac93cf05 100644 --- a/src/corelib/global/qlogging.h +++ b/src/corelib/global/qlogging.h @@ -57,7 +57,8 @@ class QMessageLogContext { Q_DISABLE_COPY(QMessageLogContext) public: - Q_DECL_CONSTEXPR QMessageLogContext() : version(2), line(0), file(0), function(0), category(0) {} + Q_DECL_CONSTEXPR QMessageLogContext() + : version(2), line(0), file(Q_NULLPTR), function(Q_NULLPTR), category(Q_NULLPTR) {} Q_DECL_CONSTEXPR QMessageLogContext(const char *fileName, int lineNumber, const char *functionName, const char *categoryName) : version(2), line(lineNumber), file(fileName), function(functionName), category(categoryName) {} diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index fc5207fa257dd7824e0ae12e240b3e242d1610f3..3e3af6ede30e5411ddabdaa1d8c62447aba1e7e9 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -496,6 +496,7 @@ public: AA_UseSoftwareOpenGL = 17, AA_ShareOpenGLContexts = 18, AA_SetPalette = 19, + AA_NoHighDpiScaling = 20, // Add new attributes before this line AA_AttributeCount @@ -1625,7 +1626,8 @@ public: enum MouseEventSource { MouseEventNotSynthesized, MouseEventSynthesizedBySystem, - MouseEventSynthesizedByQt + MouseEventSynthesizedByQt, + MouseEventSynthesizedByApplication }; enum MouseEventFlag { diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 970e1b1f426dfceed64a6a94df8b1a24122d159b..aeff9502feb969706deee46931f03012df89fa91 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -197,6 +197,11 @@ \value AA_SetPalette Indicates whether a palette was explicitly set on the QApplication/QGuiApplication. This value has been added in Qt 5.5. + \value AA_NoHighDpiScaling Disables all high-DPI scaling in Qt, exposing window + system coordinates. Note that the window system may do its own scaling, + so this does not guarantee that QPaintDevice::devicePixelRatio() will + be equal to 1. This value has been added in Qt 5.6. + The following values are obsolete: \value AA_ImmediateWidgetCreation This attribute is no longer fully @@ -2540,10 +2545,10 @@ /*! \enum Qt::EnterKeyType - This can be used to alter the appearance of the Return key on an on screen keyboard. + This can be used to alter the appearance of the Return key on an on-screen keyboard. \note Not all of these values are supported on all platforms. - For unsuppoted values the default key will be used instead. + For unsupported values the default key will be used instead. \value EnterKeyDefault The default Enter key. This can either be a button closing the keyboard, or a Return button @@ -3068,6 +3073,12 @@ \value MouseEventSynthesizedByQt Indicates that the mouse event was synthesized from an unhandled touch event by Qt. + \value MouseEventSynthesizedByApplication Indicates that the mouse + event was synthesized by the application. This allows + distinguishing application-generated mouse events from the ones + that are coming from the system or are synthesized by Qt. This + value was introduced in Qt 5.6 + \sa Qt::AA_SynthesizeMouseForUnhandledTouchEvents */ diff --git a/src/corelib/global/qsysinfo.h b/src/corelib/global/qsysinfo.h index 72acdd8c705edae461f2a03e762b552eb469f690..d40e6659c7aac1bb1ab138c695e06a958ebb70e8 100644 --- a/src/corelib/global/qsysinfo.h +++ b/src/corelib/global/qsysinfo.h @@ -137,6 +137,7 @@ public: MV_10_8 = Q_MV_OSX(10, 8), MV_10_9 = Q_MV_OSX(10, 9), MV_10_10 = Q_MV_OSX(10, 10), + MV_10_11 = Q_MV_OSX(10, 11), /* codenames */ MV_CHEETAH = MV_10_0, @@ -150,6 +151,7 @@ public: MV_MOUNTAINLION = MV_10_8, MV_MAVERICKS = MV_10_9, MV_YOSEMITE = MV_10_10, + MV_ELCAPITAN = MV_10_11, /* iOS */ MV_IOS = 1 << 8, @@ -163,7 +165,9 @@ public: MV_IOS_8_0 = Q_MV_IOS(8, 0), MV_IOS_8_1 = Q_MV_IOS(8, 1), MV_IOS_8_2 = Q_MV_IOS(8, 2), - MV_IOS_8_3 = Q_MV_IOS(8, 3) + MV_IOS_8_3 = Q_MV_IOS(8, 3), + MV_IOS_8_4 = Q_MV_IOS(8, 4), + MV_IOS_9_0 = Q_MV_IOS(9, 0) }; #if defined(Q_OS_MAC) static const MacVersion MacintoshVersion; diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h index 3a285da32c10298cad3edd0f0a53b808d131fb4b..88f1c072762c4be32f39d444d6ffa430cc4c747d 100644 --- a/src/corelib/global/qsystemdetection.h +++ b/src/corelib/global/qsystemdetection.h @@ -242,6 +242,9 @@ # if !defined(__MAC_10_10) # define __MAC_10_10 101000 # endif +# if !defined(__MAC_10_11) +# define __MAC_10_11 101100 +# endif # if !defined(MAC_OS_X_VERSION_10_7) # define MAC_OS_X_VERSION_10_7 1070 # endif @@ -254,6 +257,9 @@ # if !defined(MAC_OS_X_VERSION_10_10) # define MAC_OS_X_VERSION_10_10 101000 # endif +# if !defined(MAC_OS_X_VERSION_10_11) +# define MAC_OS_X_VERSION_10_11 101100 +# endif # # if !defined(__IPHONE_4_3) # define __IPHONE_4_3 40300 @@ -288,6 +294,12 @@ # if !defined(__IPHONE_8_3) # define __IPHONE_8_3 80300 # endif +# if !defined(__IPHONE_8_4) +# define __IPHONE_8_4 80400 +# endif +# if !defined(__IPHONE_9_0) +# define __IPHONE_9_0 90000 +# endif #endif #ifdef __LSB_VERSION__ diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h index 90ac8c6a0c41c7037154903a8a44ada6c9709443..7fee613f8922ffde30275363a96db442978d43c7 100644 --- a/src/corelib/global/qtypeinfo.h +++ b/src/corelib/global/qtypeinfo.h @@ -201,13 +201,22 @@ Q_DECLARE_TYPEINFO_BODY(QFlags<T>, Q_PRIMITIVE_TYPE); where 'type' is the name of the type to specialize. NOTE: shared types must define a member-swap, and be defined in the same namespace as Qt for this to work. + + If the type was already released without Q_DECLARE_SHARED applied, + _and_ without an explicit Q_DECLARE_TYPEINFO(type, Q_MOVABLE_TYPE), + then use Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(type) to mark the + type shared (incl. swap()), without marking it movable (which + would change the memory layout of QList, a BiC change. */ -#define Q_DECLARE_SHARED(TYPE) \ -Q_DECLARE_TYPEINFO(TYPE, Q_MOVABLE_TYPE); \ +#define Q_DECLARE_SHARED_IMPL(TYPE, FLAGS) \ +Q_DECLARE_TYPEINFO(TYPE, FLAGS); \ inline void swap(TYPE &value1, TYPE &value2) \ Q_DECL_NOEXCEPT_EXPR(noexcept(value1.swap(value2))) \ { value1.swap(value2); } +#define Q_DECLARE_SHARED(TYPE) Q_DECLARE_SHARED_IMPL(TYPE, Q_MOVABLE_TYPE) +#define Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(TYPE) \ + Q_DECLARE_SHARED_IMPL(TYPE, QT_VERSION >= QT_VERSION_CHECK(6,0,0) ? Q_MOVABLE_TYPE : Q_COMPLEX_TYPE) /* QTypeInfo primitive specializations diff --git a/src/corelib/io/forkfd_qt.cpp b/src/corelib/io/forkfd_qt.cpp index 6704ec6f2acdd4d387ffdd7213aa9be70fb75f55..b226332cc1b12f5a6d0b39817be0d0db054a8418 100644 --- a/src/corelib/io/forkfd_qt.cpp +++ b/src/corelib/io/forkfd_qt.cpp @@ -32,13 +32,6 @@ ****************************************************************************/ // these might be defined via precompiled headers -#ifndef _POSIX_C_SOURCE -# define _POSIX_C_SOURCE 200809L -#endif -#if !defined(_XOPEN_SOURCE) && !defined(__QNXNTO__) && !defined(ANDROID) -# define _XOPEN_SOURCE 700 -#endif - #include <QtCore/qatomic.h> #include "qprocess_p.h" diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index de815c3b151cb72c2135d94286f17fed6086bf8c..51b67f2fc3852494a25ab8b9f9b3fc21ac1d5998 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -149,7 +149,9 @@ win32 { mac { SOURCES += io/qsettings_mac.cpp OBJECTIVE_SOURCES += io/qurl_mac.mm - + } + freebsd: LIBS_PRIVATE += -lutil # qlockfile_unix.cpp requires this + mac { osx { OBJECTIVE_SOURCES += io/qfilesystemwatcher_fsevents.mm HEADERS += io/qfilesystemwatcher_fsevents_p.h diff --git a/src/corelib/io/qbuffer.h b/src/corelib/io/qbuffer.h index 1b2758d040956eeadd4943f3c953a0651097c87e..233c702213463623fe00b0f40a1d19c084d2a0a9 100644 --- a/src/corelib/io/qbuffer.h +++ b/src/corelib/io/qbuffer.h @@ -51,8 +51,8 @@ class Q_CORE_EXPORT QBuffer : public QIODevice public: #ifndef QT_NO_QOBJECT - explicit QBuffer(QObject *parent = 0); - QBuffer(QByteArray *buf, QObject *parent = 0); + explicit QBuffer(QObject *parent = Q_NULLPTR); + QBuffer(QByteArray *buf, QObject *parent = Q_NULLPTR); #else QBuffer(); explicit QBuffer(QByteArray *buf); diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp index 48672db2e981b1056a9c2ccc9839dd8789d798de..713b5a2f55da2899397d1face231023d5e01c337 100644 --- a/src/corelib/io/qdatastream.cpp +++ b/src/corelib/io/qdatastream.cpp @@ -526,6 +526,7 @@ void QDataStream::setByteOrder(ByteOrder bo) \value Qt_5_3 Same as Qt_5_2 \value Qt_5_4 Version 16 (Qt 5.4) \value Qt_5_5 Same as Qt_5_4 + \value Qt_5_6 Same as Qt_5_4 \omitvalue Qt_DefaultCompiledVersion \sa setVersion(), version() diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 8b3dd5d82f0ef091b9eee505b32da08028fc0c6c..e1d9858a662520fe84b586963689ce8d9740d155 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -777,6 +777,8 @@ QString QDir::relativeFilePath(const QString &fileName) const result += QLatin1Char('/'); } + if (result.isEmpty()) + return QLatin1String("."); return result; } @@ -1501,11 +1503,19 @@ bool QDir::removeRecursively() while (di.hasNext()) { di.next(); const QFileInfo& fi = di.fileInfo(); + const QString &filePath = di.filePath(); bool ok; - if (fi.isDir() && !fi.isSymLink()) - ok = QDir(di.filePath()).removeRecursively(); // recursive - else - ok = QFile::remove(di.filePath()); + if (fi.isDir() && !fi.isSymLink()) { + ok = QDir(filePath).removeRecursively(); // recursive + } else { + ok = QFile::remove(filePath); + if (!ok) { // Read-only files prevent directory deletion on Windows, retry with Write permission. + const QFile::Permissions permissions = QFile::permissions(filePath); + if (!(permissions & QFile::WriteUser)) + ok = QFile::setPermissions(filePath, permissions | QFile::WriteUser) + && QFile::remove(filePath); + } + } if (!ok) success = false; } diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h index b6946eba653a488ef45afb7015e34c8ed4744c50..ab3a331229a5e1980fa08b51d443fb39db73a068 100644 --- a/src/corelib/io/qdir.h +++ b/src/corelib/io/qdir.h @@ -101,11 +101,10 @@ public: QDir &operator=(const QDir &); QDir &operator=(const QString &path); #ifdef Q_COMPILER_RVALUE_REFS - inline QDir &operator=(QDir &&other) - { qSwap(d_ptr, other.d_ptr); return *this; } + QDir &operator=(QDir &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif - inline void swap(QDir &other) + void swap(QDir &other) Q_DECL_NOTHROW { qSwap(d_ptr, other.d_ptr); } void setPath(const QString &path); diff --git a/src/corelib/io/qfile.h b/src/corelib/io/qfile.h index 35a73680af516b626d809e1f94b456c76fd0f241..4eac710d4c2024336a2ca426e2d866c725a49cac 100644 --- a/src/corelib/io/qfile.h +++ b/src/corelib/io/qfile.h @@ -134,7 +134,7 @@ protected: #ifdef QT_NO_QOBJECT QFile(QFilePrivate &dd); #else - QFile(QFilePrivate &dd, QObject *parent = 0); + QFile(QFilePrivate &dd, QObject *parent = Q_NULLPTR); #endif private: diff --git a/src/corelib/io/qfiledevice.h b/src/corelib/io/qfiledevice.h index e9320d8d31c9342c27e29871036bd89befe0f184..afa42bd86b693606a02c295e00af0d29b07a70de 100644 --- a/src/corelib/io/qfiledevice.h +++ b/src/corelib/io/qfiledevice.h @@ -119,7 +119,7 @@ protected: QFileDevice(QFileDevicePrivate &dd); #else explicit QFileDevice(QObject *parent); - QFileDevice(QFileDevicePrivate &dd, QObject *parent = 0); + QFileDevice(QFileDevicePrivate &dd, QObject *parent = Q_NULLPTR); #endif qint64 readData(char *data, qint64 maxlen) Q_DECL_OVERRIDE; diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index 58cf9a5c0ff345b841456ef3c98ae2d116a786d8..59d12c3883cb0e3cc1b2e454bc2aef9b1fb53f81 100644 --- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -62,11 +62,10 @@ public: QFileInfo &operator=(const QFileInfo &fileinfo); #ifdef Q_COMPILER_RVALUE_REFS - inline QFileInfo&operator=(QFileInfo &&other) - { qSwap(d_ptr, other.d_ptr); return *this; } + QFileInfo &operator=(QFileInfo &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif - inline void swap(QFileInfo &other) + void swap(QFileInfo &other) Q_DECL_NOTHROW { qSwap(d_ptr, other.d_ptr); } bool operator==(const QFileInfo &fileinfo) const; diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp index cddd70f908576e76731b290fa8a4147729e2f849..85d9b0bfcbaf543ae0d40230f5f9343232d27417 100644 --- a/src/corelib/io/qfileselector.cpp +++ b/src/corelib/io/qfileselector.cpp @@ -80,7 +80,7 @@ QFileSelectorPrivate::QFileSelectorPrivate() QString defaultsBasePath = "data/"; QString defaultsPath = defaultsBasePath + "defaults.conf"; QString localizedPath = defaultsBasePath - + QString("%1/defaults.conf").arg(QLocale::system().name()); + + QString("%1/defaults.conf").arg(QLocale().name()); if (QFile::exists(localizedPath)) defaultsPath = localizedPath; QFile defaults(defaultsPath); @@ -148,7 +148,7 @@ QFileSelectorPrivate::QFileSelectorPrivate() on (list not exhaustive): android, blackberry, ios, osx, darwin, mac, linux, wince, unix, windows. On Linux, if it can be determined, the name of the distribution too, like debian, fedora or opensuse. - \li locale, same as QLocale::system().name(). + \li locale, same as QLocale().name(). \endlist Further selectors will be added from the \c QT_FILE_SELECTORS environment variable, which @@ -347,7 +347,7 @@ void QFileSelectorPrivate::updateSelectors() sharedData->staticSelectors << sharedData->preloadedStatics; //Potential for static selectors from other modules // TODO: Update on locale changed? - sharedData->staticSelectors << QLocale::system().name(); + sharedData->staticSelectors << QLocale().name(); sharedData->staticSelectors << platformSelectors(); } diff --git a/src/corelib/io/qfileselector.h b/src/corelib/io/qfileselector.h index 967d5eee75efe66032dc0cbbc793d0d90659d8b6..9ee35887807bad625cb2b99cbc712d54d5f4d4a1 100644 --- a/src/corelib/io/qfileselector.h +++ b/src/corelib/io/qfileselector.h @@ -44,7 +44,7 @@ class Q_CORE_EXPORT QFileSelector : public QObject { Q_OBJECT public: - explicit QFileSelector(QObject *parent = 0); + explicit QFileSelector(QObject *parent = Q_NULLPTR); ~QFileSelector(); QString select(const QString &filePath) const; diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index b66d1b345840a9d36c18f0c66b44c9ebb9b9057a..985f0bf5bd79472eb59fa5a8f24a5724b393b309 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -666,17 +666,11 @@ bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QSystemError & bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data) { mode_t mode = 0; - if (permissions & QFile::ReadOwner) + if (permissions & (QFile::ReadOwner | QFile::ReadUser)) mode |= S_IRUSR; - if (permissions & QFile::WriteOwner) + if (permissions & (QFile::WriteOwner | QFile::WriteUser)) mode |= S_IWUSR; - if (permissions & QFile::ExeOwner) - mode |= S_IXUSR; - if (permissions & QFile::ReadUser) - mode |= S_IRUSR; - if (permissions & QFile::WriteUser) - mode |= S_IWUSR; - if (permissions & QFile::ExeUser) + if (permissions & (QFile::ExeOwner | QFile::ExeUser)) mode |= S_IXUSR; if (permissions & QFile::ReadGroup) mode |= S_IRGRP; diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 5cca3c323ec000e514d25950e986c4bd80d3eb7c..379095a83da6b5fd2dd4fe9dd6e5be8ee78308f7 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -407,7 +407,7 @@ static QString readLink(const QFileSystemEntry &link) Q_UNUSED(link); return QString(); #endif // QT_NO_LIBRARY -#else +#elif !defined(QT_NO_WINCE_SHELLSDK) wchar_t target[MAX_PATH]; QString result; if (SHGetShortcutTarget((wchar_t*)QFileInfo(link.filePath()).absoluteFilePath().replace(QLatin1Char('/'),QLatin1Char('\\')).utf16(), target, MAX_PATH)) { @@ -418,6 +418,9 @@ static QString readLink(const QFileSystemEntry &link) result.remove(result.size()-1,1); } return result; +#else // QT_NO_WINCE_SHELLSDK + Q_UNUSED(link); + return QString(); #endif // Q_OS_WINCE } @@ -1437,11 +1440,9 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per Q_UNUSED(data); int mode = 0; - if (permissions & QFile::ReadOwner || permissions & QFile::ReadUser - || permissions & QFile::ReadGroup || permissions & QFile::ReadOther) + if (permissions & (QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther)) mode |= _S_IREAD; - if (permissions & QFile::WriteOwner || permissions & QFile::WriteUser - || permissions & QFile::WriteGroup || permissions & QFile::WriteOther) + if (permissions & (QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther)) mode |= _S_IWRITE; if (mode == 0) // not supported diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp index 3a8f7bd0a9ce5fb11df0c202b2229d6f6501387c..7fc3049f46f7082fb42828ed7c4d1e6bf66be2ce 100644 --- a/src/corelib/io/qfilesystemwatcher.cpp +++ b/src/corelib/io/qfilesystemwatcher.cpp @@ -185,7 +185,7 @@ void QFileSystemWatcherPrivate::_q_directoryChanged(const QString &path, bool re the file system monitor. Also note that your process may have other file descriptors open in addition to the ones for files being monitored, and these other open descriptors also count in - the total. OS X 10.5 and up use a different backend and do not + the total. Mac OS X 10.5 and up use a different backend and do not suffer from this issue. diff --git a/src/corelib/io/qfilesystemwatcher.h b/src/corelib/io/qfilesystemwatcher.h index 13d1782913320d0eeaf52638e1ca0443c12dd842..095b50d1e5009e1841107635f6444c8d03e00b7c 100644 --- a/src/corelib/io/qfilesystemwatcher.h +++ b/src/corelib/io/qfilesystemwatcher.h @@ -49,8 +49,8 @@ class Q_CORE_EXPORT QFileSystemWatcher : public QObject Q_DECLARE_PRIVATE(QFileSystemWatcher) public: - QFileSystemWatcher(QObject *parent = 0); - QFileSystemWatcher(const QStringList &paths, QObject *parent = 0); + QFileSystemWatcher(QObject *parent = Q_NULLPTR); + QFileSystemWatcher(const QStringList &paths, QObject *parent = Q_NULLPTR); ~QFileSystemWatcher(); bool addPath(const QString &file); diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp index 039992adba1bfaa6967dd3ebf8f8917764284834..4907a20a5fd48df4c1d1b2a214356d0202f93bdd 100644 --- a/src/corelib/io/qfilesystemwatcher_win.cpp +++ b/src/corelib/io/qfilesystemwatcher_win.cpp @@ -248,6 +248,7 @@ QStringList QWindowsFileSystemWatcherEngine::removePaths(const QStringList &path // ### files->removeAll(path); directories->removeAll(path); + it.remove(); if (h.isEmpty()) { DEBUG() << "Closing handle" << handle.handle; @@ -260,8 +261,6 @@ QStringList QWindowsFileSystemWatcherEngine::removePaths(const QStringList &path thread->handleForDir.remove(QFileSystemWatcherPathKey(absolutePath)); // h is now invalid - it.remove(); - if (thread->handleForDir.isEmpty()) { DEBUG() << "Stopping thread " << thread; locker.unlock(); diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 19343f22ffc58f6a997ef79665a587c27f4dc552..cfd50955a6a8f3d6c3e630ef99acd2da72c05c5b 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -711,7 +711,7 @@ bool QFSFileEngine::link(const QString &newName) Q_UNUSED(newName); return false; #endif // QT_NO_LIBRARY -#elif defined(Q_OS_WINCE) +#elif defined(Q_OS_WINCE) && !defined(QT_NO_WINCE_SHELLSDK) QString linkName = newName; linkName.replace(QLatin1Char('/'), QLatin1Char('\\')); if (!linkName.endsWith(QLatin1String(".lnk"))) @@ -724,7 +724,7 @@ bool QFSFileEngine::link(const QString &newName) if (!ret) setError(QFile::RenameError, qt_error_string()); return ret; -#else // Q_OS_WINCE +#else // Q_OS_WINCE && !QT_NO_WINCE_SHELLSDK Q_UNUSED(newName); Q_UNIMPLEMENTED(); return false; diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 07a2ff8f6b398a862affeeab2f70318fbc49e2c7..84a6a1d9cbf7ebb613654b31b8dbc5ece7d1e164 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -39,6 +39,7 @@ #include "qfile.h" #include "qstringlist.h" #include "qdir.h" +#include "private/qbytearray_p.h" #include <algorithm> @@ -138,7 +139,6 @@ QIODevicePrivate::QIODevicePrivate() : openMode(QIODevice::NotOpen), buffer(QIODEVICE_BUFFERSIZE), pos(0), devicePos(0) , baseReadLineDataCalled(false) - , firstRead(true) , accessMode(Unset) #ifdef QT_NO_QOBJECT , q_ptr(0) @@ -463,7 +463,6 @@ void QIODevice::setOpenMode(OpenMode openMode) #endif d->openMode = openMode; d->accessMode = QIODevicePrivate::Unset; - d->firstRead = true; if (!isReadable()) d->buffer.clear(); } @@ -555,7 +554,6 @@ bool QIODevice::open(OpenMode mode) d->pos = (mode & Append) ? size() : qint64(0); d->buffer.clear(); d->accessMode = QIODevicePrivate::Unset; - d->firstRead = true; #if defined QIODEVICE_DEBUG printf("%p QIODevice::open(0x%x)\n", this, quint32(mode)); #endif @@ -585,7 +583,6 @@ void QIODevice::close() d->errorString.clear(); d->pos = 0; d->buffer.clear(); - d->firstRead = true; } /*! @@ -692,12 +689,13 @@ bool QIODevice::seek(qint64 pos) bool QIODevice::atEnd() const { Q_D(const QIODevice); + const bool result = (d->openMode == NotOpen || (d->buffer.isEmpty() + && bytesAvailable() == 0)); #if defined QIODEVICE_DEBUG printf("%p QIODevice::atEnd() returns %s, d->openMode == %d, d->pos == %lld\n", this, - (d->openMode == NotOpen || d->pos == size()) ? "true" : "false", int(d->openMode), - d->pos); + result ? "true" : "false", int(d->openMode), d->pos); #endif - return d->openMode == NotOpen || (d->buffer.isEmpty() && bytesAvailable() == 0); + return result; } /*! @@ -814,12 +812,7 @@ qint64 QIODevice::read(char *data, qint64 maxSize) bufferReadChunkSize, readSoFar - bufferReadChunkSize); #endif } else { - if (d->firstRead) { - // this is the first time the file has been read, check it's valid and set up pos pointers - // for fast pos updates. - CHECK_READABLE(read, qint64(-1)); - d->firstRead = false; - } + CHECK_READABLE(read, qint64(-1)); } if (maxSize > 0 && !deviceAtEof) { @@ -941,9 +934,9 @@ QByteArray QIODevice::read(qint64 maxSize) Q_UNUSED(d); #endif - if (quint64(maxSize) >= QByteArray::MaxSize) { + if (maxSize >= MaxByteArraySize) { checkWarnMessage(this, "read", "maxSize argument exceeds QByteArray size limit"); - maxSize = QByteArray::MaxSize - 1; + maxSize = MaxByteArraySize - 1; } qint64 readBytes = 0; @@ -990,40 +983,31 @@ QByteArray QIODevice::readAll() #endif QByteArray result; - qint64 readBytes = 0; - const bool sequential = d->isSequential(); - - // flush internal read buffer - if (!(d->openMode & Text) && !d->buffer.isEmpty()) { - if (quint64(d->buffer.size()) >= QByteArray::MaxSize) - return QByteArray(); - result = d->buffer.readAll(); - readBytes = result.size(); - if (!sequential) - d->pos += readBytes; - } - - qint64 theSize; - if (sequential || (theSize = size()) == 0) { + qint64 readBytes = (d->isSequential() ? Q_INT64_C(0) : size()); + if (readBytes == 0) { // Size is unknown, read incrementally. + qint64 readChunkSize = qMax(d->buffer.size(), QIODEVICE_BUFFERSIZE); qint64 readResult; do { - if (quint64(readBytes) + QIODEVICE_BUFFERSIZE >= QByteArray::MaxSize) { + if (readBytes + readChunkSize >= MaxByteArraySize) { // If resize would fail, don't read more, return what we have. break; } - result.resize(readBytes + QIODEVICE_BUFFERSIZE); - readResult = read(result.data() + readBytes, QIODEVICE_BUFFERSIZE); - if (readResult > 0 || readBytes == 0) + result.resize(readBytes + readChunkSize); + readResult = read(result.data() + readBytes, readChunkSize); + if (readResult > 0 || readBytes == 0) { readBytes += readResult; + readChunkSize = QIODEVICE_BUFFERSIZE; + } } while (readResult > 0); } else { // Read it all in one go. // If resize fails, don't read anything. - if (quint64(readBytes + theSize - d->pos) >= QByteArray::MaxSize) + readBytes -= d->pos; + if (readBytes >= MaxByteArraySize) return QByteArray(); - result.resize(int(readBytes + theSize - d->pos)); - readBytes += read(result.data() + readBytes, result.size() - readBytes); + result.resize(readBytes); + readBytes = read(result.data(), readBytes); } if (readBytes <= 0) @@ -1178,9 +1162,9 @@ QByteArray QIODevice::readLine(qint64 maxSize) Q_UNUSED(d); #endif - if (quint64(maxSize) >= QByteArray::MaxSize) { + if (maxSize >= MaxByteArraySize) { qWarning("QIODevice::read: maxSize argument exceeds QByteArray size limit"); - maxSize = QByteArray::MaxSize - 1; + maxSize = MaxByteArraySize - 1; } result.resize(int(maxSize)); @@ -1188,7 +1172,7 @@ QByteArray QIODevice::readLine(qint64 maxSize) if (!result.size()) { // If resize fails or maxSize == 0, read incrementally if (maxSize == 0) - maxSize = QByteArray::MaxSize - 1; + maxSize = MaxByteArraySize - 1; // The first iteration needs to leave an extra byte for the terminating null result.resize(1); diff --git a/src/corelib/io/qiodevice.h b/src/corelib/io/qiodevice.h index 4f45805fca3b35fe619bece572b55c26b9381deb..b62c8d266c20649a157402b70426caea6e0121c3 100644 --- a/src/corelib/io/qiodevice.h +++ b/src/corelib/io/qiodevice.h @@ -140,7 +140,7 @@ protected: #ifdef QT_NO_QOBJECT QIODevice(QIODevicePrivate &dd); #else - QIODevice(QIODevicePrivate &dd, QObject *parent = 0); + QIODevice(QIODevicePrivate &dd, QObject *parent = Q_NULLPTR); #endif virtual qint64 readData(char *data, qint64 maxlen) = 0; virtual qint64 readLineData(char *data, qint64 maxlen); diff --git a/src/corelib/io/qiodevice_p.h b/src/corelib/io/qiodevice_p.h index f4cf387eb505bb966a5b236af2ac08f03954559d..56a89ab680ac52da218cf0207b2115c1e6dab162 100644 --- a/src/corelib/io/qiodevice_p.h +++ b/src/corelib/io/qiodevice_p.h @@ -212,7 +212,6 @@ public: qint64 pos; qint64 devicePos; bool baseReadLineDataCalled; - bool firstRead; virtual bool putCharHelper(char c); diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index d6ea2f1f2db605696c1e89031fc7acab63ef1c69..815c0f025bab26f9b463927cf3ff157ada0685ca 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -56,6 +56,7 @@ # include <cstdio> #elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) # include <sys/user.h> +# include <libutil.h> #endif QT_BEGIN_NAMESPACE @@ -218,24 +219,25 @@ QString QLockFilePrivate::processNameByPid(qint64 pid) #if defined(Q_OS_OSX) char name[1024]; proc_name(pid, name, sizeof(name) / sizeof(char)); - return QString::fromUtf8(name); + return QFile::decodeName(name); #elif defined(Q_OS_LINUX) if (!QFile::exists(QStringLiteral("/proc/version"))) return QString(); char exePath[64]; - char buf[PATH_MAX]; - memset(buf, 0, sizeof(buf)); + char buf[PATH_MAX + 1]; sprintf(exePath, "/proc/%lld/exe", pid); - if (readlink(exePath, buf, sizeof(buf)) < 0) { + size_t len = (size_t)readlink(exePath, buf, sizeof(buf)); + if (len >= sizeof(buf)) { // The pid is gone. Return some invalid process name to fail the test. return QStringLiteral("/ERROR/"); } - return QFileInfo(QString::fromUtf8(buf)).fileName(); + buf[len] = 0; + return QFileInfo(QFile::decodeName(buf)).fileName(); #elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) kinfo_proc *proc = kinfo_getproc(pid); if (!proc) return QString(); - QString name = QString::fromUtf8(proc->ki_comm); + QString name = QFile::decodeName(proc->ki_comm); free(proc); return name; #else diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index e6bc7caaebcdc04d9cae8257db041558ab6cf078..1d06e2a912d432a56fa6a59ee52516a525ef277d 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -147,6 +147,14 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift) \c QT_LOGGING_CONF, and rules set by \c QT_LOGGING_RULES. + Since Qt 5.6, \c QT_LOGGING_RULES may contain multiple rules separated + by semicolons: + + \code + QT_LOGGING_RULES="*.debug=false;driver.usb.debug=true" + \endcode + + Order of evaluation: \list \li QtProject/qtlogging.ini diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp index 7f2ce319eea87436406b4f0f15f0c642868fa052..ed775d62e08324640e7ff46cef19110a40dfb4f1 100644 --- a/src/corelib/io/qloggingregistry.cpp +++ b/src/corelib/io/qloggingregistry.cpp @@ -210,20 +210,23 @@ void QLoggingSettingsParser::setContent(QTextStream &stream) if (_section == QLatin1String("Rules")) { int equalPos = line.indexOf(QLatin1Char('=')); - if ((equalPos != -1) - && (line.lastIndexOf(QLatin1Char('=')) == equalPos)) { - const QStringRef pattern = line.leftRef(equalPos); - const QStringRef valueStr = line.midRef(equalPos + 1); - int value = -1; - if (valueStr == QLatin1String("true")) - value = 1; - else if (valueStr == QLatin1String("false")) - value = 0; - QLoggingRule rule(pattern, (value == 1)); - if (rule.flags != 0 && (value != -1)) - _rules.append(rule); - else + if (equalPos != -1) { + if (line.lastIndexOf(QLatin1Char('=')) == equalPos) { + const QStringRef pattern = line.leftRef(equalPos); + const QStringRef valueStr = line.midRef(equalPos + 1); + int value = -1; + if (valueStr == QLatin1String("true")) + value = 1; + else if (valueStr == QLatin1String("false")) + value = 0; + QLoggingRule rule(pattern, (value == 1)); + if (rule.flags != 0 && (value != -1)) + _rules.append(rule); + else + warnMsg("Ignoring malformed logging rule: '%s'", line.toUtf8().constData()); + } else { warnMsg("Ignoring malformed logging rule: '%s'", line.toUtf8().constData()); + } } } } @@ -265,7 +268,7 @@ void QLoggingRegistry::init() envRules = parser.rules(); } } - const QByteArray rulesSrc = qgetenv("QT_LOGGING_RULES"); + const QByteArray rulesSrc = qgetenv("QT_LOGGING_RULES").replace(';', '\n'); if (!rulesSrc.isEmpty()) { QTextStream stream(rulesSrc); QLoggingSettingsParser parser; diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 0b999ab229cac0e171798c84dc0a382feb7ef6b8..2d826f093d5cb98546900b1b7ea5ddd60c87acc2 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -100,6 +100,19 @@ QT_END_NAMESPACE QT_BEGIN_NAMESPACE +/*! + \since 5.6 + + \macro QT_NO_PROCESS_COMBINED_ARGUMENT_START + \relates QProcess + + Disables the QProcess::start() overload taking a single string. + In most cases where it is used, the user intends for the first argument + to be treated atomically as per the other overload. + + \sa QProcess::start() +*/ + /*! \class QProcessEnvironment \inmodule QtCore @@ -264,11 +277,16 @@ bool QProcessEnvironment::operator==(const QProcessEnvironment &other) const { if (d == other.d) return true; - if (d && other.d) { - QProcessEnvironmentPrivate::OrderedMutexLocker locker(d, other.d); - return d->hash == other.d->hash; + if (d) { + if (other.d) { + QProcessEnvironmentPrivate::OrderedMutexLocker locker(d, other.d); + return d->hash == other.d->hash; + } else { + return isEmpty(); + } + } else { + return other.isEmpty(); } - return false; } /*! @@ -497,8 +515,8 @@ void QProcessPrivate::Channel::clear() the process as arguments, and you can also call exitCode() to obtain the exit code of the last process that finished, and exitStatus() to obtain its exit status. If an error occurs at - any point in time, QProcess will emit the error() signal. You - can also call error() to find the type of error that occurred + any point in time, QProcess will emit the errorOccurred() signal. + You can also call error() to find the type of error that occurred last, and state() to find the current process state. \section1 Communicating via Channels @@ -735,6 +753,14 @@ void QProcessPrivate::Channel::clear() /*! \fn void QProcess::error(QProcess::ProcessError error) + \obsolete + + Use errorOccurred() instead. +*/ + +/*! + \fn void QProcess::errorOccurred(QProcess::ProcessError error) + \since 5.6 This signal is emitted when an error occurs with the process. The specified \a error describes the type of error that occurred. @@ -895,6 +921,50 @@ void QProcessPrivate::cleanup() #endif } +/*! + \internal +*/ +void QProcessPrivate::setError(QProcess::ProcessError error, const QString &description) +{ + processError = error; + if (description.isEmpty()) { + switch (error) { + case QProcess::FailedToStart: + errorString = QProcess::tr("Process failed to start"); + break; + case QProcess::Crashed: + errorString = QProcess::tr("Process crashed"); + break; + case QProcess::Timedout: + errorString = QProcess::tr("Process operation timed out"); + break; + case QProcess::ReadError: + errorString = QProcess::tr("Error reading from process"); + break; + case QProcess::WriteError: + errorString = QProcess::tr("Error writing to process"); + break; + case QProcess::UnknownError: + errorString.clear(); + break; + } + } else { + errorString = description; + } +} + +/*! + \internal +*/ +void QProcessPrivate::setErrorAndEmit(QProcess::ProcessError error, const QString &description) +{ + Q_Q(QProcess); + Q_ASSERT(error != QProcess::UnknownError); + setError(error, description); + emit q->errorOccurred(processError); + emit q->error(processError); +} + /*! \internal Returns true if we emitted readyRead(). @@ -918,9 +988,7 @@ bool QProcessPrivate::tryReadFromChannel(Channel *channel) return false; } if (readBytes == -1) { - processError = QProcess::ReadError; - q->setErrorString(QProcess::tr("Error reading from process")); - emit q->error(processError); + setErrorAndEmit(QProcess::ReadError); #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::tryReadFromChannel(%d), failed to read from the process", channel - &stdinChannel); #endif @@ -1004,9 +1072,7 @@ bool QProcessPrivate::_q_canWrite() stdinChannel.buffer.nextDataBlockSize()); if (written < 0) { closeChannel(&stdinChannel); - processError = QProcess::WriteError; - q->setErrorString(QProcess::tr("Error writing to process")); - emit q->error(processError); + setErrorAndEmit(QProcess::WriteError); return false; } @@ -1050,7 +1116,7 @@ bool QProcessPrivate::_q_processDied() // the process may have died before it got a chance to report that it was // either running or stopped, so we will call _q_startupNotification() and - // give it a chance to emit started() or error(FailedToStart). + // give it a chance to emit started() or errorOccurred(FailedToStart). if (processState == QProcess::Starting) { if (!_q_startupNotification()) return true; @@ -1075,9 +1141,7 @@ bool QProcessPrivate::_q_processDied() if (crashed) { exitStatus = QProcess::CrashExit; - processError = QProcess::Crashed; - q->setErrorString(QProcess::tr("Process crashed")); - emit q->error(processError); + setErrorAndEmit(QProcess::Crashed); } else { #ifdef QPROCESS_USE_SPAWN // if we're using posix_spawn, waitForStarted always succeeds. @@ -1085,8 +1149,8 @@ bool QProcessPrivate::_q_processDied() // 127 if anything prevents the target program from starting. // http://pubs.opengroup.org/onlinepubs/009695399/functions/posix_spawn.html if (exitStatus == QProcess::NormalExit && exitCode == 127) { - processError = QProcess::FailedToStart; - q->setErrorString(QProcess::tr("Process failed to start (spawned process exited with code 127)")); + setError(QProcess::FailedToStart, + QProcess::tr("Process failed to start (spawned process exited with code 127)")); } #endif } @@ -1130,8 +1194,7 @@ bool QProcessPrivate::_q_startupNotification() } q->setProcessState(QProcess::NotRunning); - processError = QProcess::FailedToStart; - emit q->error(processError); + setErrorAndEmit(QProcess::FailedToStart); #ifdef Q_OS_UNIX // make sure the process manager removes this entry waitForDeadChild(); @@ -1939,9 +2002,7 @@ qint64 QProcess::writeData(const char *data, qint64 len) #if defined(Q_OS_WINCE) Q_UNUSED(data); Q_UNUSED(len); - d->processError = QProcess::WriteError; - setErrorString(tr("Error writing to process")); - emit error(d->processError); + d->setErrorAndEmit(QProcess::WriteError); return -1; #endif @@ -2032,10 +2093,10 @@ QByteArray QProcess::readAllStandardError() The QProcess object will immediately enter the Starting state. If the process starts successfully, QProcess will emit started(); otherwise, - error() will be emitted. + errorOccurred() will be emitted. \note Processes are started asynchronously, which means the started() - and error() signals may be delayed. Call waitForStarted() to make + and errorOccurred() signals may be delayed. Call waitForStarted() to make sure the process has started (or has failed to start) and those signals have been emitted. @@ -2052,7 +2113,7 @@ QByteArray QProcess::readAllStandardError() printed at the console, and the existing process will continue running unaffected. - \sa pid(), started(), waitForStarted(), setNativeArguments() + \sa processId(), started(), waitForStarted(), setNativeArguments() */ void QProcess::start(const QString &program, const QStringList &arguments, OpenMode mode) { @@ -2214,15 +2275,26 @@ static QStringList parseCombinedArgString(const QString &program) After the \a command string has been split and unquoted, this function behaves like the overload which takes the arguments as a string list. + You can disable this overload by defining \c + QT_NO_PROCESS_COMBINED_ARGUMENT_START when you compile your applications. + This can be useful if you want to ensure that you are not splitting arguments + unintentionally, for example. In virtually all cases, using the other overload + is the preferred method. + + On operating systems where the system API for passing command line + arguments to a subprocess natively uses a single string (Windows), one can + conceive command lines which cannot be passed via QProcess's portable + list-based API. In these rare cases you need to use setProgram() and + setNativeArguments() instead of this function. + */ +#if !defined(QT_NO_PROCESS_COMBINED_ARGUMENT_START) void QProcess::start(const QString &command, OpenMode mode) { QStringList args = parseCombinedArgString(command); if (args.isEmpty()) { Q_D(QProcess); - d->processError = QProcess::FailedToStart; - setErrorString(tr("No program defined")); - emit error(d->processError); + d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined")); return; } @@ -2231,6 +2303,7 @@ void QProcess::start(const QString &command, OpenMode mode) start(prog, args, mode); } +#endif /*! \since 5.0 diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h index 32fa4aa866a3fc5e831480de858ce96ee479f4df..f95358250ee735679a2ba96b1c80b8163609cfd8 100644 --- a/src/corelib/io/qprocess.h +++ b/src/corelib/io/qprocess.h @@ -60,9 +60,12 @@ public: QProcessEnvironment(); QProcessEnvironment(const QProcessEnvironment &other); ~QProcessEnvironment(); +#ifdef Q_COMPILER_RVALUE_REFS + QProcessEnvironment &operator=(QProcessEnvironment && other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QProcessEnvironment &operator=(const QProcessEnvironment &other); - inline void swap(QProcessEnvironment &other) { qSwap(d, other.d); } + void swap(QProcessEnvironment &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool operator==(const QProcessEnvironment &other) const; inline bool operator!=(const QProcessEnvironment &other) const @@ -140,11 +143,13 @@ public: }; Q_ENUM(ExitStatus) - explicit QProcess(QObject *parent = 0); + explicit QProcess(QObject *parent = Q_NULLPTR); virtual ~QProcess(); void start(const QString &program, const QStringList &arguments, OpenMode mode = ReadWrite); +#if !defined(QT_NO_PROCESS_COMBINED_ARGUMENT_START) void start(const QString &command, OpenMode mode = ReadWrite); +#endif void start(OpenMode mode = ReadWrite); bool open(OpenMode mode = ReadWrite) Q_DECL_OVERRIDE; @@ -219,7 +224,7 @@ public: #if defined(Q_QDOC) = QString() #endif - , qint64 *pid = 0); + , qint64 *pid = Q_NULLPTR); #if !defined(Q_QDOC) static bool startDetached(const QString &program, const QStringList &arguments); // ### Qt6: merge overloads #endif @@ -237,7 +242,10 @@ Q_SIGNALS: void started(QPrivateSignal); void finished(int exitCode); // ### Qt 6: merge the two signals with a default value void finished(int exitCode, QProcess::ExitStatus exitStatus); - void error(QProcess::ProcessError error); +#if QT_DEPRECATED_SINCE(5,6) + QT_MOC_COMPAT void error(QProcess::ProcessError error); +#endif + void errorOccurred(QProcess::ProcessError error); void stateChanged(QProcess::ProcessState state, QPrivateSignal); void readyReadStandardOutput(QPrivateSignal); diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index f6bd64fb876ce02c76658a4eb8d83dbacc38c16d..fc6b5345d150579a3375bd0ca3753ed474a96d1c 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -383,6 +383,8 @@ public: qint64 writeToStdin(const char *data, qint64 maxlen); void cleanup(); + void setError(QProcess::ProcessError error, const QString &description = QString()); + void setErrorAndEmit(QProcess::ProcessError error, const QString &description = QString()); #ifdef Q_OS_BLACKBERRY QList<QSocketNotifier *> defaultNotifiers() const; diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 5ea3bf8982c7dec77504d3d8d2cdad1ac386afa1..63480dfc6b6c9ac78e7933b85391a55571c4039b 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -203,8 +203,8 @@ bool QProcessPrivate::openChannel(Channel &channel) channel.pipe[1] = -1; if ( (channel.pipe[0] = qt_safe_open(fname, O_RDONLY)) != -1) return true; // success - - q->setErrorString(QProcess::tr("Could not open input redirection for reading")); + setErrorAndEmit(QProcess::FailedToStart, + QProcess::tr("Could not open input redirection for reading")); } else { int mode = O_WRONLY | O_CREAT; if (channel.append) @@ -216,12 +216,9 @@ bool QProcessPrivate::openChannel(Channel &channel) if ( (channel.pipe[1] = qt_safe_open(fname, mode, 0666)) != -1) return true; // success - q->setErrorString(QProcess::tr("Could not open output redirection for writing")); + setErrorAndEmit(QProcess::FailedToStart, + QProcess::tr("Could not open input redirection for reading")); } - - // could not open file - processError = QProcess::FailedToStart; - emit q->error(processError); cleanup(); return false; } else { @@ -330,9 +327,7 @@ void QProcessPrivate::startProcess() !openChannel(stdoutChannel) || !openChannel(stderrChannel) || qt_create_pipe(childStartedPipe) != 0) { - processError = QProcess::FailedToStart; - q->setErrorString(qt_error_string(errno)); - emit q->error(processError); + setErrorAndEmit(QProcess::FailedToStart, qt_error_string(errno)); cleanup(); return; } @@ -458,9 +453,8 @@ void QProcessPrivate::startProcess() qDebug("fork failed: %s", qPrintable(qt_error_string(lastForkErrno))); #endif q->setProcessState(QProcess::NotRunning); - processError = QProcess::FailedToStart; - q->setErrorString(QProcess::tr("Resource error (fork failure): %1").arg(qt_error_string(lastForkErrno))); - emit q->error(processError); + setErrorAndEmit(QProcess::FailedToStart, + QProcess::tr("Resource error (fork failure): %1").arg(qt_error_string(lastForkErrno))); cleanup(); return; } @@ -678,9 +672,9 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv qt_safe_close(childStartedPipe[0]); // enter the working directory - if (workingDir) { - if (QT_CHDIR(workingDir) == -1) - qWarning("QProcessPrivate::execChild() failed to chdir to %s", workingDir); + if (workingDir && QT_CHDIR(workingDir) == -1) { + // failed, stop the process + goto report_errno; } // this is a virtual call, and it base behavior is to do nothing. @@ -709,6 +703,7 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv } // notify failure +report_errno: QString error = qt_error_string(errno); #if defined (QPROCESS_DEBUG) fprintf(stderr, "QProcessPrivate::execChild() failed (%s), notifying parent process\n", qPrintable(error)); @@ -808,8 +803,6 @@ void QProcessPrivate::killProcess() bool QProcessPrivate::waitForStarted(int msecs) { - Q_Q(QProcess); - #if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForStarted(%d) waiting for child to start (fd = %d)", msecs, childStartedPipe[0]); @@ -819,8 +812,7 @@ bool QProcessPrivate::waitForStarted(int msecs) FD_ZERO(&fds); FD_SET(childStartedPipe[0], &fds); if (qt_select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) { - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); #if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForStarted(%d) == false (timed out)", msecs); #endif @@ -847,7 +839,6 @@ QList<QSocketNotifier *> QProcessPrivate::defaultNotifiers() const bool QProcessPrivate::waitForReadyRead(int msecs) { - Q_Q(QProcess); #if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForReadyRead(%d)", msecs); #endif @@ -890,8 +881,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs) break; } if (ret == 0) { - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } @@ -927,7 +917,6 @@ bool QProcessPrivate::waitForReadyRead(int msecs) bool QProcessPrivate::waitForBytesWritten(int msecs) { - Q_Q(QProcess); #if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForBytesWritten(%d)", msecs); #endif @@ -972,8 +961,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) } if (ret == 0) { - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } @@ -1002,7 +990,6 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) bool QProcessPrivate::waitForFinished(int msecs) { - Q_Q(QProcess); #if defined (QPROCESS_DEBUG) qDebug("QProcessPrivate::waitForFinished(%d)", msecs); #endif @@ -1046,8 +1033,7 @@ bool QProcessPrivate::waitForFinished(int msecs) break; } if (ret == 0) { - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } @@ -1090,17 +1076,17 @@ bool QProcessPrivate::waitForDeadChild() return true; // child has already exited // read the process information from our fd - siginfo_t info; - qint64 ret = qt_safe_read(forkfd, &info, sizeof info); - Q_ASSERT(ret == sizeof info); - Q_UNUSED(ret); + forkfd_info info; + int ret; + EINTR_LOOP(ret, forkfd_wait(forkfd, &info, Q_NULLPTR)); - Q_ASSERT(info.si_pid == pid_t(pid)); + exitCode = info.status; + crashed = info.code != CLD_EXITED; - exitCode = info.si_status; - crashed = info.si_code != CLD_EXITED; + delete deathNotifier; + deathNotifier = 0; - qt_safe_close(forkfd); + EINTR_LOOP(ret, forkfd_close(forkfd)); forkfd = -1; // Child is dead, don't try to kill it anymore #if defined QPROCESS_DEBUG diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index cef961ecbde26b4aa3e0e6d032de5e9ae83a0986..5c9db05efffe9bbcb26567a05691fe980b28dd65 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -217,7 +217,8 @@ bool QProcessPrivate::openChannel(Channel &channel) if (channel.pipe[0] != INVALID_Q_PIPE) return true; - q->setErrorString(QProcess::tr("Could not open input redirection for reading")); + setErrorAndEmit(QProcess::FailedToStart, + QProcess::tr("Could not open input redirection for reading")); } else { // open in write mode channel.pipe[0] = INVALID_Q_PIPE; @@ -237,12 +238,9 @@ bool QProcessPrivate::openChannel(Channel &channel) return true; } - q->setErrorString(QProcess::tr("Could not open output redirection for writing")); + setErrorAndEmit(QProcess::FailedToStart, + QProcess::tr("Could not open output redirection for writing")); } - - // could not open file - processError = QProcess::FailedToStart; - emit q->error(processError); cleanup(); return false; } else { @@ -504,9 +502,10 @@ void QProcessPrivate::startProcess() environment.isEmpty() ? 0 : envlist.data(), workingDirectory.isEmpty() ? 0 : (wchar_t*)QDir::toNativeSeparators(workingDirectory).utf16(), &startupInfo, pid); + QString errorString; if (!success) { // Capture the error string before we do CloseHandle below - q->setErrorString(QProcess::tr("Process failed to start: %1").arg(qt_error_string())); + errorString = QProcess::tr("Process failed to start: %1").arg(qt_error_string()); } if (stdinChannel.pipe[0] != INVALID_Q_PIPE) { @@ -524,8 +523,7 @@ void QProcessPrivate::startProcess() if (!success) { cleanup(); - processError = QProcess::FailedToStart; - emit q->error(processError); + setErrorAndEmit(QProcess::FailedToStart, errorString); q->setProcessState(QProcess::NotRunning); return; } @@ -595,16 +593,13 @@ void QProcessPrivate::killProcess() bool QProcessPrivate::waitForStarted(int) { - Q_Q(QProcess); - if (processStarted()) return true; if (processError == QProcess::FailedToStart) return false; - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } @@ -636,8 +631,6 @@ bool QProcessPrivate::drainOutputPipes() bool QProcessPrivate::waitForReadyRead(int msecs) { - Q_Q(QProcess); - QIncrementalSleepTimer timer(msecs); forever { @@ -652,7 +645,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs) if (!pid) return false; - if (WaitForSingleObject(pid->hProcess, 0) == WAIT_OBJECT_0) { + if (WaitForSingleObjectEx(pid->hProcess, 0, false) == WAIT_OBJECT_0) { bool readyReadEmitted = drainOutputPipes(); _q_processDied(); return readyReadEmitted; @@ -663,15 +656,12 @@ bool QProcessPrivate::waitForReadyRead(int msecs) break; } - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } bool QProcessPrivate::waitForBytesWritten(int msecs) { - Q_Q(QProcess); - QIncrementalSleepTimer timer(msecs); forever { @@ -721,7 +711,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) // Wait for the process to signal any change in its state, // such as incoming data, or if the process died. - if (WaitForSingleObject(pid->hProcess, 0) == WAIT_OBJECT_0) { + if (WaitForSingleObjectEx(pid->hProcess, 0, false) == WAIT_OBJECT_0) { _q_processDied(); return false; } @@ -731,14 +721,12 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) break; } - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } bool QProcessPrivate::waitForFinished(int msecs) { - Q_Q(QProcess); #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::waitForFinished(%d)", msecs); #endif @@ -770,8 +758,7 @@ bool QProcessPrivate::waitForFinished(int msecs) break; } - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } @@ -814,13 +801,10 @@ qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) bool QProcessPrivate::waitForWrite(int msecs) { - Q_Q(QProcess); - if (!stdinChannel.writer || stdinChannel.writer->waitForWrite(msecs)) return true; - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } diff --git a/src/corelib/io/qprocess_wince.cpp b/src/corelib/io/qprocess_wince.cpp index 53767758c278bf70b594c729b599c1bb6c8f8007..807472b7b20fe30ecb502bd5f809ef8b206af69e 100644 --- a/src/corelib/io/qprocess_wince.cpp +++ b/src/corelib/io/qprocess_wince.cpp @@ -138,8 +138,7 @@ void QProcessPrivate::startProcess() if (!success) { cleanup(); - processError = QProcess::FailedToStart; - emit q->error(processError); + setErrorAndEmit(QProcess::FailedToStart); q->setProcessState(QProcess::NotRunning); return; } @@ -210,8 +209,7 @@ bool QProcessPrivate::waitForStarted(int) if (processError == QProcess::FailedToStart) return false; - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } @@ -251,8 +249,7 @@ bool QProcessPrivate::waitForFinished(int msecs) if (timer.hasTimedOut()) break; } - processError = QProcess::Timedout; - q->setErrorString(QProcess::tr("Process operation timed out")); + setError(QProcess::Timedout); return false; } diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index fbda081114d046747f2a0d44638f01cd86410cdf..345f0bd65ddfe16ca03c0f5138df2062b79e0ee9 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -790,6 +790,7 @@ QStringList QResourceRoot::children(int node) const offset += 4; const int child_off = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); + ret.reserve(child_count); for(int i = child_off; i < child_off+child_count; ++i) ret << name(i); } diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp index ffa6ad1c55df84c55b805b2171146dcad308b361..5a325f8e2ccf1995b8a6a068260d39f5f0ebf225 100644 --- a/src/corelib/io/qsavefile.cpp +++ b/src/corelib/io/qsavefile.cpp @@ -215,7 +215,8 @@ bool QSaveFile::open(OpenMode mode) d->finalFileName = existingFile.filePath(); } - d->fileEngine = new QTemporaryFileEngine(d->finalFileName, 0666); + d->fileEngine = new QTemporaryFileEngine; + static_cast<QTemporaryFileEngine *>(d->fileEngine)->initialize(d->finalFileName, 0666); // Same as in QFile: QIODevice provides the buffering, so there's no need to request it from the file engine. if (!d->fileEngine->open(mode | QIODevice::Unbuffered)) { QFileDevice::FileError err = d->fileEngine->error(); diff --git a/src/corelib/io/qsavefile.h b/src/corelib/io/qsavefile.h index 3f5f09bf5c1c983c3dcc487853233da72e0fcda8..085378ed4e2931b8e5205214c7bacd814355c545 100644 --- a/src/corelib/io/qsavefile.h +++ b/src/corelib/io/qsavefile.h @@ -58,7 +58,7 @@ class Q_CORE_EXPORT QSaveFile : public QFileDevice public: explicit QSaveFile(const QString &name); - explicit QSaveFile(QObject *parent = 0); + explicit QSaveFile(QObject *parent = Q_NULLPTR); explicit QSaveFile(const QString &name, QObject *parent); ~QSaveFile(); diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 251b10ea89563f269474d34a00aefa4e8b0ae0cc..da4a02e4e4327e352eb87107871b461fe32089a8 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -127,6 +127,7 @@ struct QConfFileCustomFormat QSettings::WriteFunc writeFunc; Qt::CaseSensitivity caseSensitivity; }; +Q_DECLARE_TYPEINFO(QConfFileCustomFormat, Q_MOVABLE_TYPE); typedef QHash<QString, QConfFile *> ConfFileHash; typedef QCache<QString, QConfFile> ConfFileCache; @@ -299,7 +300,7 @@ QSettingsPrivate *QSettingsPrivate::create(const QString &fileName, QSettings::F } #endif -void QSettingsPrivate::processChild(QString key, ChildSpec spec, QMap<QString, QString> &result) +void QSettingsPrivate::processChild(QStringRef key, ChildSpec spec, QStringList &result) { if (spec != AllKeys) { int slashPos = key.indexOf(QLatin1Char('/')); @@ -312,7 +313,7 @@ void QSettingsPrivate::processChild(QString key, ChildSpec spec, QMap<QString, Q key.truncate(slashPos); } } - result.insert(key, QString()); + result.append(key.toString()); } void QSettingsPrivate::beginGroupOrArray(const QSettingsGroup &group) @@ -357,6 +358,7 @@ void QSettingsPrivate::requestUpdate() QStringList QSettingsPrivate::variantListToStringList(const QVariantList &l) { QStringList result; + result.reserve(l.count()); QVariantList::const_iterator it = l.constBegin(); for (; it != l.constEnd(); ++it) result.append(variantToString(*it)); @@ -374,7 +376,9 @@ QVariant QSettingsPrivate::stringListToVariantList(const QStringList &l) outStringList[i].remove(0, 1); } else { QVariantList variantList; - for (int j = 0; j < l.count(); ++j) + const int stringCount = l.count(); + variantList.reserve(stringCount); + for (int j = 0; j < stringCount; ++j) variantList.append(stringToVariant(l.at(j))); return variantList; } @@ -1269,7 +1273,7 @@ bool QConfFileSettingsPrivate::get(const QString &key, QVariant *value) const QStringList QConfFileSettingsPrivate::children(const QString &prefix, ChildSpec spec) const { - QMap<QString, QString> result; + QStringList result; ParsedSettingsMap::const_iterator j; QSettingsKey thePrefix(prefix, caseSensitivity); @@ -1289,14 +1293,14 @@ QStringList QConfFileSettingsPrivate::children(const QString &prefix, ChildSpec &confFile->originalKeys)->lowerBound( thePrefix); while (j != confFile->originalKeys.constEnd() && j.key().startsWith(thePrefix)) { if (!confFile->removedKeys.contains(j.key())) - processChild(j.key().originalCaseKey().mid(startPos), spec, result); + processChild(j.key().originalCaseKey().midRef(startPos), spec, result); ++j; } j = const_cast<const ParsedSettingsMap *>( &confFile->addedKeys)->lowerBound(thePrefix); while (j != confFile->addedKeys.constEnd() && j.key().startsWith(thePrefix)) { - processChild(j.key().originalCaseKey().mid(startPos), spec, result); + processChild(j.key().originalCaseKey().midRef(startPos), spec, result); ++j; } @@ -1304,7 +1308,10 @@ QStringList QConfFileSettingsPrivate::children(const QString &prefix, ChildSpec break; } } - return result.keys(); + std::sort(result.begin(), result.end()); + result.erase(std::unique(result.begin(), result.end()), + result.end()); + return result; } void QConfFileSettingsPrivate::clear() @@ -1755,6 +1762,7 @@ public: int position; }; +Q_DECLARE_TYPEINFO(QSettingsIniKey, Q_MOVABLE_TYPE); static bool operator<(const QSettingsIniKey &k1, const QSettingsIniKey &k2) { diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h index f7a7bdbb191f831b92b94c9b857bd0917138536e..8f41273ffa02bb84550ee6df4932ea476eeefc32 100644 --- a/src/corelib/io/qsettings.h +++ b/src/corelib/io/qsettings.h @@ -105,13 +105,13 @@ public: #ifndef QT_NO_QOBJECT explicit QSettings(const QString &organization, - const QString &application = QString(), QObject *parent = 0); + const QString &application = QString(), QObject *parent = Q_NULLPTR); QSettings(Scope scope, const QString &organization, - const QString &application = QString(), QObject *parent = 0); + const QString &application = QString(), QObject *parent = Q_NULLPTR); QSettings(Format format, Scope scope, const QString &organization, - const QString &application = QString(), QObject *parent = 0); - QSettings(const QString &fileName, Format format, QObject *parent = 0); - explicit QSettings(QObject *parent = 0); + const QString &application = QString(), QObject *parent = Q_NULLPTR); + QSettings(const QString &fileName, Format format, QObject *parent = Q_NULLPTR); + explicit QSettings(QObject *parent = Q_NULLPTR); #else explicit QSettings(const QString &organization, const QString &application = QString()); diff --git a/src/corelib/io/qsettings_mac.cpp b/src/corelib/io/qsettings_mac.cpp index 51321c49e703638156ba3c7ecdb472d0f5b88643..1ad198b990887dd8a8f9fdd07f0f7cbbaadbbccc 100644 --- a/src/corelib/io/qsettings_mac.cpp +++ b/src/corelib/io/qsettings_mac.cpp @@ -491,7 +491,7 @@ bool QMacSettingsPrivate::get(const QString &key, QVariant *value) const QStringList QMacSettingsPrivate::children(const QString &prefix, ChildSpec spec) const { - QMap<QString, QString> result; + QStringList result; int startPos = prefix.size(); for (int i = 0; i < numDomains; ++i) { @@ -505,7 +505,7 @@ QStringList QMacSettingsPrivate::children(const QString &prefix, ChildSpec spec) QString currentKey = qtKey(static_cast<CFStringRef>(CFArrayGetValueAtIndex(cfarray, k))); if (currentKey.startsWith(prefix)) - processChild(currentKey.mid(startPos), spec, result); + processChild(currentKey.midRef(startPos), spec, result); } } } @@ -513,7 +513,10 @@ QStringList QMacSettingsPrivate::children(const QString &prefix, ChildSpec spec) if (!fallbacks) break; } - return result.keys(); + std::sort(result.begin(), result.end()); + result.erase(std::unique(result.begin(), result.end()), + result.end()); + return result; } void QMacSettingsPrivate::clear() diff --git a/src/corelib/io/qsettings_p.h b/src/corelib/io/qsettings_p.h index 93d63fd41181086c0f31bf22438a558de343896f..5a3eb58a586212d9344a345a1f5671af6985f5dc 100644 --- a/src/corelib/io/qsettings_p.h +++ b/src/corelib/io/qsettings_p.h @@ -127,6 +127,7 @@ public: int num; int maxNum; }; +Q_DECLARE_TYPEINFO(QSettingsGroup, Q_MOVABLE_TYPE); inline QString QSettingsGroup::toString() const { @@ -211,7 +212,7 @@ public: const QString &organization, const QString &application); static QSettingsPrivate *create(const QString &fileName, QSettings::Format format); - static void processChild(QString key, ChildSpec spec, QMap<QString, QString> &result); + static void processChild(QStringRef key, ChildSpec spec, QStringList &result); // Variant streaming functions static QStringList variantListToStringList(const QVariantList &l); diff --git a/src/corelib/io/qsettings_win.cpp b/src/corelib/io/qsettings_win.cpp index 60b15f41a065b0235baf6437da8cdf75ac712bd0..1546219c3b726248b8c0f60503493dd8a6c88898 100644 --- a/src/corelib/io/qsettings_win.cpp +++ b/src/corelib/io/qsettings_win.cpp @@ -319,11 +319,11 @@ private: }; RegistryKey::RegistryKey(HKEY parent_handle, const QString &key, bool read_only) + : m_parent_handle(parent_handle), + m_handle(0), + m_key(key), + m_read_only(read_only) { - m_parent_handle = parent_handle; - m_handle = 0; - m_read_only = read_only; - m_key = key; } QString RegistryKey::key() const diff --git a/src/corelib/io/qstorageinfo.cpp b/src/corelib/io/qstorageinfo.cpp index d63b6a2a2156ced62acc3adea57e5e61d08c94de..99a2a1a42a4c84cd50906cafb3e900bf4ef4dec4 100644 --- a/src/corelib/io/qstorageinfo.cpp +++ b/src/corelib/io/qstorageinfo.cpp @@ -186,6 +186,8 @@ QString QStorageInfo::rootPath() const This size can be less than or equal to the free size returned by bytesFree() function. + Returns -1 if QStorageInfo object is not valid. + \sa bytesTotal(), bytesFree() */ qint64 QStorageInfo::bytesAvailable() const @@ -198,6 +200,8 @@ qint64 QStorageInfo::bytesAvailable() const quotas on the filesystem, this value can be larger than the value returned by bytesAvailable(). + Returns -1 if QStorageInfo object is not valid. + \sa bytesTotal(), bytesAvailable() */ qint64 QStorageInfo::bytesFree() const @@ -208,6 +212,8 @@ qint64 QStorageInfo::bytesFree() const /*! Returns the total volume size in bytes. + Returns -1 if QStorageInfo object is not valid. + \sa bytesFree(), bytesAvailable() */ qint64 QStorageInfo::bytesTotal() const @@ -215,6 +221,18 @@ qint64 QStorageInfo::bytesTotal() const return d->bytesTotal; } +/*! + \since 5.6 + Returns the optimal transfer block size for this filesystem. + + Returns -1 if QStorageInfo could not determine the size or if the QStorageInfo + object is not valid. + */ +int QStorageInfo::blockSize() const +{ + return d->blockSize; +} + /*! Returns the type name of the filesystem. diff --git a/src/corelib/io/qstorageinfo.h b/src/corelib/io/qstorageinfo.h index 848278e69f6c30da7f2ec3918d299448890e4c70..c7a558bb4ed124bc83f9cd2ab081833f1d7ccc43 100644 --- a/src/corelib/io/qstorageinfo.h +++ b/src/corelib/io/qstorageinfo.h @@ -55,11 +55,10 @@ public: QStorageInfo &operator=(const QStorageInfo &other); #ifdef Q_COMPILER_RVALUE_REFS - inline QStorageInfo &operator=(QStorageInfo &&other) - { qSwap(d, other.d); return *this; } + QStorageInfo &operator=(QStorageInfo &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif - inline void swap(QStorageInfo &other) + inline void swap(QStorageInfo &other) Q_DECL_NOTHROW { qSwap(d, other.d); } void setPath(const QString &path); @@ -73,6 +72,7 @@ public: qint64 bytesTotal() const; qint64 bytesFree() const; qint64 bytesAvailable() const; + int blockSize() const; inline bool isRoot() const; bool isReadOnly() const; diff --git a/src/corelib/io/qstorageinfo_mac.cpp b/src/corelib/io/qstorageinfo_mac.cpp index 539af33c5d2045624c21c53f32152bf37bcca473..1ef998391851a61d55566196c655a0a2207e3c87 100644 --- a/src/corelib/io/qstorageinfo_mac.cpp +++ b/src/corelib/io/qstorageinfo_mac.cpp @@ -76,6 +76,7 @@ void QStorageInfoPrivate::retrievePosixInfo() device = QByteArray(statfs_buf.f_mntfromname); readOnly = (statfs_buf.f_flags & MNT_RDONLY) != 0; fileSystemType = QByteArray(statfs_buf.f_fstypename); + blockSize = statfs_buf.f_bsize; } } diff --git a/src/corelib/io/qstorageinfo_p.h b/src/corelib/io/qstorageinfo_p.h index 9e152df1adac6c495417f1ea59349ab1fa83699f..fb3bd8bd5b7c1049bfe071e1f0c6f9791e449ff9 100644 --- a/src/corelib/io/qstorageinfo_p.h +++ b/src/corelib/io/qstorageinfo_p.h @@ -53,7 +53,7 @@ class QStorageInfoPrivate : public QSharedData { public: inline QStorageInfoPrivate() : QSharedData(), - bytesTotal(0), bytesFree(0), bytesAvailable(0), + bytesTotal(-1), bytesFree(-1), bytesAvailable(-1), blockSize(-1), readOnly(false), ready(false), valid(false) {} @@ -84,6 +84,7 @@ public: qint64 bytesTotal; qint64 bytesFree; qint64 bytesAvailable; + int blockSize; bool readOnly; bool ready; diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index 310312fa91fd6fdf34857172ea15141e1c81e68e..94653278fd84202bccfb50251273a967fa1d6702 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -511,6 +511,7 @@ void QStorageInfoPrivate::retrieveVolumeInfo() bytesTotal = statfs_buf.f_blocks * statfs_buf.f_bsize; bytesFree = statfs_buf.f_bfree * statfs_buf.f_bsize; bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_bsize; + blockSize = statfs_buf.f_bsize; #if defined(Q_OS_ANDROID) || defined (Q_OS_BSD4) #if defined(_STATFS_F_FLAGS) readOnly = (statfs_buf.f_flags & ST_RDONLY) != 0; diff --git a/src/corelib/io/qtemporarydir.cpp b/src/corelib/io/qtemporarydir.cpp index 0beda22f248bfb87a458cc24a88195e2429a082b..c7150d7b33147f8adab88bdfafab9dcbcae092af 100644 --- a/src/corelib/io/qtemporarydir.cpp +++ b/src/corelib/io/qtemporarydir.cpp @@ -38,6 +38,7 @@ #include "qdiriterator.h" #include "qplatformdefs.h" #include <QDebug> +#include <QPair> #if defined(QT_BUILD_CORE_LIB) #include "qcoreapplication.h" @@ -59,7 +60,7 @@ public: void create(const QString &templateName); - QString path; + QString pathOrError; bool autoRemove; bool success; }; @@ -97,7 +98,7 @@ static int nextRand(int &v) return r; } -static char *q_mkdtemp(char *templateName) +QPair<QString, bool> q_mkdtemp(char *templateName) { static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; @@ -105,8 +106,7 @@ static char *q_mkdtemp(char *templateName) char *XXXXXX = templateName + length - 6; - if ((length < 6u) || strncmp(XXXXXX, "XXXXXX", 6)) - return 0; + Q_ASSERT((length >= 6u) && strncmp(XXXXXX, "XXXXXX", 6) == 0); for (int i = 0; i < 256; ++i) { int v = qrand(); @@ -133,17 +133,27 @@ static char *q_mkdtemp(char *templateName) qWarning() << "Unable to remove unused directory" << templateNameStr; continue; } - return templateName; + return qMakePair(QFile::decodeName(templateName), true); } +# ifdef Q_OS_WIN + const int exists = ERROR_ALREADY_EXISTS; + int code = GetLastError(); +# else + const int exists = EEXIST; + int code = errno; +# endif + if (code != exists) + return qMakePair(qt_error_string(code), false); } - return 0; + return qMakePair(qt_error_string(), false); } #else // defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) -static char *q_mkdtemp(char *templateName) +QPair<QString, bool> q_mkdtemp(char *templateName) { - return mkdtemp(templateName); + bool ok = (mkdtemp(templateName) != 0); + return qMakePair(ok ? QFile::decodeName(templateName) : qt_error_string(), ok); } #endif @@ -153,10 +163,9 @@ void QTemporaryDirPrivate::create(const QString &templateName) QByteArray buffer = QFile::encodeName(templateName); if (!buffer.endsWith("XXXXXX")) buffer += "XXXXXX"; - if (q_mkdtemp(buffer.data())) { // modifies buffer - success = true; - path = QFile::decodeName(buffer.constData()); - } + QPair<QString, bool> result = q_mkdtemp(buffer.data()); // modifies buffer + pathOrError = result.first; + success = result.second; } //************* QTemporaryDir @@ -255,13 +264,25 @@ bool QTemporaryDir::isValid() const return d_ptr->success; } +/*! + \since 5.6 + + If isValid() returns \c false, this function returns the error string that + explains why the creation of the temporary directory failed. Otherwise, this + function return an empty string. +*/ +QString QTemporaryDir::errorString() const +{ + return d_ptr->success ? QString() : d_ptr->pathOrError; +} + /*! Returns the path to the temporary directory. Empty if the QTemporaryDir could not be created. */ QString QTemporaryDir::path() const { - return d_ptr->path; + return d_ptr->success ? d_ptr->pathOrError : QString(); } /*! diff --git a/src/corelib/io/qtemporarydir.h b/src/corelib/io/qtemporarydir.h index 8b9822652996ee8afa235771264985417299c29d..ab6d841cdfffd68c7ae99109f9bf709b728cd08d 100644 --- a/src/corelib/io/qtemporarydir.h +++ b/src/corelib/io/qtemporarydir.h @@ -52,6 +52,7 @@ public: ~QTemporaryDir(); bool isValid() const; + QString errorString() const; bool autoRemove() const; void setAutoRemove(bool b); diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index bdf4392275a3c6dee82006a0648f0cd0a99e52a0..e8e8d8c87822319eccfa96b4d4eaac475d31b4c3 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -409,14 +409,24 @@ QTemporaryFilePrivate::~QTemporaryFilePrivate() QAbstractFileEngine *QTemporaryFilePrivate::engine() const { if (!fileEngine) { - if (fileName.isEmpty()) - fileEngine = new QTemporaryFileEngine(templateName, 0600); - else - fileEngine = new QTemporaryFileEngine(fileName, 0600, false); + fileEngine = new QTemporaryFileEngine; + resetFileEngine(); } return fileEngine; } +void QTemporaryFilePrivate::resetFileEngine() const +{ + if (!fileEngine) + return; + + QTemporaryFileEngine *tef = static_cast<QTemporaryFileEngine *>(fileEngine); + if (fileName.isEmpty()) + tef->initialize(templateName, 0600); + else + tef->initialize(fileName, 0600, false); +} + QString QTemporaryFilePrivate::defaultTemplateName() { QString baseName; @@ -769,6 +779,13 @@ bool QTemporaryFile::open(OpenMode flags) } } + // reset the engine state so it creates a new, unique file name from the template; + // equivalent to: + // delete d->fileEngine; + // d->fileEngine = 0; + // d->engine(); + d->resetFileEngine(); + if (QFile::open(flags)) { d->fileName = d->fileEngine->fileName(QAbstractFileEngine::DefaultName); return true; diff --git a/src/corelib/io/qtemporaryfile_p.h b/src/corelib/io/qtemporaryfile_p.h index 341ae9bd3f13736312b1fd82fde9695e5e2a2262..8002990270af64bbce45c411f91657d6e9764497 100644 --- a/src/corelib/io/qtemporaryfile_p.h +++ b/src/corelib/io/qtemporaryfile_p.h @@ -64,6 +64,7 @@ protected: ~QTemporaryFilePrivate(); QAbstractFileEngine *engine() const; + void resetFileEngine() const; bool autoRemove; QString templateName; @@ -77,22 +78,17 @@ class QTemporaryFileEngine : public QFSFileEngine { Q_DECLARE_PRIVATE(QFSFileEngine) public: - - QTemporaryFileEngine(const QString &file, - quint32 fileMode, - bool fileIsTemplate = true) : - QFSFileEngine(), - fileMode(fileMode), - filePathIsTemplate(fileIsTemplate), - filePathWasTemplate(fileIsTemplate) + void initialize(const QString &file, quint32 mode, bool nameIsTemplate = true) { Q_D(QFSFileEngine); + Q_ASSERT(!isReallyOpen()); + fileMode = mode; + filePathIsTemplate = filePathWasTemplate = nameIsTemplate; d->fileEntry = QFileSystemEntry(file); if (!filePathIsTemplate) QFSFileEngine::setFileName(file); } - ~QTemporaryFileEngine(); bool isReallyOpen() const; diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 47b96d708f8f17a39dd0ae508079a2a43175fd15..8ad1c2852cc63daa5cc084ab22a23e395d110abd 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -1591,7 +1591,7 @@ QString QTextStream::readLine(qint64 maxlen) { QString line; - readLine(&line, maxlen); + readLineInto(&line, maxlen); return line; } @@ -1612,7 +1612,7 @@ QString QTextStream::readLine(qint64 maxlen) If \a line has sufficient capacity for the data that is about to be read, this function may not need to allocate new memory. Because of - this, it can be faster than the other readLine() overload. + this, it can be faster than readLine(). Returns \c false if the stream has read to the end of the file or an error has occurred; otherwise returns \c true. The contents in @@ -1620,7 +1620,7 @@ QString QTextStream::readLine(qint64 maxlen) \sa readAll(), QIODevice::readLine() */ -bool QTextStream::readLine(QString *line, qint64 maxlen) +bool QTextStream::readLineInto(QString *line, qint64 maxlen) { Q_D(QTextStream); // keep in sync with CHECK_VALID_STREAM diff --git a/src/corelib/io/qtextstream.h b/src/corelib/io/qtextstream.h index 125502e68d38414144aa72ce735e025a3f1955a3..eb33db63d7d56b2fa9d33d5eb676c7ecc67085ba 100644 --- a/src/corelib/io/qtextstream.h +++ b/src/corelib/io/qtextstream.h @@ -124,7 +124,7 @@ public: void skipWhiteSpace(); QString readLine(qint64 maxlen = 0); - bool readLine(QString *line, qint64 maxlen = 0); + bool readLineInto(QString *line, qint64 maxlen = 0); QString readAll(); QString read(qint64 maxlen); @@ -205,8 +205,8 @@ typedef void (QTextStream::*QTSMFC)(QChar); // manipulator w/QChar argument class Q_CORE_EXPORT QTextStreamManipulator { public: - QTextStreamManipulator(QTSMFI m, int a) { mf = m; mc = 0; arg = a; } - QTextStreamManipulator(QTSMFC m, QChar c) { mf = 0; mc = m; ch = c; arg = -1; } + Q_DECL_CONSTEXPR QTextStreamManipulator(QTSMFI m, int a) Q_DECL_NOTHROW : mf(m), mc(Q_NULLPTR), arg(a), ch() {} + Q_DECL_CONSTEXPR QTextStreamManipulator(QTSMFC m, QChar c) Q_DECL_NOTHROW : mf(Q_NULLPTR), mc(m), arg(-1), ch(c) {} void exec(QTextStream &s) { if (mf) { (s.*mf)(arg); } else { (s.*mc)(ch); } } private: diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp index 91e6e21e20deb87805d41da536aa413a36355304..2b695a4f7b6d48634ce13872f3389de4ba8485a6 100644 --- a/src/corelib/io/qurlquery.cpp +++ b/src/corelib/io/qurlquery.cpp @@ -642,6 +642,7 @@ QList<QPair<QString, QString> > QUrlQuery::queryItems(QUrl::ComponentFormattingO QList<QPair<QString, QString> > result; Map::const_iterator it = d->itemList.constBegin(); Map::const_iterator end = d->itemList.constEnd(); + result.reserve(d->itemList.count()); for ( ; it != end; ++it) result << qMakePair(d->recodeToUser(it->first, encoding), d->recodeToUser(it->second, encoding)); diff --git a/src/corelib/io/qurlquery.h b/src/corelib/io/qurlquery.h index 21962fcb225eef4f044536e372ac2920295fb1fc..ae3a79c1196061412dfcbc35a2b02cc875d736e8 100644 --- a/src/corelib/io/qurlquery.h +++ b/src/corelib/io/qurlquery.h @@ -56,8 +56,7 @@ public: QUrlQuery(const QUrlQuery &other); QUrlQuery &operator=(const QUrlQuery &other); #ifdef Q_COMPILER_RVALUE_REFS - QUrlQuery &operator=(QUrlQuery &&other) - { qSwap(d, other.d); return *this; } + QUrlQuery &operator=(QUrlQuery &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif ~QUrlQuery(); @@ -65,7 +64,7 @@ public: bool operator!=(const QUrlQuery &other) const { return !(*this == other); } - void swap(QUrlQuery &other) { qSwap(d, other.d); } + void swap(QUrlQuery &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool isEmpty() const; bool isDetached() const; diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index 2f3cfc1c0ad11d7f8eece69c3ea4f0c8a6d81eb9..90297b9115736c1b167564b62c6f94132d5a4a4b 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -3222,6 +3222,7 @@ QModelIndexList QAbstractItemModel::persistentIndexList() const { Q_D(const QAbstractItemModel); QModelIndexList result; + result.reserve(d->persistent.indexes.count()); for (QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator it = d->persistent.indexes.constBegin(); it != d->persistent.indexes.constEnd(); ++it) { QPersistentModelIndexData *data = *it; diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h index 5ca7bd012316cae7e96a722938d25595569b5dc2..096e67c5134673cbcf665f4dd2bf05bc1ca6f16f 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.h +++ b/src/corelib/itemmodels/qabstractitemmodel.h @@ -49,7 +49,7 @@ class Q_CORE_EXPORT QModelIndex { friend class QAbstractItemModel; public: - Q_DECL_CONSTEXPR inline QModelIndex() Q_DECL_NOTHROW : r(-1), c(-1), i(0), m(0) {} + Q_DECL_CONSTEXPR inline QModelIndex() Q_DECL_NOTHROW : r(-1), c(-1), i(0), m(Q_NULLPTR) {} // compiler-generated copy/move ctors/assignment operators are fine! Q_DECL_CONSTEXPR inline int row() const Q_DECL_NOTHROW { return r; } Q_DECL_CONSTEXPR inline int column() const Q_DECL_NOTHROW { return c; } @@ -61,7 +61,7 @@ public: inline QVariant data(int role = Qt::DisplayRole) const; inline Qt::ItemFlags flags() const; Q_DECL_CONSTEXPR inline const QAbstractItemModel *model() const Q_DECL_NOTHROW { return m; } - Q_DECL_CONSTEXPR inline bool isValid() const Q_DECL_NOTHROW { return (r >= 0) && (c >= 0) && (m != 0); } + Q_DECL_CONSTEXPR inline bool isValid() const Q_DECL_NOTHROW { return (r >= 0) && (c >= 0) && (m != Q_NULLPTR); } Q_DECL_CONSTEXPR inline bool operator==(const QModelIndex &other) const Q_DECL_NOTHROW { return (other.r == r) && (other.i == i) && (other.c == c) && (other.m == m); } Q_DECL_CONSTEXPR inline bool operator!=(const QModelIndex &other) const Q_DECL_NOTHROW @@ -161,7 +161,7 @@ class Q_CORE_EXPORT QAbstractItemModel : public QObject friend class QIdentityProxyModel; public: - explicit QAbstractItemModel(QObject *parent = 0); + explicit QAbstractItemModel(QObject *parent = Q_NULLPTR); virtual ~QAbstractItemModel(); Q_INVOKABLE bool hasIndex(int row, int column, const QModelIndex &parent = QModelIndex()) const; @@ -276,9 +276,9 @@ protected Q_SLOTS: void resetInternalData(); protected: - QAbstractItemModel(QAbstractItemModelPrivate &dd, QObject *parent = 0); + QAbstractItemModel(QAbstractItemModelPrivate &dd, QObject *parent = Q_NULLPTR); - inline QModelIndex createIndex(int row, int column, void *data = 0) const; + inline QModelIndex createIndex(int row, int column, void *data = Q_NULLPTR) const; inline QModelIndex createIndex(int row, int column, quintptr id) const; void encodeData(const QModelIndexList &indexes, QDataStream &stream) const; @@ -357,7 +357,7 @@ class Q_CORE_EXPORT QAbstractTableModel : public QAbstractItemModel Q_OBJECT public: - explicit QAbstractTableModel(QObject *parent = 0); + explicit QAbstractTableModel(QObject *parent = Q_NULLPTR); ~QAbstractTableModel(); QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; @@ -383,7 +383,7 @@ class Q_CORE_EXPORT QAbstractListModel : public QAbstractItemModel Q_OBJECT public: - explicit QAbstractListModel(QObject *parent = 0); + explicit QAbstractListModel(QObject *parent = Q_NULLPTR); ~QAbstractListModel(); QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; @@ -420,7 +420,7 @@ inline QVariant QModelIndex::data(int arole) const { return m ? m->data(*this, arole) : QVariant(); } inline Qt::ItemFlags QModelIndex::flags() const -{ return m ? m->flags(*this) : Qt::ItemFlags(0); } +{ return m ? m->flags(*this) : Qt::ItemFlags(); } inline uint qHash(const QModelIndex &index) Q_DECL_NOTHROW { return uint((index.row() << 4) + index.column() + index.internalId()); } diff --git a/src/corelib/itemmodels/qabstractitemmodel_p.h b/src/corelib/itemmodels/qabstractitemmodel_p.h index acf376eff13fb7a32b8aae1b94f8dc7a48c630c8..c2cbaf5298e868b204c47d6f8148c41a54588dc9 100644 --- a/src/corelib/itemmodels/qabstractitemmodel_p.h +++ b/src/corelib/itemmodels/qabstractitemmodel_p.h @@ -164,6 +164,7 @@ public: QHash<int,QByteArray> roleNames; static const QHash<int,QByteArray> &defaultRoleNames(); }; +Q_DECLARE_TYPEINFO(QAbstractItemModelPrivate::Change, Q_MOVABLE_TYPE); QT_END_NAMESPACE diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp index 4d08306d2805ee03788e35a30d612e5ba5384c7a..dbbbbb8ff47810387129230e328d98f847ad6952 100644 --- a/src/corelib/itemmodels/qabstractproxymodel.cpp +++ b/src/corelib/itemmodels/qabstractproxymodel.cpp @@ -379,6 +379,7 @@ QMimeData* QAbstractProxyModel::mimeData(const QModelIndexList &indexes) const { Q_D(const QAbstractProxyModel); QModelIndexList list; + list.reserve(indexes.count()); foreach(const QModelIndex &index, indexes) list << mapToSource(index); return d->model->mimeData(list); diff --git a/src/corelib/itemmodels/qabstractproxymodel.h b/src/corelib/itemmodels/qabstractproxymodel.h index dc8d2d4dc8a7fe287f1b25ec003495f1ee0bf5e9..a4cb74830b54e501926cabad868bc921614fa7c5 100644 --- a/src/corelib/itemmodels/qabstractproxymodel.h +++ b/src/corelib/itemmodels/qabstractproxymodel.h @@ -50,7 +50,7 @@ class Q_CORE_EXPORT QAbstractProxyModel : public QAbstractItemModel Q_PROPERTY(QAbstractItemModel* sourceModel READ sourceModel WRITE setSourceModel NOTIFY sourceModelChanged) public: - explicit QAbstractProxyModel(QObject *parent = 0); + explicit QAbstractProxyModel(QObject *parent = Q_NULLPTR); ~QAbstractProxyModel(); virtual void setSourceModel(QAbstractItemModel *sourceModel); diff --git a/src/corelib/itemmodels/qidentityproxymodel.cpp b/src/corelib/itemmodels/qidentityproxymodel.cpp index f773219aeb8d8ac702723fca94b686c4b58b3f75..f46fd135caf058bfa41d5b5157d3d9a96a3eaac3 100644 --- a/src/corelib/itemmodels/qidentityproxymodel.cpp +++ b/src/corelib/itemmodels/qidentityproxymodel.cpp @@ -212,6 +212,7 @@ QItemSelection QIdentityProxyModel::mapSelectionFromSource(const QItemSelection& QItemSelection::const_iterator it = selection.constBegin(); const QItemSelection::const_iterator end = selection.constEnd(); + proxySelection.reserve(selection.count()); for ( ; it != end; ++it) { Q_ASSERT(it->model() == d->model); const QItemSelectionRange range(mapFromSource(it->topLeft()), mapFromSource(it->bottomRight())); @@ -234,6 +235,7 @@ QItemSelection QIdentityProxyModel::mapSelectionToSource(const QItemSelection& s QItemSelection::const_iterator it = selection.constBegin(); const QItemSelection::const_iterator end = selection.constEnd(); + sourceSelection.reserve(selection.count()); for ( ; it != end; ++it) { Q_ASSERT(it->model() == this); const QItemSelectionRange range(mapToSource(it->topLeft()), mapToSource(it->bottomRight())); @@ -269,6 +271,7 @@ QModelIndexList QIdentityProxyModel::match(const QModelIndex& start, int role, c QModelIndexList::const_iterator it = sourceList.constBegin(); const QModelIndexList::const_iterator end = sourceList.constEnd(); QModelIndexList proxyList; + proxyList.reserve(sourceList.count()); for ( ; it != end; ++it) proxyList.append(mapFromSource(*it)); return proxyList; diff --git a/src/corelib/itemmodels/qidentityproxymodel.h b/src/corelib/itemmodels/qidentityproxymodel.h index e4587cb3865bb03d1d7ae86119de4b08c01e58b0..7578f8d38067b6107c1a476975339d765399b923 100644 --- a/src/corelib/itemmodels/qidentityproxymodel.h +++ b/src/corelib/itemmodels/qidentityproxymodel.h @@ -48,7 +48,7 @@ class Q_CORE_EXPORT QIdentityProxyModel : public QAbstractProxyModel { Q_OBJECT public: - explicit QIdentityProxyModel(QObject* parent = 0); + explicit QIdentityProxyModel(QObject* parent = Q_NULLPTR); ~QIdentityProxyModel(); int columnCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE; diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp index 47fcab9b24a114faa89ccbbffc679cd617993f30..fa7d4647a413e658b5db2d6059af58b17fdace6c 100644 --- a/src/corelib/itemmodels/qitemselectionmodel.cpp +++ b/src/corelib/itemmodels/qitemselectionmodel.cpp @@ -103,6 +103,14 @@ QT_BEGIN_NAMESPACE by the model index \a index. */ +/*! + \fn QItemSelectionRange::swap(QItemSelectionRange &other) + \since 5.6 + + Swaps this selection range's contents with \a other. + This function is very fast and never fails. +*/ + /*! \fn int QItemSelectionRange::top() const @@ -1764,7 +1772,7 @@ const QAbstractItemModel *QItemSelectionModel::model() const /*! \since 5.5 - Sets the model. The modelChanged() signal will be emitted. + Sets the model to \a model. The modelChanged() signal will be emitted. \sa model(), modelChanged() */ diff --git a/src/corelib/itemmodels/qitemselectionmodel.h b/src/corelib/itemmodels/qitemselectionmodel.h index 4fe836c098b9b2ad43144bf505a8b012ccab6fb5..09b710175ef5d7fde4b32eb8d83d31a24426186c 100644 --- a/src/corelib/itemmodels/qitemselectionmodel.h +++ b/src/corelib/itemmodels/qitemselectionmodel.h @@ -48,12 +48,28 @@ class Q_CORE_EXPORT QItemSelectionRange { public: - inline QItemSelectionRange() {} + inline QItemSelectionRange() : tl(), br() {} +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) + // ### Qt 6: remove them all, the compiler-generated ones are fine inline QItemSelectionRange(const QItemSelectionRange &other) : tl(other.tl), br(other.br) {} - inline QItemSelectionRange(const QModelIndex &topLeft, const QModelIndex &bottomRight); - explicit inline QItemSelectionRange(const QModelIndex &index) - { tl = index; br = tl; } +# ifdef Q_COMPILER_RVALUE_REFS + QItemSelectionRange(QItemSelectionRange &&other) Q_DECL_NOTHROW + : tl(std::move(other.tl)), br(std::move(other.br)) {} + QItemSelectionRange &operator=(QItemSelectionRange &&other) Q_DECL_NOTHROW + { tl = std::move(other.tl); br = std::move(other.br); return *this; } +# endif + QItemSelectionRange &operator=(const QItemSelectionRange &other) + { tl = other.tl; br = other.br; return *this; } +#endif // Qt < 6 + QItemSelectionRange(const QModelIndex &topL, const QModelIndex &bottomR) : tl(topL), br(bottomR) {} + explicit QItemSelectionRange(const QModelIndex &index) : tl(index), br(tl) {} + + void swap(QItemSelectionRange &other) Q_DECL_NOTHROW + { + qSwap(tl, other.tl); + qSwap(br, other.br); + } inline int top() const { return tl.row(); } inline int left() const { return tl.column(); } @@ -133,10 +149,6 @@ private: }; Q_DECLARE_TYPEINFO(QItemSelectionRange, Q_MOVABLE_TYPE); -inline QItemSelectionRange::QItemSelectionRange(const QModelIndex &atopLeft, - const QModelIndex &abottomRight) -{ tl = atopLeft; br = abottomRight; } - class QItemSelection; class QItemSelectionModelPrivate; @@ -170,7 +182,7 @@ public: Q_DECLARE_FLAGS(SelectionFlags, SelectionFlag) Q_FLAG(SelectionFlags) - explicit QItemSelectionModel(QAbstractItemModel *model = 0); + explicit QItemSelectionModel(QAbstractItemModel *model = Q_NULLPTR); explicit QItemSelectionModel(QAbstractItemModel *model, QObject *parent); virtual ~QItemSelectionModel(); @@ -235,8 +247,11 @@ inline uint qHash(const QItemSelectionRange &) { return 0; } class Q_CORE_EXPORT QItemSelection : public QList<QItemSelectionRange> { public: - QItemSelection() {} + QItemSelection() Q_DECL_NOTHROW : QList<QItemSelectionRange>() {} QItemSelection(const QModelIndex &topLeft, const QModelIndex &bottomRight); + + // reusing QList::swap() here is OK! + void select(const QModelIndex &topLeft, const QModelIndex &bottomRight); bool contains(const QModelIndex &index) const; QModelIndexList indexes() const; @@ -245,6 +260,7 @@ public: const QItemSelectionRange &other, QItemSelection *result); }; +Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QItemSelection) #ifndef QT_NO_DEBUG_STREAM Q_CORE_EXPORT QDebug operator<<(QDebug, const QItemSelectionRange &); diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index 922d0f1622e24ebe6aa14fa9e0a26c835d8238a5..4ee37defae86c315f9d360cda375910545e0f783 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -272,6 +272,7 @@ public: QModelIndexPairList store_persistent_indexes(); void update_persistent_indexes(const QModelIndexPairList &source_indexes); + void filter_about_to_be_changed(const QModelIndex &source_parent = QModelIndex()); void filter_changed(const QModelIndex &source_parent = QModelIndex()); QSet<int> handle_filter_changed( QVector<int> &source_to_proxy, QVector<int> &proxy_to_source, @@ -1011,6 +1012,7 @@ QModelIndexPairList QSortFilterProxyModelPrivate::store_persistent_indexes() { Q_Q(QSortFilterProxyModel); QModelIndexPairList source_indexes; + source_indexes.reserve(persistent.indexes.count()); foreach (QPersistentModelIndexData *data, persistent.indexes) { QModelIndex proxy_index = data->index; QModelIndex source_index = q->mapToSource(proxy_index); @@ -1030,7 +1032,10 @@ void QSortFilterProxyModelPrivate::update_persistent_indexes( { Q_Q(QSortFilterProxyModel); QModelIndexList from, to; - for (int i = 0; i < source_indexes.count(); ++i) { + const int numSourceIndexes = source_indexes.count(); + from.reserve(numSourceIndexes); + to.reserve(numSourceIndexes); + for (int i = 0; i < numSourceIndexes; ++i) { QModelIndex source_index = source_indexes.at(i).second; QModelIndex old_proxy_index = source_indexes.at(i).first; create_mapping(source_index.parent()); @@ -1041,6 +1046,19 @@ void QSortFilterProxyModelPrivate::update_persistent_indexes( q->changePersistentIndexList(from, to); } +/*! + \internal + + Updates the source_index mapping in case it's invalid and we + need it because we have a valid filter +*/ +void QSortFilterProxyModelPrivate::filter_about_to_be_changed(const QModelIndex &source_parent) +{ + if (!filter_regexp.pattern().isEmpty() && + source_index_mapping.constFind(source_parent) == source_index_mapping.constEnd()) + create_mapping(source_parent); +} + /*! \internal @@ -2013,7 +2031,9 @@ QMimeData *QSortFilterProxyModel::mimeData(const QModelIndexList &indexes) const { Q_D(const QSortFilterProxyModel); QModelIndexList source_indexes; - for (int i = 0; i < indexes.count(); ++i) + const int numIndexes = indexes.count(); + source_indexes.reserve(numIndexes); + for (int i = 0; i < numIndexes; ++i) source_indexes << mapToSource(indexes.at(i)); return d->model->mimeData(source_indexes); } @@ -2108,6 +2128,7 @@ bool QSortFilterProxyModel::removeRows(int row, int count, const QModelIndex &pa // remove corresponding source intervals // ### if this proves to be slow, we can switch to single-row removal QVector<int> rows; + rows.reserve(count); for (int i = row; i < row + count; ++i) rows.append(m->source_rows.at(i)); std::sort(rows.begin(), rows.end()); @@ -2147,6 +2168,7 @@ bool QSortFilterProxyModel::removeColumns(int column, int count, const QModelInd } // remove corresponding source intervals QVector<int> columns; + columns.reserve(count); for (int i = column; i < column + count; ++i) columns.append(m->source_columns.at(i)); @@ -2298,6 +2320,7 @@ QRegExp QSortFilterProxyModel::filterRegExp() const void QSortFilterProxyModel::setFilterRegExp(const QRegExp ®Exp) { Q_D(QSortFilterProxyModel); + d->filter_about_to_be_changed(); d->filter_regexp = regExp; d->filter_changed(); } @@ -2319,6 +2342,7 @@ int QSortFilterProxyModel::filterKeyColumn() const void QSortFilterProxyModel::setFilterKeyColumn(int column) { Q_D(QSortFilterProxyModel); + d->filter_about_to_be_changed(); d->filter_column = column; d->filter_changed(); } @@ -2344,6 +2368,7 @@ void QSortFilterProxyModel::setFilterCaseSensitivity(Qt::CaseSensitivity cs) Q_D(QSortFilterProxyModel); if (cs == d->filter_regexp.caseSensitivity()) return; + d->filter_about_to_be_changed(); d->filter_regexp.setCaseSensitivity(cs); d->filter_changed(); } @@ -2409,6 +2434,7 @@ void QSortFilterProxyModel::setSortLocaleAware(bool on) void QSortFilterProxyModel::setFilterRegExp(const QString &pattern) { Q_D(QSortFilterProxyModel); + d->filter_about_to_be_changed(); d->filter_regexp.setPatternSyntax(QRegExp::RegExp); d->filter_regexp.setPattern(pattern); d->filter_changed(); @@ -2423,6 +2449,7 @@ void QSortFilterProxyModel::setFilterRegExp(const QString &pattern) void QSortFilterProxyModel::setFilterWildcard(const QString &pattern) { Q_D(QSortFilterProxyModel); + d->filter_about_to_be_changed(); d->filter_regexp.setPatternSyntax(QRegExp::Wildcard); d->filter_regexp.setPattern(pattern); d->filter_changed(); @@ -2437,6 +2464,7 @@ void QSortFilterProxyModel::setFilterWildcard(const QString &pattern) void QSortFilterProxyModel::setFilterFixedString(const QString &pattern) { Q_D(QSortFilterProxyModel); + d->filter_about_to_be_changed(); d->filter_regexp.setPatternSyntax(QRegExp::FixedString); d->filter_regexp.setPattern(pattern); d->filter_changed(); @@ -2516,6 +2544,7 @@ void QSortFilterProxyModel::setFilterRole(int role) Q_D(QSortFilterProxyModel); if (d->filter_role == role) return; + d->filter_about_to_be_changed(); d->filter_role = role; d->filter_changed(); } @@ -2617,9 +2646,12 @@ bool QSortFilterProxyModel::lessThan(const QModelIndex &source_left, const QMode Q_D(const QSortFilterProxyModel); QVariant l = (source_left.model() ? source_left.model()->data(source_left, d->sort_role) : QVariant()); QVariant r = (source_right.model() ? source_right.model()->data(source_right, d->sort_role) : QVariant()); + // Duplicated in QStandardItem::operator<() + if (l.userType() == QVariant::Invalid) + return false; + if (r.userType() == QVariant::Invalid) + return true; switch (l.userType()) { - case QVariant::Invalid: - return (r.type() != QVariant::Invalid); case QVariant::Int: return l.toInt() < r.toInt(); case QVariant::UInt: diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.h b/src/corelib/itemmodels/qsortfilterproxymodel.h index a08d7c6416bd105b62db2dcba42a7e891cb6d095..4be5aedd48baa7039a39ca3c88d979df0408652b 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.h +++ b/src/corelib/itemmodels/qsortfilterproxymodel.h @@ -63,7 +63,7 @@ class Q_CORE_EXPORT QSortFilterProxyModel : public QAbstractProxyModel Q_PROPERTY(int filterRole READ filterRole WRITE setFilterRole) public: - explicit QSortFilterProxyModel(QObject *parent = 0); + explicit QSortFilterProxyModel(QObject *parent = Q_NULLPTR); ~QSortFilterProxyModel(); void setSourceModel(QAbstractItemModel *sourceModel) Q_DECL_OVERRIDE; diff --git a/src/corelib/itemmodels/qstringlistmodel.cpp b/src/corelib/itemmodels/qstringlistmodel.cpp index 2853be3fda0358314848eb3dddda3944c9f100dd..dad736b445fbce3e7c97ec2808adac10b9b2e7ac 100644 --- a/src/corelib/itemmodels/qstringlistmodel.cpp +++ b/src/corelib/itemmodels/qstringlistmodel.cpp @@ -257,7 +257,9 @@ void QStringListModel::sort(int, Qt::SortOrder order) emit layoutAboutToBeChanged(QList<QPersistentModelIndex>(), VerticalSortHint); QList<QPair<QString, int> > list; - for (int i = 0; i < lst.count(); ++i) + const int lstCount = lst.count(); + list.reserve(lstCount); + for (int i = 0; i < lstCount; ++i) list.append(QPair<QString, int>(lst.at(i), i)); if (order == Qt::AscendingOrder) diff --git a/src/corelib/itemmodels/qstringlistmodel.h b/src/corelib/itemmodels/qstringlistmodel.h index 973007995b20a56fe939ec9083f2435d6c9925a6..a1cb923dbb6a733148c4b3703c26805f2fd55b5d 100644 --- a/src/corelib/itemmodels/qstringlistmodel.h +++ b/src/corelib/itemmodels/qstringlistmodel.h @@ -46,8 +46,8 @@ class Q_CORE_EXPORT QStringListModel : public QAbstractListModel { Q_OBJECT public: - explicit QStringListModel(QObject *parent = 0); - explicit QStringListModel(const QStringList &strings, QObject *parent = 0); + explicit QStringListModel(QObject *parent = Q_NULLPTR); + explicit QStringListModel(const QStringList &strings, QObject *parent = Q_NULLPTR); int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; QModelIndex sibling(int row, int column, const QModelIndex &idx) const Q_DECL_OVERRIDE; diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp index 77a3d0a2b8be3ffd30de102fa27e2bf98e5320a7..dd27603d6da7f61b8c035d7e5071492e67222b01 100644 --- a/src/corelib/json/qjsonarray.cpp +++ b/src/corelib/json/qjsonarray.cpp @@ -271,6 +271,7 @@ QVariantList QJsonArray::toVariantList() const QVariantList list; if (a) { + list.reserve(a->length); for (int i = 0; i < (int)a->length; ++i) list.append(QJsonValue(d, a, a->at(i)).toVariant()); } diff --git a/src/corelib/json/qjsonarray.h b/src/corelib/json/qjsonarray.h index 61486421061f21251fcc22946c0df00039fb39a9..611e1f419332574bc36ea2d1dc0cd03a09574ee9 100644 --- a/src/corelib/json/qjsonarray.h +++ b/src/corelib/json/qjsonarray.h @@ -107,7 +107,7 @@ public: typedef QJsonValueRef reference; typedef QJsonValueRefPtr pointer; - inline iterator() : a(0), i(0) { } + inline iterator() : a(Q_NULLPTR), i(0) { } explicit inline iterator(QJsonArray *array, int index) : a(array), i(index) { } inline QJsonValueRef operator*() const { return QJsonValueRef(a, i); } @@ -152,9 +152,11 @@ public: typedef QJsonValue reference; typedef QJsonValuePtr pointer; - inline const_iterator() : a(0), i(0) { } + inline const_iterator() : a(Q_NULLPTR), i(0) { } explicit inline const_iterator(const QJsonArray *array, int index) : a(array), i(index) { } - inline const_iterator(const const_iterator &o) : a(o.a), i(o.i) {} +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + inline const_iterator(const const_iterator &o) : a(o.a), i(o.i) {} // ### Qt 6: Removed so class can be trivially-copyable +#endif inline const_iterator(const iterator &o) : a(o.a), i(o.i) {} inline QJsonValue operator*() const { return a->at(i); } diff --git a/src/corelib/json/qjsondocument.h b/src/corelib/json/qjsondocument.h index 285b42c6c8334428b20a12656a64fea705ba653a..d7a88b2f156161ff0ba2a53ac04aa50d4db66060 100644 --- a/src/corelib/json/qjsondocument.h +++ b/src/corelib/json/qjsondocument.h @@ -106,7 +106,7 @@ public: Compact }; - static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = 0); + static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR); #ifdef Q_QDOC QByteArray toJson(JsonFormat format = Indented) const; diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp index ae44cd9ff91c26bd7833480c0145d7b54107dc3a..b7dfe88434093c69297b456e878b79bf98ebb9f8 100644 --- a/src/corelib/json/qjsonobject.cpp +++ b/src/corelib/json/qjsonobject.cpp @@ -274,7 +274,7 @@ QStringList QJsonObject::keys() const return QStringList(); QStringList keys; - + keys.reserve(o->length); for (uint i = 0; i < o->length; ++i) { QJsonPrivate::Entry *e = o->entryAt(i); keys.append(e->key()); diff --git a/src/corelib/json/qjsonobject.h b/src/corelib/json/qjsonobject.h index 5f24ac3ac8df174270310e5476b8cf791f06b3d4..19c938fd83fe14dfba96e0b87583a2c7b117b4ca 100644 --- a/src/corelib/json/qjsonobject.h +++ b/src/corelib/json/qjsonobject.h @@ -105,7 +105,7 @@ public: typedef QJsonValue value_type; typedef QJsonValueRef reference; - Q_DECL_CONSTEXPR inline iterator() : o(0), i(0) {} + Q_DECL_CONSTEXPR inline iterator() : o(Q_NULLPTR), i(0) {} Q_DECL_CONSTEXPR inline iterator(QJsonObject *obj, int index) : o(obj), i(index) {} inline QString key() const { return o->keyAt(i); } @@ -147,7 +147,7 @@ public: typedef QJsonValue value_type; typedef QJsonValue reference; - Q_DECL_CONSTEXPR inline const_iterator() : o(0), i(0) {} + Q_DECL_CONSTEXPR inline const_iterator() : o(Q_NULLPTR), i(0) {} Q_DECL_CONSTEXPR inline const_iterator(const QJsonObject *obj, int index) : o(obj), i(index) {} inline const_iterator(const iterator &other) diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 5a5307bd34260863d448ceaa2facdea87cf1e802..5a8a273b35915d50137aa433938c27bcb4cc4c29 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -90,7 +90,7 @@ win32 { } } -wince*: { +wince { SOURCES += \ kernel/qfunctions_wince.cpp HEADERS += \ diff --git a/src/corelib/kernel/qabstracteventdispatcher.h b/src/corelib/kernel/qabstracteventdispatcher.h index c80f7d3d084dadd1b46150326b38318232996008..eb357cefe567fea37abf16b64a322e1eabf3f73d 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.h +++ b/src/corelib/kernel/qabstracteventdispatcher.h @@ -64,10 +64,10 @@ public: { } }; - explicit QAbstractEventDispatcher(QObject *parent = 0); + explicit QAbstractEventDispatcher(QObject *parent = Q_NULLPTR); ~QAbstractEventDispatcher(); - static QAbstractEventDispatcher *instance(QThread *thread = 0); + static QAbstractEventDispatcher *instance(QThread *thread = Q_NULLPTR); virtual bool processEvents(QEventLoop::ProcessEventsFlags flags) = 0; virtual bool hasPendingEvents() = 0; // ### Qt6: remove, mark final or make protected diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index fa083a3f44102291e7f575f536fb49be4895efc5..c744873fce69cac51edee31ed7ada0aca438ba29 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -67,24 +67,6 @@ struct sockaddr; -#if defined(Q_OS_LINUX) && defined(O_CLOEXEC) -# define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1 -QT_BEGIN_NAMESPACE -namespace QtLibcSupplement { - inline int accept4(int, sockaddr *, QT_SOCKLEN_T *, int) - { errno = ENOSYS; return -1; } - inline int dup3(int, int, int) - { errno = ENOSYS; return -1; } - inline int pipe2(int [], int ) - { errno = ENOSYS; return -1; } -} -QT_END_NAMESPACE -using namespace QT_PREPEND_NAMESPACE(QtLibcSupplement); - -#else -# define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 0 -#endif - #define EINTR_LOOP(var, cmd) \ do { \ var = cmd; \ @@ -179,22 +161,14 @@ static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 07 // call qt_safe_pipe static inline int qt_safe_pipe(int pipefd[2], int flags = 0) { -#ifdef O_CLOEXEC - Q_ASSERT((flags & ~(O_CLOEXEC | O_NONBLOCK)) == 0); -#else Q_ASSERT((flags & ~O_NONBLOCK) == 0); -#endif - int ret; -#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(O_CLOEXEC) +#ifdef QT_THREADSAFE_CLOEXEC // use pipe2 flags |= O_CLOEXEC; - ret = ::pipe2(pipefd, flags); // pipe2 is Linux-specific and is documented not to return EINTR - if (ret == 0 || errno != ENOSYS) - return ret; -#endif - - ret = ::pipe(pipefd); + return ::pipe2(pipefd, flags); // pipe2 is documented not to return EINTR +#else + int ret = ::pipe(pipefd); if (ret == -1) return -1; @@ -208,6 +182,7 @@ static inline int qt_safe_pipe(int pipefd[2], int flags = 0) } return 0; +#endif } #endif // Q_OS_VXWORKS @@ -217,22 +192,19 @@ static inline int qt_safe_dup(int oldfd, int atleast = 0, int flags = FD_CLOEXEC { Q_ASSERT(flags == FD_CLOEXEC || flags == 0); - int ret; #ifdef F_DUPFD_CLOEXEC - // use this fcntl - if (flags & FD_CLOEXEC) { - ret = ::fcntl(oldfd, F_DUPFD_CLOEXEC, atleast); - if (ret != -1 || errno != EINVAL) - return ret; - } -#endif - + int cmd = F_DUPFD; + if (flags & FD_CLOEXEC) + cmd = F_DUPFD_CLOEXEC; + return ::fcntl(oldfd, cmd, atleast); +#else // use F_DUPFD - ret = ::fcntl(oldfd, F_DUPFD, atleast); + int ret = ::fcntl(oldfd, F_DUPFD, atleast); if (flags && ret != -1) ::fcntl(ret, F_SETFD, flags); return ret; +#endif } // don't call dup2 @@ -242,14 +214,11 @@ static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC) Q_ASSERT(flags == FD_CLOEXEC || flags == 0); int ret; -#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(O_CLOEXEC) +#ifdef QT_THREADSAFE_CLOEXEC // use dup3 - if (flags & FD_CLOEXEC) { - EINTR_LOOP(ret, ::dup3(oldfd, newfd, O_CLOEXEC)); - if (ret == 0 || errno != ENOSYS) - return ret; - } -#endif + EINTR_LOOP(ret, ::dup3(oldfd, newfd, flags ? O_CLOEXEC : 0)); + return ret; +#else EINTR_LOOP(ret, ::dup2(oldfd, newfd)); if (ret == -1) return -1; @@ -257,6 +226,7 @@ static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC) if (flags) ::fcntl(newfd, F_SETFD, flags); return 0; +#endif } static inline qint64 qt_safe_read(int fd, void *data, qint64 maxlen) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 17ec0eadf427d39c808910550924bdc8b27765e4..0b9543980c540deb873eaa5c27ef859d052bbf50 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Intel Corporation. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -333,12 +334,14 @@ struct QCoreApplicationData { QCoreApplicationData() Q_DECL_NOTHROW { #ifndef QT_NO_LIBRARY app_libpaths = 0; + manual_libpaths = 0; #endif applicationNameSet = false; } ~QCoreApplicationData() { #ifndef QT_NO_LIBRARY delete app_libpaths; + delete manual_libpaths; #endif #ifndef QT_NO_QOBJECT // cleanup the QAdoptedThread created for the main() thread @@ -384,6 +387,7 @@ struct QCoreApplicationData { #ifndef QT_NO_LIBRARY QStringList *app_libpaths; + QStringList *manual_libpaths; #endif }; @@ -401,7 +405,7 @@ static bool quitLockRefEnabled = true; // GUI apps or when using MinGW due to its globbing. static inline bool isArgvModified(int argc, char **argv) { - if (__argc != argc) + if (__argc != argc || !__argv /* wmain() */) return true; if (__argv == argv) return false; @@ -548,6 +552,14 @@ QThread *QCoreApplicationPrivate::mainThread() return theMainThread; } +bool QCoreApplicationPrivate::threadRequiresCoreApplication() +{ + QThreadData *data = QThreadData::current(false); + if (!data) + return true; // default setting + return data->requiresCoreApplication; +} + void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver) { QThread *currentThread = QThread::currentThread(); @@ -769,6 +781,38 @@ void QCoreApplication::init() QLoggingRegistry::instance()->init(); +#ifndef QT_NO_LIBRARY + // Reset the lib paths, so that they will be recomputed, taking the availability of argv[0] + // into account. If necessary, recompute right away and replay the manual changes on top of the + // new lib paths. + QStringList *appPaths = coreappdata()->app_libpaths; + QStringList *manualPaths = coreappdata()->manual_libpaths; + if (appPaths) { + coreappdata()->app_libpaths = 0; + if (manualPaths) { + // Replay the delta. As paths can only be prepended to the front or removed from + // anywhere in the list, we can just linearly scan the lists and find the items that + // have been removed. Once the original list is exhausted we know all the remaining + // items have been added. + coreappdata()->manual_libpaths = 0; + QStringList newPaths(libraryPaths()); + for (int i = manualPaths->length(), j = appPaths->length(); i > 0 || j > 0; qt_noop()) { + if (--j < 0) { + newPaths.prepend((*manualPaths)[--i]); + } else if (--i < 0) { + newPaths.removeAll((*appPaths)[j]); + } else if ((*manualPaths)[i] != (*appPaths)[j]) { + newPaths.removeAll((*appPaths)[j]); + ++i; // try again with next item. + } + } + delete manualPaths; + coreappdata()->manual_libpaths = new QStringList(newPaths); + } + delete appPaths; + } +#endif + #ifndef QT_NO_QOBJECT // use the event dispatcher created by the app programmer (if any) if (!QCoreApplicationPrivate::eventDispatcher) @@ -787,11 +831,6 @@ void QCoreApplication::init() d->eventDispatcherReady(); #endif -#ifndef QT_NO_LIBRARY - if (coreappdata()->app_libpaths) - d->appendApplicationPathToLibraryPaths(); -#endif - #ifdef QT_EVAL extern void qt_core_eval_init(QCoreApplicationPrivate::Type); qt_core_eval_init(d->application_type); @@ -846,6 +885,8 @@ QCoreApplication::~QCoreApplication() #ifndef QT_NO_LIBRARY delete coreappdata()->app_libpaths; coreappdata()->app_libpaths = 0; + delete coreappdata()->manual_libpaths; + coreappdata()->manual_libpaths = 0; #endif } @@ -936,6 +977,8 @@ bool QCoreApplication::isQuitLockEnabled() return quitLockRefEnabled; } +static bool doNotify(QObject *, QEvent *); + /*! Enables the ability of the QEventLoopLocker feature to quit the application. @@ -951,12 +994,29 @@ void QCoreApplication::setQuitLockEnabled(bool enabled) /*! \internal + \deprecated This function is here to make it possible for Qt extensions to hook into event notification without subclassing QApplication */ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event) { + return notifyInternal2(receiver, event); +} + +/*! + \internal + \since 5.6 + + This function is here to make it possible for Qt extensions to + hook into event notification without subclassing QApplication. +*/ +bool QCoreApplication::notifyInternal2(QObject *receiver, QEvent *event) +{ + bool selfRequired = QCoreApplicationPrivate::threadRequiresCoreApplication(); + if (!self && selfRequired) + return false; + // Make it possible for Qt Script to hook into events even // though QApplication is subclassed... bool result = false; @@ -972,10 +1032,11 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event) QObjectPrivate *d = receiver->d_func(); QThreadData *threadData = d->threadData; QScopedLoopLevelCounter loopLevelCounter(threadData); - return notify(receiver, event); + if (!selfRequired) + return doNotify(receiver, event); + return self->notify(receiver, event); } - /*! Sends \a event to \a receiver: \a {receiver}->event(\a event). Returns the value that is returned from the receiver's event @@ -1015,31 +1076,48 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event) do not change the focus widget. \endlist + \b{Future direction:} This function will not be called for objects that live + outside the main thread in Qt 6. Applications that need that functionality + should find other solutions for their event inspection needs in the meantime. + The change may be extended to the main thread, causing this function to be + deprecated. + + \warning If you override this function, you must ensure all threads that + process events stop doing so before your application object begins + destruction. This includes threads started by other libraries that you may be + using, but does not apply to Qt's own threads. + \sa QObject::event(), installNativeEventFilter() */ bool QCoreApplication::notify(QObject *receiver, QEvent *event) { - Q_D(QCoreApplication); // no events are delivered after ~QCoreApplication() has started if (QCoreApplicationPrivate::is_app_closing) return true; + return doNotify(receiver, event); +} +static bool doNotify(QObject *receiver, QEvent *event) +{ if (receiver == 0) { // serious error qWarning("QCoreApplication::notify: Unexpected null receiver"); return true; } #ifndef QT_NO_DEBUG - d->checkReceiverThread(receiver); + QCoreApplicationPrivate::checkReceiverThread(receiver); #endif - return receiver->isWidgetType() ? false : d->notify_helper(receiver, event); + return receiver->isWidgetType() ? false : QCoreApplicationPrivate::notify_helper(receiver, event); } bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event) { - if (receiver->d_func()->threadData == this->threadData && extraData) { + // We can't access the application event filters outside of the main thread (race conditions) + Q_ASSERT(receiver->d_func()->threadData->thread == mainThread()); + + if (extraData) { // application event filters are only called for objects in the GUI thread for (int i = 0; i < extraData->eventFilters.size(); ++i) { QObject *obj = extraData->eventFilters.at(i); @@ -1058,8 +1136,7 @@ bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiv bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event) { - Q_Q(QCoreApplication); - if (receiver != q && receiver->d_func()->extraData) { + if (receiver != QCoreApplication::instance() && receiver->d_func()->extraData) { for (int i = 0; i < receiver->d_func()->extraData->eventFilters.size(); ++i) { QObject *obj = receiver->d_func()->extraData->eventFilters.at(i); if (!obj) @@ -1078,12 +1155,14 @@ bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, Q /*! \internal - Helper function called by notify() + Helper function called by QCoreApplicationPrivate::notify() and qapplication.cpp */ bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event) { - // send to all application event filters - if (sendThroughApplicationEventFilters(receiver, event)) + // send to all application event filters (only does anything in the main thread) + if (QCoreApplication::self + && receiver->d_func()->threadData->thread == mainThread() + && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) return true; // send to all receiver event filters if (sendThroughObjectEventFilters(receiver, event)) @@ -2064,11 +2143,13 @@ QString QCoreApplication::applicationFilePath() QCoreApplicationPrivate *d = self->d_func(); - static char *procName = d->argv[0]; - if (qstrcmp(procName, d->argv[0]) != 0) { - // clear the cache if the procname changes, so we reprocess it. - QCoreApplicationPrivate::clearApplicationFilePath(); - procName = d->argv[0]; + if (d->argc) { + static const char *procName = d->argv[0]; + if (qstrcmp(procName, d->argv[0]) != 0) { + // clear the cache if the procname changes, so we reprocess it. + QCoreApplicationPrivate::clearApplicationFilePath(); + procName = d->argv[0]; + } } if (QCoreApplicationPrivate::cachedApplicationFilePath) @@ -2465,6 +2546,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive)) QStringList QCoreApplication::libraryPaths() { QMutexLocker locker(libraryPathMutex()); + + if (coreappdata()->manual_libpaths) + return *(coreappdata()->manual_libpaths); + if (!coreappdata()->app_libpaths) { QStringList *app_libpaths = coreappdata()->app_libpaths = new QStringList; QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath); @@ -2481,12 +2566,7 @@ QStringList QCoreApplication::libraryPaths() const QByteArray libPathEnv = qgetenv("QT_PLUGIN_PATH"); if (!libPathEnv.isEmpty()) { -#if defined(Q_OS_WIN) - QLatin1Char pathSep(';'); -#else - QLatin1Char pathSep(':'); -#endif - QStringList paths = QFile::decodeName(libPathEnv).split(pathSep, QString::SkipEmptyParts); + QStringList paths = QFile::decodeName(libPathEnv).split(QDir::listSeparator(), QString::SkipEmptyParts); for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) { QString canonicalPath = QDir(*it).canonicalPath(); if (!canonicalPath.isEmpty() @@ -2507,14 +2587,25 @@ QStringList QCoreApplication::libraryPaths() \a paths. All existing paths will be deleted and the path list will consist of the paths given in \a paths. + The library paths are reset to the default when an instance of + QCoreApplication is destructed. + \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary */ void QCoreApplication::setLibraryPaths(const QStringList &paths) { QMutexLocker locker(libraryPathMutex()); + + // setLibraryPaths() is considered a "remove everything and then add some new ones" operation. + // When the application is constructed it should still amend the paths. So we keep the originals + // around, and even create them if they don't exist, yet. if (!coreappdata()->app_libpaths) - coreappdata()->app_libpaths = new QStringList; - *(coreappdata()->app_libpaths) = paths; + libraryPaths(); + + if (!coreappdata()->manual_libpaths) + coreappdata()->manual_libpaths = new QStringList; + *(coreappdata()->manual_libpaths) = paths; + locker.unlock(); QFactoryLoader::refreshAll(); } @@ -2529,6 +2620,9 @@ void QCoreApplication::setLibraryPaths(const QStringList &paths) is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was installed. + The library paths are reset to the default when an instance of + QCoreApplication is destructed. + \sa removeLibraryPath(), libraryPaths(), setLibraryPaths() */ void QCoreApplication::addLibraryPath(const QString &path) @@ -2536,24 +2630,38 @@ void QCoreApplication::addLibraryPath(const QString &path) if (path.isEmpty()) return; + QString canonicalPath = QDir(path).canonicalPath(); + if (canonicalPath.isEmpty()) + return; + QMutexLocker locker(libraryPathMutex()); - // make sure that library paths is initialized - libraryPaths(); + QStringList *libpaths = coreappdata()->manual_libpaths; + if (libpaths) { + if (libpaths->contains(canonicalPath)) + return; + } else { + // make sure that library paths are initialized + libraryPaths(); + QStringList *app_libpaths = coreappdata()->app_libpaths; + if (app_libpaths->contains(canonicalPath)) + return; - QString canonicalPath = QDir(path).canonicalPath(); - if (!canonicalPath.isEmpty() - && !coreappdata()->app_libpaths->contains(canonicalPath)) { - coreappdata()->app_libpaths->prepend(canonicalPath); - locker.unlock(); - QFactoryLoader::refreshAll(); + libpaths = coreappdata()->manual_libpaths = new QStringList(*app_libpaths); } + + libpaths->prepend(canonicalPath); + locker.unlock(); + QFactoryLoader::refreshAll(); } /*! Removes \a path from the library path list. If \a path is empty or not in the path list, the list is not changed. + The library paths are reset to the default when an instance of + QCoreApplication is destructed. + \sa addLibraryPath(), libraryPaths(), setLibraryPaths() */ void QCoreApplication::removeLibraryPath(const QString &path) @@ -2561,13 +2669,28 @@ void QCoreApplication::removeLibraryPath(const QString &path) if (path.isEmpty()) return; + QString canonicalPath = QDir(path).canonicalPath(); + if (canonicalPath.isEmpty()) + return; + QMutexLocker locker(libraryPathMutex()); - // make sure that library paths is initialized - libraryPaths(); + QStringList *libpaths = coreappdata()->manual_libpaths; + if (libpaths) { + if (libpaths->removeAll(canonicalPath) == 0) + return; + } else { + // make sure that library paths is initialized + libraryPaths(); + QStringList *app_libpaths = coreappdata()->app_libpaths; + if (!app_libpaths->contains(canonicalPath)) + return; + + libpaths = coreappdata()->manual_libpaths = new QStringList(*app_libpaths); + libpaths->removeAll(canonicalPath); + } - QString canonicalPath = QDir(path).canonicalPath(); - coreappdata()->app_libpaths->removeAll(canonicalPath); + locker.unlock(); QFactoryLoader::refreshAll(); } diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index 1cd835daae095bdb1548818e137c943ab98c9af6..d865c4e7a8b6500f9b7f15cee47494abc6fd69fb 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -117,7 +117,7 @@ public: static bool sendEvent(QObject *receiver, QEvent *event); static void postEvent(QObject *receiver, QEvent *event, int priority = Qt::NormalEventPriority); - static void sendPostedEvents(QObject *receiver = 0, int event_type = 0); + static void sendPostedEvents(QObject *receiver = Q_NULLPTR, int event_type = 0); static void removePostedEvents(QObject *receiver, int eventType = 0); #if QT_DEPRECATED_SINCE(5, 3) QT_DEPRECATED static bool hasPendingEvents(); @@ -149,7 +149,7 @@ public: static QString translate(const char * context, const char * key, - const char * disambiguation = 0, + const char * disambiguation = Q_NULLPTR, int n = -1); #if QT_DEPRECATED_SINCE(5, 0) enum Encoding { UnicodeUTF8, Latin1, DefaultCodec = UnicodeUTF8, CodecForTr = UnicodeUTF8 }; @@ -194,7 +194,10 @@ protected: private: #ifndef QT_NO_QOBJECT static bool sendSpontaneousEvent(QObject *receiver, QEvent *event); - bool notifyInternal(QObject *receiver, QEvent *event); +# if QT_DEPRECATED_SINCE(5,6) + QT_DEPRECATED bool notifyInternal(QObject *receiver, QEvent *event); // ### Qt6 BIC: remove me +# endif + static bool notifyInternal2(QObject *receiver, QEvent *); #endif void init(); @@ -221,23 +224,23 @@ private: #ifndef QT_NO_QOBJECT inline bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event) -{ if (event) event->spont = false; return self ? self->notifyInternal(receiver, event) : false; } +{ if (event) event->spont = false; return notifyInternal2(receiver, event); } inline bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event) -{ if (event) event->spont = true; return self ? self->notifyInternal(receiver, event) : false; } +{ if (event) event->spont = true; return notifyInternal2(receiver, event); } #endif #ifdef QT_NO_DEPRECATED # define QT_DECLARE_DEPRECATED_TR_FUNCTIONS(context) #else # define QT_DECLARE_DEPRECATED_TR_FUNCTIONS(context) \ - QT_DEPRECATED static inline QString trUtf8(const char *sourceText, const char *disambiguation = 0, int n = -1) \ + QT_DEPRECATED static inline QString trUtf8(const char *sourceText, const char *disambiguation = Q_NULLPTR, int n = -1) \ { return QCoreApplication::translate(#context, sourceText, disambiguation, n); } #endif #define Q_DECLARE_TR_FUNCTIONS(context) \ public: \ - static inline QString tr(const char *sourceText, const char *disambiguation = 0, int n = -1) \ + static inline QString tr(const char *sourceText, const char *disambiguation = Q_NULLPTR, int n = -1) \ { return QCoreApplication::translate(#context, sourceText, disambiguation, n); } \ QT_DECLARE_DEPRECATED_TR_FUNCTIONS(context) \ private: diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 2646a28d71cbe8e2340ee9f80ae7aeae9f8c8b42..21f59d819707ec988991d87efab703fd64bc1845 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -86,8 +86,8 @@ public: #ifndef QT_NO_QOBJECT bool sendThroughApplicationEventFilters(QObject *, QEvent *); - bool sendThroughObjectEventFilters(QObject *, QEvent *); - bool notify_helper(QObject *, QEvent *); + static bool sendThroughObjectEventFilters(QObject *, QEvent *); + static bool notify_helper(QObject *, QEvent *); static inline void setEventSpontaneous(QEvent *e, bool spontaneous) { e->spont = spontaneous; } virtual void createEventDispatcher(); @@ -107,9 +107,11 @@ public: static QThread *theMainThread; static QThread *mainThread(); + static bool threadRequiresCoreApplication(); + static void sendPostedEvents(QObject *receiver, int event_type, QThreadData *data); - void checkReceiverThread(QObject *receiver); + static void checkReceiverThread(QObject *receiver); void cleanupThreadData(); #endif // QT_NO_QOBJECT diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index f3d8e99e8b91f291713b2ab2568243399cc8ec33..e8ff8a79363fa9eb750c3c4a2c8a7019b1fdd5e3 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -560,6 +560,17 @@ static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatch return wnd; } +static void calculateNextTimeout(WinTimerInfo *t, quint64 currentTime) +{ + uint interval = t->interval; + if ((interval >= 20000u && t->timerType != Qt::PreciseTimer) || t->timerType == Qt::VeryCoarseTimer) { + // round the interval, VeryCoarseTimers only have full second accuracy + interval = ((interval + 500)) / 1000 * 1000; + } + t->interval = interval; + t->timeout = currentTime + interval; +} + void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t) { Q_ASSERT(internalHwnd); @@ -567,6 +578,7 @@ void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t) Q_Q(QEventDispatcherWin32); int ok = 0; + calculateNextTimeout(t, qt_msectime()); uint interval = t->interval; if (interval == 0u) { // optimization for single-shot-zero-timer @@ -575,17 +587,13 @@ void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t) } else if ((interval < 20u || t->timerType == Qt::PreciseTimer) && qtimeSetEvent) { ok = t->fastTimerId = qtimeSetEvent(interval, 1, qt_fast_timer_proc, (DWORD_PTR)t, TIME_CALLBACK_FUNCTION | TIME_PERIODIC | TIME_KILL_SYNCHRONOUS); - } else if (interval >= 20000u || t->timerType == Qt::VeryCoarseTimer) { - // round the interval, VeryCoarseTimers only have full second accuracy - interval = ((interval + 500)) / 1000 * 1000; } + if (ok == 0) { // user normal timers for (Very)CoarseTimers, or if no more multimedia timers available ok = SetTimer(internalHwnd, t->timerId, interval, 0); } - t->timeout = qt_msectime() + interval; - if (ok == 0) qErrnoWarning("QEventDispatcherWin32::registerTimer: Failed to create a timer"); } @@ -610,6 +618,9 @@ void QEventDispatcherWin32Private::sendTimerEvent(int timerId) // send event, but don't allow it to recurse t->inTimerEvent = true; + // recalculate next emission + calculateNextTimeout(t, qt_msectime()); + QTimerEvent e(t->timerId); QCoreApplication::sendEvent(t->obj, &e); @@ -1075,11 +1086,10 @@ void QEventDispatcherWin32::activateEventNotifiers() for (int i=0; i<d->winEventNotifierList.count(); i++) { #if !defined(Q_OS_WINCE) if (WaitForSingleObjectEx(d->winEventNotifierList.at(i)->handle(), 0, TRUE) == WAIT_OBJECT_0) - d->activateEventNotifier(d->winEventNotifierList.at(i)); #else if (WaitForSingleObject(d->winEventNotifierList.at(i)->handle(), 0) == WAIT_OBJECT_0) - d->activateEventNotifier(d->winEventNotifierList.at(i)); #endif + d->activateEventNotifier(d->winEventNotifierList.at(i)); } } diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index 6b4fb18f4693c2c1b245e6dc361399b449e45a3a..e59e29f1ffa05e1836ca96e81aeb7d44d9e5415b 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -58,7 +58,7 @@ class QEventDispatcherWin32Private; // forward declaration LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); -int qt_msectime(); +quint64 qt_msectime(); class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher { diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp index 150999619974c623fac1c6a571ce3d902b876d5b..eceba8d002504fda17475cf8522bca9f42bdd298 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt.cpp +++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp @@ -144,7 +144,10 @@ private: IID_PPV_ARGS(&application)); RETURN_VOID_IF_FAILED("Failed to get the application factory"); - ComPtr<ICoreApplicationView> view; + static ComPtr<ICoreApplicationView> view; + if (view) + return; + hr = application->get_MainView(&view); RETURN_VOID_IF_FAILED("Failed to get the main view"); @@ -166,13 +169,6 @@ QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent) { Q_D(QEventDispatcherWinRT); - // Special treatment for the WinMain thread, as it is created before the UI - static bool firstThread = true; - if (firstThread) { - firstThread = false; - return; - } - d->fetchCoreDispatcher(); } @@ -212,6 +208,7 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags) DWORD waitResult = WaitForMultipleObjectsEx(timerHandles.count(), timerHandles.constData(), FALSE, 1, TRUE); if (waitResult >= WAIT_OBJECT_0 && waitResult < WAIT_OBJECT_0 + timerHandles.count()) { const HANDLE handle = timerHandles.value(waitResult - WAIT_OBJECT_0); + ResetEvent(handle); const int timerId = d->timerHandleToId.value(handle); if (timerId == INTERRUPT_HANDLE) break; @@ -288,8 +285,8 @@ void QEventDispatcherWinRT::registerTimer(int timerId, int interval, Qt::TimerTy TimeSpan period; period.Duration = interval ? (interval * 10000) : 1; // TimeSpan is based on 100-nanosecond units IThreadPoolTimer *timer; - const HANDLE handle = CreateEventEx(NULL, NULL, NULL, SYNCHRONIZE|EVENT_MODIFY_STATE); - const HANDLE cancelHandle = CreateEventEx(NULL, NULL, NULL, SYNCHRONIZE|EVENT_MODIFY_STATE); + const HANDLE handle = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, SYNCHRONIZE | EVENT_MODIFY_STATE); + const HANDLE cancelHandle = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, SYNCHRONIZE|EVENT_MODIFY_STATE); HRESULT hr = d->timerFactory->CreatePeriodicTimerWithCompletion( Callback<ITimerElapsedHandler>([handle, cancelHandle](IThreadPoolTimer *timer) { DWORD cancelResult = WaitForSingleObjectEx(cancelHandle, 0, TRUE); @@ -376,7 +373,7 @@ QList<QAbstractEventDispatcher::TimerInfo> QEventDispatcherWinRT::registeredTime Q_D(const QEventDispatcherWinRT); QList<TimerInfo> timerInfos; foreach (const WinRTTimerInfo &info, d->timerInfos) { - if (info.object == object) + if (info.object == object && info.timerId != INVALID_TIMER_ID) timerInfos.append(info); } return timerInfos; @@ -486,7 +483,9 @@ bool QEventDispatcherWinRT::event(QEvent *e) QEventDispatcherWinRTPrivate::QEventDispatcherWinRTPrivate() { - CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + const bool isGuiThread = QCoreApplication::instance() && + QThread::currentThread() == QCoreApplication::instance()->thread(); + CoInitializeEx(NULL, isGuiThread ? COINIT_APARTMENTTHREADED : COINIT_MULTITHREADED); HRESULT hr; hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Threading_ThreadPoolTimer).Get(), &timerFactory); Q_ASSERT_SUCCEEDED(hr); diff --git a/src/corelib/kernel/qeventdispatcher_winrt_p.h b/src/corelib/kernel/qeventdispatcher_winrt_p.h index e39746aeefa0aabfcd76706c775e653bdc1774b1..fd3d259c96b08b876e284ae277a16557a40be994 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt_p.h +++ b/src/corelib/kernel/qeventdispatcher_winrt_p.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE -int qt_msectime(); +quint64 qt_msectime(); class QEventDispatcherWinRTPrivate; diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp index 1723db0ab9fd61831d53251ab1cf58d9f05edaf4..dca25ce968a68542269c3ec5b63db87f54186333 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -93,7 +93,7 @@ QEventLoop::QEventLoop(QObject *parent) : QObject(*new QEventLoopPrivate, parent) { Q_D(QEventLoop); - if (!QCoreApplication::instance()) { + if (!QCoreApplication::instance() && QCoreApplicationPrivate::threadRequiresCoreApplication()) { qWarning("QEventLoop: Cannot be used without QApplication"); } else if (!d->threadData->eventDispatcher.load()) { QThreadPrivate::createEventDispatcher(d->threadData); diff --git a/src/corelib/kernel/qeventloop.h b/src/corelib/kernel/qeventloop.h index 99c0cd50ff57745d8ef9f287456ec6d0cf2ef223..375a63abddc753a4baf648a987b4a962004ea9af 100644 --- a/src/corelib/kernel/qeventloop.h +++ b/src/corelib/kernel/qeventloop.h @@ -47,7 +47,7 @@ class Q_CORE_EXPORT QEventLoop : public QObject Q_DECLARE_PRIVATE(QEventLoop) public: - explicit QEventLoop(QObject *parent = 0); + explicit QEventLoop(QObject *parent = Q_NULLPTR); ~QEventLoop(); enum ProcessEventsFlag { diff --git a/src/corelib/kernel/qfunctions_wince.cpp b/src/corelib/kernel/qfunctions_wince.cpp index 8f8fc21313fab7374fed30c2dffb9b592a38b3b4..2503a262cd30ec5696bae2c98244862a18a78ab2 100644 --- a/src/corelib/kernel/qfunctions_wince.cpp +++ b/src/corelib/kernel/qfunctions_wince.cpp @@ -36,7 +36,11 @@ #include <winbase.h> #include <kfuncs.h> #include <stdio.h> -#include <altcecrt.h> +#if _WIN32_WCE < 0x800 +# include <altcecrt.h> +#else +# include <fcntl.h> +#endif #include "qplatformdefs.h" #include "qfunctions_wince.h" @@ -93,7 +97,9 @@ FILETIME qt_wince_time_tToFt( time_t tt ) } // File I/O --------------------------------------------------------- +#if _WIN32_WCE < 0x800 int errno = 0; +#endif int qt_wince__getdrive( void ) { diff --git a/src/corelib/kernel/qfunctions_wince.h b/src/corelib/kernel/qfunctions_wince.h index 987342d29a330e7a4b8ece4201a94e8b7dc436e9..d172acceecf411bbfedf14d2e3a06ff8cd0f6502 100644 --- a/src/corelib/kernel/qfunctions_wince.h +++ b/src/corelib/kernel/qfunctions_wince.h @@ -37,6 +37,9 @@ #include <QtCore/qglobal.h> #ifdef Q_OS_WINCE +# ifndef NOMINMAX +# define NOMINMAX +# endif #include <stdio.h> #include <stdlib.h> #include <windows.h> @@ -47,7 +50,12 @@ #include <ctype.h> #include <time.h> #include <crtdefs.h> -#include <altcecrt.h> +#if _WIN32_WCE < 0x800 +# include <altcecrt.h> +#else +# include <fcntl.h> +# include <stat.h> +#endif #include <winsock.h> #include <ceconfig.h> @@ -102,6 +110,8 @@ struct tm { FILETIME qt_wince_time_tToFt( time_t tt ); time_t qt_wince_ftToTime_t( const FILETIME ft ); +#if _WIN32_WCE < 0x800 + // File I/O --------------------------------------------------------- #define _O_RDONLY 0x0001 #define _O_RDWR 0x0002 @@ -161,6 +171,7 @@ struct stat typedef int mode_t; extern int errno; +#endif // _WIN32_WCE < 0x800 int qt_wince__getdrive( void ); int qt_wince__waccess( const wchar_t *path, int pmode ); @@ -437,8 +448,10 @@ generate_inline_return_func0(tmpfile, FILE *) generate_inline_return_func2(_rename, int, const char *, const char *) generate_inline_return_func1(_remove, int, const char *) generate_inline_return_func1(SetErrorMode, int, int) +#if _WIN32_WCE < 0x800 generate_inline_return_func2(_chmod, bool, const char *, int) generate_inline_return_func2(_wchmod, bool, const wchar_t *, int) +#endif generate_inline_return_func7(CreateFileA, HANDLE, LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE) generate_inline_return_func4(SetWindowOrgEx, BOOL, HDC, int, int, LPPOINT) generate_inline_return_func2(calloc, void *, size_t, size_t) diff --git a/src/corelib/kernel/qmath.h b/src/corelib/kernel/qmath.h index 5cc3ec586ed063ca020d8db29f365f32825a578f..e60561c05f3a57890141350202e80595581190aa 100644 --- a/src/corelib/kernel/qmath.h +++ b/src/corelib/kernel/qmath.h @@ -40,8 +40,18 @@ #include <QtCore/qglobal.h> +#ifndef _USE_MATH_DEFINES +# define _USE_MATH_DEFINES +# define undef_USE_MATH_DEFINES +#endif + #include <cmath> +#ifdef undef_USE_MATH_DEFINES +# undef _USE_MATH_DEFINES +# undef undef_USE_MATH_DEFINES +#endif + QT_BEGIN_NAMESPACE #define QT_SINE_TABLE_SIZE 256 diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 60cd3ab94a61f39b9d698b454b81ab288eaed49a..90ee7d8f950636f8309dd9ab840fdc50fee8eee1 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1879,13 +1879,14 @@ const char *QMetaMethod::typeName() const way in the function declaration: \code + // In the class MainWindow declaration #ifndef Q_MOC_RUN - // define the tag text - # define THISISTESTTAG + // define the tag text as empty, so the compiler doesn't see it + # define MY_CUSTOM_TAG #endif ... private slots: - THISISTESTTAG void testFunc(); + MY_CUSTOM_TAG void testFunc(); \endcode and the information can be accessed by using: @@ -1895,12 +1896,14 @@ const char *QMetaMethod::typeName() const win.show(); int functionIndex = win.metaObject()->indexOfSlot("testFunc()"); - QMetaMethod mm = metaObject()->method(functionIndex); - qDebug() << mm.tag(); // prints THISISTESTTAG + QMetaMethod mm = win.metaObject()->method(functionIndex); + qDebug() << mm.tag(); // prints MY_CUSTOM_TAG \endcode For the moment, \c moc will extract and record all tags, but it will not - handle any of them specially. + handle any of them specially. You can use the tags to annotate your methods + differently, and treat them according to the specific needs of your + application. \note Since Qt 5.0, \c moc expands preprocessor macros, so it is necessary to surround the definition with \c #ifndef \c Q_MOC_RUN, as shown in the @@ -1960,8 +1963,9 @@ int QMetaMethod::revision() const Returns the access specification of this method (private, protected, or public). - Signals are always protected, meaning that you can only emit them - from the class or from a subclass. + \note Signals are always public, but you should regard that as an + implementation detail. It is almost always a bad idea to emit a signal from + outside its class. \sa methodType() */ diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h index b522a211bbaea6dfb17445f187a9a1bb7715d1df..1a282d3261bab2276ed3b9ac47d4aa03429575c6 100644 --- a/src/corelib/kernel/qmetaobject.h +++ b/src/corelib/kernel/qmetaobject.h @@ -48,7 +48,7 @@ template <typename T> class QList; class Q_CORE_EXPORT QMetaMethod { public: - Q_DECL_CONSTEXPR inline QMetaMethod() : mobj(0),handle(0) {} + Q_DECL_CONSTEXPR inline QMetaMethod() : mobj(Q_NULLPTR), handle(0) {} QByteArray methodSignature() const; QByteArray name() const; @@ -74,7 +74,7 @@ public: bool invoke(QObject *object, Qt::ConnectionType connectionType, QGenericReturnArgument returnValue, - QGenericArgument val0 = QGenericArgument(0), + QGenericArgument val0 = QGenericArgument(Q_NULLPTR), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), @@ -86,7 +86,7 @@ public: QGenericArgument val9 = QGenericArgument()) const; inline bool invoke(QObject *object, QGenericReturnArgument returnValue, - QGenericArgument val0 = QGenericArgument(0), + QGenericArgument val0 = QGenericArgument(Q_NULLPTR), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), @@ -102,7 +102,7 @@ public: } inline bool invoke(QObject *object, Qt::ConnectionType connectionType, - QGenericArgument val0 = QGenericArgument(0), + QGenericArgument val0 = QGenericArgument(Q_NULLPTR), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), @@ -117,7 +117,7 @@ public: val0, val1, val2, val3, val4, val5, val6, val7, val8, val9); } inline bool invoke(QObject *object, - QGenericArgument val0 = QGenericArgument(0), + QGenericArgument val0 = QGenericArgument(Q_NULLPTR), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), @@ -134,7 +134,7 @@ public: bool invokeOnGadget(void *gadget, QGenericReturnArgument returnValue, - QGenericArgument val0 = QGenericArgument(0), + QGenericArgument val0 = QGenericArgument(Q_NULLPTR), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), @@ -145,7 +145,7 @@ public: QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument()) const; inline bool invokeOnGadget(void *gadget, - QGenericArgument val0 = QGenericArgument(0), + QGenericArgument val0 = QGenericArgument(Q_NULLPTR), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), @@ -160,7 +160,7 @@ public: val0, val1, val2, val3, val4, val5, val6, val7, val8, val9); } - inline bool isValid() const { return mobj != 0; } + inline bool isValid() const { return mobj != Q_NULLPTR; } #ifdef Q_QDOC static QMetaMethod fromSignal(PointerToMemberFunction signal); @@ -204,7 +204,7 @@ inline bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2) class Q_CORE_EXPORT QMetaEnum { public: - Q_DECL_CONSTEXPR inline QMetaEnum() : mobj(0),handle(0) {} + Q_DECL_CONSTEXPR inline QMetaEnum() : mobj(Q_NULLPTR), handle(0) {} const char *name() const; bool isFlag() const; @@ -215,14 +215,14 @@ public: const char *scope() const; - int keyToValue(const char *key, bool *ok = 0) const; + int keyToValue(const char *key, bool *ok = Q_NULLPTR) const; const char* valueToKey(int value) const; - int keysToValue(const char * keys, bool *ok = 0) const; + int keysToValue(const char * keys, bool *ok = Q_NULLPTR) const; QByteArray valueToKeys(int value) const; inline const QMetaObject *enclosingMetaObject() const { return mobj; } - inline bool isValid() const { return name() != 0; } + inline bool isValid() const { return name() != Q_NULLPTR; } template<typename T> static QMetaEnum fromType() { Q_STATIC_ASSERT_X(QtPrivate::IsQEnumHelper<T>::Value, @@ -253,11 +253,11 @@ public: bool isReadable() const; bool isWritable() const; bool isResettable() const; - bool isDesignable(const QObject *obj = 0) const; - bool isScriptable(const QObject *obj = 0) const; - bool isStored(const QObject *obj = 0) const; - bool isEditable(const QObject *obj = 0) const; - bool isUser(const QObject *obj = 0) const; + bool isDesignable(const QObject *obj = Q_NULLPTR) const; + bool isScriptable(const QObject *obj = Q_NULLPTR) const; + bool isStored(const QObject *obj = Q_NULLPTR) const; + bool isEditable(const QObject *obj = Q_NULLPTR) const; + bool isUser(const QObject *obj = Q_NULLPTR) const; bool isConstant() const; bool isFinal() const; @@ -297,7 +297,7 @@ private: class Q_CORE_EXPORT QMetaClassInfo { public: - Q_DECL_CONSTEXPR inline QMetaClassInfo() : mobj(0),handle(0) {} + Q_DECL_CONSTEXPR inline QMetaClassInfo() : mobj(Q_NULLPTR), handle(0) {} const char *name() const; const char *value() const; inline const QMetaObject *enclosingMetaObject() const { return mobj; } diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp index a1b8125121f37e61f1775274dfee38d49bb5625a..021e137273c86ec96c15194e0fa45046ce4b176d 100644 --- a/src/corelib/kernel/qmetaobjectbuilder.cpp +++ b/src/corelib/kernel/qmetaobjectbuilder.cpp @@ -88,6 +88,7 @@ static inline Q_DECL_UNUSED const QMetaObjectPrivate *priv(const uint* data) class QMetaMethodBuilderPrivate { public: + QMetaMethodBuilderPrivate() {} // for QVector, don't use QMetaMethodBuilderPrivate (QMetaMethod::MethodType _methodType, const QByteArray& _signature, @@ -139,10 +140,12 @@ public: return signature.left(qMax(signature.indexOf('('), 0)); } }; +Q_DECLARE_TYPEINFO(QMetaMethodBuilderPrivate, Q_MOVABLE_TYPE); class QMetaPropertyBuilderPrivate { public: + QMetaPropertyBuilderPrivate() {} // for QVector, don't use QMetaPropertyBuilderPrivate (const QByteArray& _name, const QByteArray& _type, int notifierIdx=-1, int _revision = 0) @@ -176,10 +179,12 @@ public: flags &= ~f; } }; +Q_DECLARE_TYPEINFO(QMetaPropertyBuilderPrivate, Q_MOVABLE_TYPE); class QMetaEnumBuilderPrivate { public: + QMetaEnumBuilderPrivate() {} // for QVector, don't use QMetaEnumBuilderPrivate(const QByteArray& _name) : name(_name), isFlag(false) { @@ -188,8 +193,9 @@ public: QByteArray name; bool isFlag; QList<QByteArray> keys; - QList<int> values; + QVector<int> values; }; +Q_DECLARE_TYPEINFO(QMetaEnumBuilderPrivate, Q_MOVABLE_TYPE); class QMetaObjectBuilderPrivate { @@ -207,12 +213,12 @@ public: QByteArray className; const QMetaObject *superClass; QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction; - QList<QMetaMethodBuilderPrivate> methods; - QList<QMetaMethodBuilderPrivate> constructors; - QList<QMetaPropertyBuilderPrivate> properties; + QVector<QMetaMethodBuilderPrivate> methods; + QVector<QMetaMethodBuilderPrivate> constructors; + QVector<QMetaPropertyBuilderPrivate> properties; QList<QByteArray> classInfoNames; QList<QByteArray> classInfoValues; - QList<QMetaEnumBuilderPrivate> enumerators; + QVector<QMetaEnumBuilderPrivate> enumerators; QList<const QMetaObject *> relatedMetaObjects; int flags; }; @@ -1149,7 +1155,7 @@ void QMetaStringTable::writeBlob(char *out) const // Returns the sum of all parameters (including return type) for the given // \a methods. This is needed for calculating the size of the methods' // parameter type/name meta-data. -static int aggregateParameterCount(const QList<QMetaMethodBuilderPrivate> &methods) +static int aggregateParameterCount(const QVector<QMetaMethodBuilderPrivate> &methods) { int sum = 0; for (int i = 0; i < methods.size(); ++i) @@ -1330,7 +1336,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, Q_ASSERT(!buf || dataIndex == pmeta->methodData + d->methods.size() * 5 + (hasRevisionedMethods ? d->methods.size() : 0)); for (int x = 0; x < 2; ++x) { - QList<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors; + QVector<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors; for (index = 0; index < methods.size(); ++index) { QMetaMethodBuilderPrivate *method = &(methods[index]); QList<QByteArray> paramTypeNames = method->parameterTypes(); diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 3b70ef92edfc567fbeb874ddae36cea6f57a4739..641053371d0bb54722c729c68f237993e375a097 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -303,7 +303,7 @@ struct DefinedTypesFilter { \omitvalue WeakPointerToQObject \omitvalue TrackingPointerToQObject \omitvalue WasDeclaredAsMetaType - \value IsGadget This type is a Q_GADGET and it's corresponding QMetaObject can be accessed with QMetaType::metaObject Since 5.5. + \omitvalue IsGadget This type is a Q_GADGET and it's corresponding QMetaObject can be accessed with QMetaType::metaObject Since 5.5. */ /*! @@ -1046,6 +1046,16 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, if (idx >= User) { previousSize = ct->at(idx - User).size; previousFlags = ct->at(idx - User).flags; + + // Set new/additional flags in case of old library/app. + // Ensures that older code works in conjunction with new Qt releases + // requiring the new flags. + if (flags != previousFlags) { + QCustomTypeInfo &inf = ct->data()[idx - User]; + inf.flags |= flags; + if (metaObject) + inf.metaObject = metaObject; + } } } @@ -1061,11 +1071,11 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, normalizedTypeName.constData(), idx, previousSize, size); } + // Do not compare types higher than 0x100: // Ignore WasDeclaredAsMetaType inconsitency, to many users were hitting the problem - previousFlags |= WasDeclaredAsMetaType; - flags |= WasDeclaredAsMetaType; - - if (previousFlags != flags) { + // Ignore IsGadget as it was added in Qt 5.5 + // Ignore all the future flags as well + if ((previousFlags ^ flags) & 0xff) { const int maskForTypeInfo = NeedsConstruction | NeedsDestruction | MovableType; const char *msg = "QMetaType::registerType: Binary compatibility break. " "\nType flags for type '%s' [%i] don't match. Previously " @@ -1168,12 +1178,6 @@ bool QMetaType::isRegistered(int type) return ((type >= User) && (ct && ct->count() > type - User) && !ct->at(type - User).typeName.isEmpty()); } -/*! - \fn int qMetaTypeTypeImpl(const char *typeName, int length) - \internal - - Implementation of QMetaType::type(). -*/ template <bool tryNormalizedType> static inline int qMetaTypeTypeImpl(const char *typeName, int length) { diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 1b214e9f74830c766b798b8099689a52386ee482..9e3e1e94faf46e7f0155f949e0a75a532d89fc1d 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -229,7 +229,7 @@ struct AbstractDebugStreamFunction { typedef void (*Stream)(const AbstractDebugStreamFunction *, QDebug&, const void *); typedef void (*Destroy)(AbstractDebugStreamFunction *); - explicit AbstractDebugStreamFunction(Stream s = 0, Destroy d = 0) + explicit AbstractDebugStreamFunction(Stream s = Q_NULLPTR, Destroy d = Q_NULLPTR) : stream(s), destroy(d) {} Q_DISABLE_COPY(AbstractDebugStreamFunction) Stream stream; @@ -259,7 +259,7 @@ struct AbstractComparatorFunction typedef bool (*LessThan)(const AbstractComparatorFunction *, const void *, const void *); typedef bool (*Equals)(const AbstractComparatorFunction *, const void *, const void *); typedef void (*Destroy)(AbstractComparatorFunction *); - explicit AbstractComparatorFunction(LessThan lt = 0, Equals e = 0, Destroy d = 0) + explicit AbstractComparatorFunction(LessThan lt = Q_NULLPTR, Equals e = Q_NULLPTR, Destroy d = Q_NULLPTR) : lessThan(lt), equals(e), destroy(d) {} Q_DISABLE_COPY(AbstractComparatorFunction) LessThan lessThan; @@ -296,7 +296,7 @@ template<typename T> struct BuiltInEqualsComparatorFunction : public AbstractComparatorFunction { BuiltInEqualsComparatorFunction() - : AbstractComparatorFunction(0, equals, destroy) {} + : AbstractComparatorFunction(Q_NULLPTR, equals, destroy) {} static bool equals(const AbstractComparatorFunction *, const void *l, const void *r) { const T *lhs = static_cast<const T *>(l); @@ -313,7 +313,7 @@ struct BuiltInEqualsComparatorFunction : public AbstractComparatorFunction struct AbstractConverterFunction { typedef bool (*Converter)(const AbstractConverterFunction *, const void *, void*); - explicit AbstractConverterFunction(Converter c = 0) + explicit AbstractConverterFunction(Converter c = Q_NULLPTR) : convert(c) {} Q_DISABLE_COPY(AbstractConverterFunction) Converter convert; @@ -510,9 +510,9 @@ public: static TypeFlags typeFlags(int type); static const QMetaObject *metaObjectForType(int type); static bool isRegistered(int type); - static void *create(int type, const void *copy = 0); + static void *create(int type, const void *copy = Q_NULLPTR); #if QT_DEPRECATED_SINCE(5, 0) - QT_DEPRECATED static void *construct(int type, const void *copy = 0) + QT_DEPRECATED static void *construct(int type, const void *copy = Q_NULLPTR) { return create(type, copy); } #endif static void destroy(int type, void *data); @@ -533,9 +533,9 @@ public: inline TypeFlags flags() const; inline const QMetaObject *metaObject() const; - inline void *create(const void *copy = 0) const; + inline void *create(const void *copy = Q_NULLPTR) const; inline void destroy(void *data) const; - inline void *construct(void *where, const void *copy = 0) const; + inline void *construct(void *where, const void *copy = Q_NULLPTR) const; inline void destruct(void *data) const; public: @@ -611,7 +611,7 @@ public: return registerConverterFunction(&f, fromTypeId, toTypeId); } - // member function as in "double QString::toDouble(bool *ok = 0) const" + // member function as in "double QString::toDouble(bool *ok = Q_NULLPTR) const" template<typename From, typename To> static bool registerConverter(To(From::*function)(bool*) const) { @@ -674,9 +674,9 @@ private: uint sizeExtended() const; QMetaType::TypeFlags flagsExtended() const; const QMetaObject *metaObjectExtended() const; - void *createExtended(const void *copy = 0) const; + void *createExtended(const void *copy = Q_NULLPTR) const; void destroyExtended(void *data) const; - void *constructExtended(void *where, const void *copy = 0) const; + void *constructExtended(void *where, const void *copy = Q_NULLPTR) const; void destructExtended(void *data) const; static bool registerComparatorFunction(const QtPrivate::AbstractComparatorFunction *f, int type); @@ -740,6 +740,11 @@ ConverterFunctor<From, To, UnaryFunction>::~ConverterFunctor() } +#define QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(C, F) \ + } \ + Q_DECLARE_TYPEINFO(QtMetaTypePrivate:: C, (F)); \ + namespace QtMetaTypePrivate { + namespace QtMetaTypePrivate { template <typename T, bool Accepted = true> struct QMetaTypeFunctionHelper { @@ -771,7 +776,7 @@ struct QMetaTypeFunctionHelper { template <typename T> struct QMetaTypeFunctionHelper<T, /* Accepted */ false> { static void Destruct(void *) {} - static void *Construct(void *, const void *) { return 0; } + static void *Construct(void *, const void *) { return Q_NULLPTR; } #ifndef QT_NO_DATASTREAM static void Save(QDataStream &, const void *) {} static void Load(QDataStream &, void *) {} @@ -1009,7 +1014,7 @@ public: public: template<class T> QSequentialIterableImpl(const T*p) : _iterable(p) - , _iterator(0) + , _iterator(Q_NULLPTR) , _metaType_id(qMetaTypeId<typename T::value_type>()) , _metaType_flags(QTypeInfo<typename T::value_type>::isPointer) , _iteratorCapabilities(ContainerAPI<T>::IteratorCapabilities) @@ -1026,20 +1031,20 @@ public: } QSequentialIterableImpl() - : _iterable(0) - , _iterator(0) + : _iterable(Q_NULLPTR) + , _iterator(Q_NULLPTR) , _metaType_id(QMetaType::UnknownType) , _metaType_flags(0) , _iteratorCapabilities(0) - , _size(0) - , _at(0) - , _moveToBegin(0) - , _moveToEnd(0) - , _advance(0) - , _get(0) - , _destroyIter(0) - , _equalIter(0) - , _copyIter(0) + , _size(Q_NULLPTR) + , _at(Q_NULLPTR) + , _moveToBegin(Q_NULLPTR) + , _moveToEnd(Q_NULLPTR) + , _advance(Q_NULLPTR) + , _get(Q_NULLPTR) + , _destroyIter(Q_NULLPTR) + , _equalIter(Q_NULLPTR) + , _copyIter(Q_NULLPTR) { } @@ -1067,6 +1072,7 @@ public: _copyIter(&_iterator, &other._iterator); } }; +QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(QSequentialIterableImpl, Q_MOVABLE_TYPE) template<typename From> struct QSequentialIterableConvertFunctor @@ -1195,21 +1201,21 @@ public: } QAssociativeIterableImpl() - : _iterable(0) + : _iterable(Q_NULLPTR) , _metaType_id_key(QMetaType::UnknownType) , _metaType_flags_key(0) , _metaType_id_value(QMetaType::UnknownType) , _metaType_flags_value(0) - , _size(0) - , _find(0) - , _begin(0) - , _end(0) - , _advance(0) - , _getKey(0) - , _getValue(0) - , _destroyIter(0) - , _equalIter(0) - , _copyIter(0) + , _size(Q_NULLPTR) + , _find(Q_NULLPTR) + , _begin(Q_NULLPTR) + , _end(Q_NULLPTR) + , _advance(Q_NULLPTR) + , _getKey(Q_NULLPTR) + , _getValue(Q_NULLPTR) + , _destroyIter(Q_NULLPTR) + , _equalIter(Q_NULLPTR) + , _copyIter(Q_NULLPTR) { } @@ -1234,6 +1240,7 @@ public: _copyIter(&_iterator, &other._iterator); } }; +QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(QAssociativeIterableImpl, Q_MOVABLE_TYPE) template<typename From> struct QAssociativeIterableConvertFunctor @@ -1277,15 +1284,20 @@ public: } QPairVariantInterfaceImpl() - : _pair(0) - , _getFirst(0) - , _getSecond(0) + : _pair(Q_NULLPTR) + , _metaType_id_first(QMetaType::UnknownType) + , _metaType_flags_first(0) + , _metaType_id_second(QMetaType::UnknownType) + , _metaType_flags_second(0) + , _getFirst(Q_NULLPTR) + , _getSecond(Q_NULLPTR) { } inline VariantData first() const { return _getFirst(&_pair, _metaType_id_first, _metaType_flags_first); } inline VariantData second() const { return _getSecond(&_pair, _metaType_id_second, _metaType_flags_second); } }; +QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(QPairVariantInterfaceImpl, Q_MOVABLE_TYPE) template<typename From> struct QPairVariantInterfaceConvertFunctor; @@ -1354,7 +1366,7 @@ namespace QtPrivate #endif static no_type checkType(...); Q_STATIC_ASSERT_X(sizeof(T), "Type argument of Q_DECLARE_METATYPE(T*) must be fully defined"); - enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(yes_type) }; + enum { Value = sizeof(checkType(static_cast<T*>(Q_NULLPTR))) == sizeof(yes_type) }; }; template<typename T, typename Enable = void> @@ -1391,7 +1403,7 @@ QT_WARNING_POP template<typename T, typename Enable = void> struct MetaObjectForType { - static inline const QMetaObject *value() { return 0; } + static inline const QMetaObject *value() { return Q_NULLPTR; } }; template<> struct MetaObjectForType<void> @@ -1692,7 +1704,7 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz template <typename T> int qRegisterMetaType(const char *typeName #ifndef Q_QDOC - , T * dummy = 0 + , T * dummy = Q_NULLPTR , typename QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::Defined #endif ) @@ -1709,7 +1721,7 @@ int qRegisterMetaType(const char *typeName template <typename T> void qRegisterMetaTypeStreamOperators(const char *typeName #ifndef Q_QDOC - , T * /* dummy */ = 0 + , T * /* dummy */ = Q_NULLPTR #endif ) { @@ -2095,7 +2107,7 @@ inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeI , m_loadOp(loadOp) , m_constructor(constructor) , m_destructor(destructor) - , m_extension(0) + , m_extension(Q_NULLPTR) , m_size(size) , m_typeFlags(theTypeFlags) , m_extensionFlags(extensionFlags) diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp index 3e9cdac966e0545d1f23103cab843946c590a49a..93788afeae5e8c1cd16d4c43e74f4080398d49e1 100644 --- a/src/corelib/kernel/qmimedata.cpp +++ b/src/corelib/kernel/qmimedata.cpp @@ -354,7 +354,9 @@ void QMimeData::setUrls(const QList<QUrl> &urls) { Q_D(QMimeData); QList<QVariant> list; - for (int i = 0; i < urls.size(); ++i) + const int numUrls = urls.size(); + list.reserve(numUrls); + for (int i = 0; i < numUrls; ++i) list.append(urls.at(i)); d->setData(QLatin1String("text/uri-list"), list); diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 3ca9c890e8c765bb8400a1b3acd7443eaec7e106..e6ea27ef58915ffb3dfe414333851f1718558a4d 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -503,6 +503,7 @@ void QMetaCallEvent::placeMetaCall(QObject *object) \brief Exception-safe wrapper around QObject::blockSignals() \since 5.3 \ingroup objectmodel + \inmodule QtCore \reentrant @@ -909,14 +910,7 @@ QObject::~QObject() } if (!d->isWidget && d->isSignalConnected(0)) { - QT_TRY { - emit destroyed(this); - } QT_CATCH(...) { - // all the signal/slots connections are still in place - if we don't - // quit now, we will crash pretty soon. - qWarning("Detected an unexpected exception in ~QObject while emitting destroyed()."); - QT_RETHROW; - } + emit destroyed(this); } if (d->declarativeData) { @@ -4922,6 +4916,16 @@ QMetaObject::Connection::~Connection() static_cast<QObjectPrivate::Connection *>(d_ptr)->deref(); } +/*! \internal Returns true if the object is still connected */ +bool QMetaObject::Connection::isConnected_helper() const +{ + Q_ASSERT(d_ptr); // we're only called from operator RestrictedBool() const + QObjectPrivate::Connection *c = static_cast<QObjectPrivate::Connection *>(d_ptr); + + return c->receiver; +} + + /*! \fn QMetaObject::Connection::operator bool() const diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 5f61dd984f1cf3d8aa4bef51fe777496afeadf6f..64c5b58fd47f43ffafe1ae1825971f6df545e2e2 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -110,23 +110,23 @@ class Q_CORE_EXPORT QObject Q_DECLARE_PRIVATE(QObject) public: - Q_INVOKABLE explicit QObject(QObject *parent=0); + Q_INVOKABLE explicit QObject(QObject *parent=Q_NULLPTR); virtual ~QObject(); virtual bool event(QEvent *); virtual bool eventFilter(QObject *, QEvent *); #ifdef Q_QDOC - static QString tr(const char *sourceText, const char *comment = 0, int n = -1); - static QString trUtf8(const char *sourceText, const char *comment = 0, int n = -1); + static QString tr(const char *sourceText, const char *comment = Q_NULLPTR, int n = -1); + static QString trUtf8(const char *sourceText, const char *comment = Q_NULLPTR, int n = -1); virtual const QMetaObject *metaObject() const; static const QMetaObject staticMetaObject; #endif #ifdef QT_NO_TRANSLATION - static QString tr(const char *sourceText, const char * = 0, int = -1) + static QString tr(const char *sourceText, const char * = Q_NULLPTR, int = -1) { return QString::fromUtf8(sourceText); } #if QT_DEPRECATED_SINCE(5, 0) - QT_DEPRECATED static QString trUtf8(const char *sourceText, const char * = 0, int = -1) + QT_DEPRECATED static QString trUtf8(const char *sourceText, const char * = Q_NULLPTR, int = -1) { return QString::fromUtf8(sourceText); } #endif #endif //QT_NO_TRANSLATION @@ -228,7 +228,7 @@ public: Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value), "Return type of the slot is not compatible with the return type of the signal."); - const int *types = 0; + const int *types = Q_NULLPTR; if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection) types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types(); @@ -268,11 +268,11 @@ public: Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value), "Return type of the slot is not compatible with the return type of the signal."); - const int *types = 0; + const int *types = Q_NULLPTR; if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection) types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types(); - return connectImpl(sender, reinterpret_cast<void **>(&signal), context, 0, + return connectImpl(sender, reinterpret_cast<void **>(&signal), context, Q_NULLPTR, new QtPrivate::QStaticSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value, typename SignalType::ReturnType>(slot), @@ -338,11 +338,11 @@ public: Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value, "No Q_OBJECT in the class with the signal"); - const int *types = 0; + const int *types = Q_NULLPTR; if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection) types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types(); - return connectImpl(sender, reinterpret_cast<void **>(&signal), context, 0, + return connectImpl(sender, reinterpret_cast<void **>(&signal), context, Q_NULLPTR, new QtPrivate::QFunctorSlotObject<Func2, SlotArgumentCount, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value, typename SignalType::ReturnType>(slot), @@ -354,11 +354,11 @@ public: const QObject *receiver, const char *member); static bool disconnect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &member); - inline bool disconnect(const char *signal = 0, - const QObject *receiver = 0, const char *member = 0) const + inline bool disconnect(const char *signal = Q_NULLPTR, + const QObject *receiver = Q_NULLPTR, const char *member = Q_NULLPTR) const { return disconnect(this, signal, receiver, member); } - inline bool disconnect(const QObject *receiver, const char *member = 0) const - { return disconnect(this, 0, receiver, member); } + inline bool disconnect(const QObject *receiver, const char *member = Q_NULLPTR) const + { return disconnect(this, Q_NULLPTR, receiver, member); } static bool disconnect(const QMetaObject::Connection &); #ifdef Q_QDOC @@ -385,7 +385,7 @@ public: static inline bool disconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *receiver, void **zero) { - // This is the overload for when one wish to disconnect a signal from any slot. (slot=0) + // This is the overload for when one wish to disconnect a signal from any slot. (slot=Q_NULLPTR) // Since the function template parameter cannot be deduced from '0', we use a // dummy void ** parameter that must be equal to 0 Q_ASSERT(!zero); @@ -412,14 +412,14 @@ public: #endif // QT_NO_USERDATA Q_SIGNALS: - void destroyed(QObject * = 0); + void destroyed(QObject * = Q_NULLPTR); void objectNameChanged(const QString &objectName, QPrivateSignal); public: inline QObject *parent() const { return d_ptr->parent; } inline bool inherits(const char *classname) const - { return const_cast<QObject *>(this)->qt_metacast(classname) != 0; } + { return const_cast<QObject *>(this)->qt_metacast(classname) != Q_NULLPTR; } public Q_SLOTS: void deleteLater(); @@ -438,7 +438,7 @@ protected: virtual void disconnectNotify(const QMetaMethod &signal); protected: - QObject(QObjectPrivate &dd, QObject *parent = 0); + QObject(QObjectPrivate &dd, QObject *parent = Q_NULLPTR); protected: QScopedPointer<QObjectData> d_ptr; @@ -529,16 +529,16 @@ inline T qobject_cast(const QObject *object) template <class T> inline const char * qobject_interface_iid() -{ return 0; } +{ return Q_NULLPTR; } #ifndef Q_MOC_RUN # define Q_DECLARE_INTERFACE(IFace, IId) \ template <> inline const char *qobject_interface_iid<IFace *>() \ { return IId; } \ template <> inline IFace *qobject_cast<IFace *>(QObject *object) \ - { return reinterpret_cast<IFace *>((object ? object->qt_metacast(IId) : 0)); } \ + { return reinterpret_cast<IFace *>((object ? object->qt_metacast(IId) : Q_NULLPTR)); } \ template <> inline IFace *qobject_cast<IFace *>(const QObject *object) \ - { return reinterpret_cast<IFace *>((object ? const_cast<QObject *>(object)->qt_metacast(IId) : 0)); } + { return reinterpret_cast<IFace *>((object ? const_cast<QObject *>(object)->qt_metacast(IId) : Q_NULLPTR)); } #endif // Q_MOC_RUN #ifndef QT_NO_DEBUG_STREAM @@ -584,7 +584,7 @@ QSignalBlocker::QSignalBlocker(QSignalBlocker &&other) Q_DECL_NOTHROW m_blocked(other.m_blocked), m_inhibited(other.m_inhibited) { - other.m_o = 0; + other.m_o = Q_NULLPTR; } QSignalBlocker &QSignalBlocker::operator=(QSignalBlocker &&other) Q_DECL_NOTHROW @@ -598,7 +598,7 @@ QSignalBlocker &QSignalBlocker::operator=(QSignalBlocker &&other) Q_DECL_NOTHROW m_blocked = other.m_blocked; m_inhibited = other.m_inhibited; // disable other: - other.m_o = 0; + other.m_o = Q_NULLPTR; } return *this; } diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h index 4d9e42ba765d95dae951f99b778673fc4f57ae76..09d52584c4fb67f1e42b8e1d2bc8d1dc3dc9cd10 100644 --- a/src/corelib/kernel/qobject_impl.h +++ b/src/corelib/kernel/qobject_impl.h @@ -90,9 +90,9 @@ namespace QtPrivate { { enum { Value = QMetaTypeId2<Arg>::Defined && TypesAreDeclaredMetaType<List<Tail...>>::Value }; }; template <typename ArgList, bool Declared = TypesAreDeclaredMetaType<ArgList>::Value > struct ConnectionTypes - { static const int *types() { return 0; } }; + { static const int *types() { return Q_NULLPTR; } }; template <> struct ConnectionTypes<List<>, true> - { static const int *types() { return 0; } }; + { static const int *types() { return Q_NULLPTR; } }; template <typename... Args> struct ConnectionTypes<List<Args...>, true> { static const int *types() { static const int t[sizeof...(Args) + 1] = { (QtPrivate::QMetaTypeIdHelper<Args>::qt_metatype_id())..., 0 }; return t; } }; #endif @@ -118,10 +118,10 @@ namespace QtPrivate { inline int ref() Q_DECL_NOTHROW { return m_ref.ref(); } inline void destroyIfLastRef() Q_DECL_NOTHROW - { if (!m_ref.deref()) m_impl(Destroy, this, 0, 0, 0); } + { if (!m_ref.deref()) m_impl(Destroy, this, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR); } - inline bool compare(void **a) { bool ret; m_impl(Compare, this, 0, a, &ret); return ret; } - inline void call(QObject *r, void **a) { m_impl(Call, this, r, a, 0); } + inline bool compare(void **a) { bool ret; m_impl(Compare, this, Q_NULLPTR, a, &ret); return ret; } + inline void call(QObject *r, void **a) { m_impl(Call, this, r, a, Q_NULLPTR); } protected: ~QSlotObjectBase() {} private: diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 4d0126490690703d595f50f2242a3f4f2319cd8b..b1ed971eba77ce13e07acf17bf7a41b9d9210ef2 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -78,7 +78,11 @@ class QString; #define Q_CLASSINFO(name, value) #define Q_PLUGIN_METADATA(x) #define Q_INTERFACES(x) +#ifdef Q_COMPILER_VARIADIC_MACROS +#define Q_PROPERTY(...) +#else #define Q_PROPERTY(text) +#endif #define Q_PRIVATE_PROPERTY(d, text) #define Q_REVISION(v) #define Q_OVERRIDE(text) @@ -254,7 +258,7 @@ class QMetaClassInfo; class Q_CORE_EXPORT QGenericArgument { public: - inline QGenericArgument(const char *aName = 0, const void *aData = 0) + inline QGenericArgument(const char *aName = Q_NULLPTR, const void *aData = Q_NULLPTR) : _data(aData), _name(aName) {} inline void *data() const { return const_cast<void *>(_data); } inline const char *name() const { return _name; } @@ -267,7 +271,7 @@ private: class Q_CORE_EXPORT QGenericReturnArgument: public QGenericArgument { public: - inline QGenericReturnArgument(const char *aName = 0, void *aData = 0) + inline QGenericReturnArgument(const char *aName = Q_NULLPTR, void *aData = Q_NULLPTR) : QGenericArgument(aName, aData) {} }; @@ -347,7 +351,7 @@ struct Q_CORE_EXPORT QMetaObject // internal index-based connect static Connection connect(const QObject *sender, int signal_index, const QObject *receiver, int method_index, - int type = 0, int *types = 0); + int type = 0, int *types = Q_NULLPTR); // internal index-based disconnect static bool disconnect(const QObject *sender, int signal_index, const QObject *receiver, int method_index); @@ -364,7 +368,7 @@ struct Q_CORE_EXPORT QMetaObject static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, - QGenericArgument val0 = QGenericArgument(0), + QGenericArgument val0 = QGenericArgument(Q_NULLPTR), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), @@ -377,7 +381,7 @@ struct Q_CORE_EXPORT QMetaObject static inline bool invokeMethod(QObject *obj, const char *member, QGenericReturnArgument ret, - QGenericArgument val0 = QGenericArgument(0), + QGenericArgument val0 = QGenericArgument(Q_NULLPTR), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), @@ -394,7 +398,7 @@ struct Q_CORE_EXPORT QMetaObject static inline bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, - QGenericArgument val0 = QGenericArgument(0), + QGenericArgument val0 = QGenericArgument(Q_NULLPTR), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), @@ -410,7 +414,7 @@ struct Q_CORE_EXPORT QMetaObject } static inline bool invokeMethod(QObject *obj, const char *member, - QGenericArgument val0 = QGenericArgument(0), + QGenericArgument val0 = QGenericArgument(Q_NULLPTR), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), @@ -425,7 +429,7 @@ struct Q_CORE_EXPORT QMetaObject val1, val2, val3, val4, val5, val6, val7, val8, val9); } - QObject *newInstance(QGenericArgument val0 = QGenericArgument(0), + QObject *newInstance(QGenericArgument val0 = QGenericArgument(Q_NULLPTR), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), @@ -472,6 +476,7 @@ class Q_CORE_EXPORT QMetaObject::Connection { friend class QObject; friend class QObjectPrivate; friend struct QMetaObject; + bool isConnected_helper() const; public: ~Connection(); Connection(); @@ -481,11 +486,11 @@ public: operator bool() const; #else typedef void *Connection::*RestrictedBool; - operator RestrictedBool() const { return d_ptr ? &Connection::d_ptr : 0; } + operator RestrictedBool() const { return d_ptr && isConnected_helper() ? &Connection::d_ptr : Q_NULLPTR; } #endif #ifdef Q_COMPILER_RVALUE_REFS - inline Connection(Connection &&o) : d_ptr(o.d_ptr) { o.d_ptr = 0; } + inline Connection(Connection &&o) : d_ptr(o.d_ptr) { o.d_ptr = Q_NULLPTR; } inline Connection &operator=(Connection &&other) { qSwap(d_ptr, other.d_ptr); return *this; } #endif diff --git a/src/corelib/kernel/qpointer.cpp b/src/corelib/kernel/qpointer.cpp index 2c872716d1984e1f2d41ec7a41e592748299191f..f237498f4e5039c76d71ed0a0ea1ba1a26f32135 100644 --- a/src/corelib/kernel/qpointer.cpp +++ b/src/corelib/kernel/qpointer.cpp @@ -127,6 +127,14 @@ pointed to. */ +/*! + \fn void QPointer::swap(QPointer &other) + \since 5.6 + + Swaps the contents of this QPointer with the contents of \a other. + This operation is very fast and never fails. +*/ + /*! \fn QPointer<T> & QPointer::operator=(T* p) diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h index 07649ce0b298e041128976ba7768cafb779af37a..72388f2bb7178b1397bb8290e2e0022c53e82841 100644 --- a/src/corelib/kernel/qpointer.h +++ b/src/corelib/kernel/qpointer.h @@ -64,7 +64,9 @@ public: inline QPointer() { } inline QPointer(T *p) : wp(p, true) { } // compiler-generated copy/move ctor/assignment operators are fine! - inline ~QPointer() { } + // compiler-generated dtor is fine! + + inline void swap(QPointer &other) { wp.swap(other.wp); } inline QPointer<T> &operator=(T* p) { wp.assign(static_cast<QObjectType*>(p)); return *this; } diff --git a/src/corelib/kernel/qsharedmemory.h b/src/corelib/kernel/qsharedmemory.h index c192910dc7bf82303b288275d73e88eb1e0a1f3a..67558e3348812722d72033bcb8446218da20aaf6 100644 --- a/src/corelib/kernel/qsharedmemory.h +++ b/src/corelib/kernel/qsharedmemory.h @@ -68,8 +68,8 @@ public: UnknownError }; - QSharedMemory(QObject *parent = 0); - QSharedMemory(const QString &key, QObject *parent = 0); + QSharedMemory(QObject *parent = Q_NULLPTR); + QSharedMemory(const QString &key, QObject *parent = Q_NULLPTR); ~QSharedMemory(); void setKey(const QString &key); diff --git a/src/corelib/kernel/qsignalmapper.h b/src/corelib/kernel/qsignalmapper.h index df2a0a52eaec8cbaa3e6faaf0b9383c529865208..7aaef6affce25b16e75a46314efe75af3e40cb77 100644 --- a/src/corelib/kernel/qsignalmapper.h +++ b/src/corelib/kernel/qsignalmapper.h @@ -45,7 +45,7 @@ class Q_CORE_EXPORT QSignalMapper : public QObject Q_OBJECT Q_DECLARE_PRIVATE(QSignalMapper) public: - explicit QSignalMapper(QObject *parent = 0); + explicit QSignalMapper(QObject *parent = Q_NULLPTR); ~QSignalMapper(); void setMapping(QObject *sender, int id); diff --git a/src/corelib/kernel/qsocketnotifier.h b/src/corelib/kernel/qsocketnotifier.h index 4bafbfa69fb37496767ad69ca6ce9a6c612196e0..8a7af6ebbc835d5d91dcc4ae400969358690fdee 100644 --- a/src/corelib/kernel/qsocketnotifier.h +++ b/src/corelib/kernel/qsocketnotifier.h @@ -47,7 +47,7 @@ class Q_CORE_EXPORT QSocketNotifier : public QObject public: enum Type { Read, Write, Exception }; - QSocketNotifier(qintptr socket, Type, QObject *parent = 0); + QSocketNotifier(qintptr socket, Type, QObject *parent = Q_NULLPTR); ~QSocketNotifier(); qintptr socket() const; diff --git a/src/corelib/kernel/qsystemsemaphore_win.cpp b/src/corelib/kernel/qsystemsemaphore_win.cpp index ca55025c2a6c8c6872c5327952b0f8f533c5c30f..89b8a87f2afba278080afa8ccf0addd4c483ead7 100644 --- a/src/corelib/kernel/qsystemsemaphore_win.cpp +++ b/src/corelib/kernel/qsystemsemaphore_win.cpp @@ -115,7 +115,7 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count) return false; } } else { -#if defined(Q_OS_WINRT) +#if !defined(Q_OS_WINCE) if (WAIT_OBJECT_0 != WaitForSingleObjectEx(semaphore, INFINITE, FALSE)) { #else if (WAIT_OBJECT_0 != WaitForSingleObject(semaphore, INFINITE)) { diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h index 163ef75291a3659f40888beb31cae2fb5cee21e6..889f5d7f708ad0424b9a72568c3e84d98406e253 100644 --- a/src/corelib/kernel/qtimer.h +++ b/src/corelib/kernel/qtimer.h @@ -53,7 +53,7 @@ class Q_CORE_EXPORT QTimer : public QObject Q_PROPERTY(Qt::TimerType timerType READ timerType WRITE setTimerType) Q_PROPERTY(bool active READ isActive) public: - explicit QTimer(QObject *parent = 0); + explicit QTimer(QObject *parent = Q_NULLPTR); ~QTimer(); inline bool isActive() const { return id >= 0; } @@ -102,12 +102,16 @@ public: } // singleShot to a functor or function pointer (without context) template <typename Func1> - static inline void singleShot(int msec, Func1 slot) + static inline typename QtPrivate::QEnableIf<!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction && + !QtPrivate::is_same<const char*, Func1>::value, void>::Type + singleShot(int msec, Func1 slot) { singleShot(msec, msec >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer, Q_NULLPTR, slot); } template <typename Func1> - static inline void singleShot(int msec, Qt::TimerType timerType, Func1 slot) + static inline typename QtPrivate::QEnableIf<!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction && + !QtPrivate::is_same<const char*, Func1>::value, void>::Type + singleShot(int msec, Qt::TimerType timerType, Func1 slot) { singleShot(msec, timerType, Q_NULLPTR, slot); } diff --git a/src/corelib/kernel/qtranslator.h b/src/corelib/kernel/qtranslator.h index 1552bbde358e67b15411d838cc089910d6a5f633..78f714c5c6bb5fae9445ecd8b2b7d99737fa6f4b 100644 --- a/src/corelib/kernel/qtranslator.h +++ b/src/corelib/kernel/qtranslator.h @@ -49,11 +49,11 @@ class Q_CORE_EXPORT QTranslator : public QObject { Q_OBJECT public: - explicit QTranslator(QObject *parent = 0); + explicit QTranslator(QObject *parent = Q_NULLPTR); ~QTranslator(); virtual QString translate(const char *context, const char *sourceText, - const char *disambiguation = 0, int n = -1) const; + const char *disambiguation = Q_NULLPTR, int n = -1) const; virtual bool isEmpty() const; diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index f7a4abbf6891e8d6e450d92830db48bfd902d168..35f178e6a9d26a7bb1f6709bbfd65851670fc115 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -3832,7 +3832,11 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p) /*! \internal */ +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QSequentialIterable::QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl impl) +#else +QSequentialIterable::QSequentialIterable(const QtMetaTypePrivate::QSequentialIterableImpl &impl) +#endif : m_impl(impl) { } @@ -4140,7 +4144,11 @@ QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operato /*! \internal */ +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QAssociativeIterable::QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl impl) +#else +QAssociativeIterable::QAssociativeIterable(const QtMetaTypePrivate::QAssociativeIterableImpl &impl) +#endif : m_impl(impl) { } diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index 58dfc3aab0752a2783adf019a891b78aa45d8cda..27b19982de2fe36cee4d4be85b91c55adf72f1e1 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -278,14 +278,14 @@ class Q_CORE_EXPORT QVariant void detach(); inline bool isDetached() const; - int toInt(bool *ok = 0) const; - uint toUInt(bool *ok = 0) const; - qlonglong toLongLong(bool *ok = 0) const; - qulonglong toULongLong(bool *ok = 0) const; + int toInt(bool *ok = Q_NULLPTR) const; + uint toUInt(bool *ok = Q_NULLPTR) const; + qlonglong toLongLong(bool *ok = Q_NULLPTR) const; + qulonglong toULongLong(bool *ok = Q_NULLPTR) const; bool toBool() const; - double toDouble(bool *ok = 0) const; - float toFloat(bool *ok = 0) const; - qreal toReal(bool *ok = 0) const; + double toDouble(bool *ok = Q_NULLPTR) const; + float toFloat(bool *ok = Q_NULLPTR) const; + qreal toReal(bool *ok = Q_NULLPTR) const; QByteArray toByteArray() const; QBitArray toBitArray() const; QString toString() const; @@ -364,7 +364,7 @@ class Q_CORE_EXPORT QVariant struct Private { inline Private() Q_DECL_NOTHROW : type(Invalid), is_shared(false), is_null(true) - { data.ptr = 0; } + { data.ptr = Q_NULLPTR; } // Internal constructor for initialized variants. explicit inline Private(uint variantType) Q_DECL_NOTHROW @@ -607,7 +607,11 @@ public: friend struct const_iterator; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) explicit QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl impl); +#else + explicit QSequentialIterable(const QtMetaTypePrivate::QSequentialIterableImpl &impl); +#endif const_iterator begin() const; const_iterator end() const; @@ -660,7 +664,11 @@ public: friend struct const_iterator; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) explicit QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl impl); +#else + explicit QAssociativeIterable(const QtMetaTypePrivate::QAssociativeIterableImpl &impl); +#endif const_iterator begin() const; const_iterator end() const; diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index bec7a79e8fc7b7011cc02f619840c1ae4c75d023..133933f9af7d136efb181b0729b99e4426212f70 100644 --- a/src/corelib/mimetypes/qmimedatabase.cpp +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -434,6 +434,7 @@ QList<QMimeType> QMimeDatabase::mimeTypesForFileName(const QString &fileName) co QStringList matches = d->mimeTypeForFileName(fileName); QList<QMimeType> mimes; matches.sort(); // Make it deterministic + mimes.reserve(matches.count()); foreach (const QString &mime, matches) mimes.append(d->mimeTypeForName(mime)); return mimes; diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index 7342a5cd77a067976ed32de75d85700a26b39580..dd8f385c8251a228fec7d1e8448f9ac33bd98a62 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -541,6 +541,7 @@ QList<QMimeType> QMimeBinaryProvider::allMimeTypes() { QList<QMimeType> result; loadMimeTypeList(); + result.reserve(m_mimetypeNames.count()); for (QSet<QString>::const_iterator it = m_mimetypeNames.constBegin(); it != m_mimetypeNames.constEnd(); ++it) diff --git a/src/corelib/mimetypes/qmimetype.h b/src/corelib/mimetypes/qmimetype.h index 5693b703eefb3495bbc2542d9c2cd1e9dc698188..3c153da21d5bac30945814574209a56f44311298 100644 --- a/src/corelib/mimetypes/qmimetype.h +++ b/src/corelib/mimetypes/qmimetype.h @@ -57,13 +57,9 @@ public: QMimeType(const QMimeType &other); QMimeType &operator=(const QMimeType &other); #ifdef Q_COMPILER_RVALUE_REFS - QMimeType &operator=(QMimeType &&other) - { - qSwap(d, other.d); - return *this; - } + QMimeType &operator=(QMimeType &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif - void swap(QMimeType &other) + void swap(QMimeType &other) Q_DECL_NOTHROW { qSwap(d, other.d); } diff --git a/src/corelib/plugin/qlibrary.h b/src/corelib/plugin/qlibrary.h index 16bdf792066f890369de0e859ea2a699ee783fd0..77ad107c6f0f608d744f4e24ed0dd001d72fa936 100644 --- a/src/corelib/plugin/qlibrary.h +++ b/src/corelib/plugin/qlibrary.h @@ -59,10 +59,10 @@ public: Q_FLAG(LoadHint) Q_FLAG(LoadHints) - explicit QLibrary(QObject *parent = 0); - explicit QLibrary(const QString& fileName, QObject *parent = 0); - explicit QLibrary(const QString& fileName, int verNum, QObject *parent = 0); - explicit QLibrary(const QString& fileName, const QString &version, QObject *parent = 0); + explicit QLibrary(QObject *parent = Q_NULLPTR); + explicit QLibrary(const QString& fileName, QObject *parent = Q_NULLPTR); + explicit QLibrary(const QString& fileName, int verNum, QObject *parent = Q_NULLPTR); + explicit QLibrary(const QString& fileName, const QString &version, QObject *parent = Q_NULLPTR); ~QLibrary(); QFunctionPointer resolve(const char *symbol); diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index 2756414d70dc89e91dba62b6bcd84cf4f70ba2e3..292ad30525898ba1fd4a2f3dfed7530bf1c4949e 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -435,7 +435,9 @@ QObjectList QPluginLoader::staticInstances() QObjectList instances; const StaticPluginList *plugins = staticPluginList(); if (plugins) { - for (int i = 0; i < plugins->size(); ++i) + const int numPlugins = plugins->size(); + instances.reserve(numPlugins); + for (int i = 0; i < numPlugins; ++i) instances += plugins->at(i).instance(); } return instances; diff --git a/src/corelib/plugin/qpluginloader.h b/src/corelib/plugin/qpluginloader.h index b947e6ed9e6fecd0e6c6b1805a703d01d85f1fb6..0ab25bbb078d814247113aefd86a737694203358 100644 --- a/src/corelib/plugin/qpluginloader.h +++ b/src/corelib/plugin/qpluginloader.h @@ -50,8 +50,8 @@ class Q_CORE_EXPORT QPluginLoader : public QObject Q_PROPERTY(QString fileName READ fileName WRITE setFileName) Q_PROPERTY(QLibrary::LoadHints loadHints READ loadHints WRITE setLoadHints) public: - explicit QPluginLoader(QObject *parent = 0); - explicit QPluginLoader(const QString &fileName, QObject *parent = 0); + explicit QPluginLoader(QObject *parent = Q_NULLPTR); + explicit QPluginLoader(const QString &fileName, QObject *parent = Q_NULLPTR); ~QPluginLoader(); QObject *instance(); diff --git a/src/corelib/statemachine/qabstractstate.cpp b/src/corelib/statemachine/qabstractstate.cpp index 543edb2f98d85b66b9dec656cca6e44390e1d909..2c412849e80c5f7c5d863c68d02dfa57e670493e 100644 --- a/src/corelib/statemachine/qabstractstate.cpp +++ b/src/corelib/statemachine/qabstractstate.cpp @@ -85,16 +85,6 @@ QAbstractStatePrivate::QAbstractStatePrivate(StateType type) { } -QAbstractStatePrivate *QAbstractStatePrivate::get(QAbstractState *q) -{ - return q->d_func(); -} - -const QAbstractStatePrivate *QAbstractStatePrivate::get(const QAbstractState *q) -{ - return q->d_func(); -} - QStateMachine *QAbstractStatePrivate::machine() const { QObject *par = parent; @@ -227,7 +217,7 @@ bool QAbstractState::active() const \fn QAbstractState::activeChanged(bool active) \since 5.4 - This signal is emitted when the active property is changed. + This signal is emitted when the active property is changed with \a active as argument. \sa QAbstractState::active, entered(), exited() */ diff --git a/src/corelib/statemachine/qabstractstate.h b/src/corelib/statemachine/qabstractstate.h index 592c841c18e83813324f3346d5ec41a8b2b04fdf..3aa4b2fabb3ea64f58ce2d97e4c3193c2143c63d 100644 --- a/src/corelib/statemachine/qabstractstate.h +++ b/src/corelib/statemachine/qabstractstate.h @@ -63,7 +63,7 @@ Q_SIGNALS: void activeChanged(bool active); protected: - QAbstractState(QState *parent = 0); + QAbstractState(QState *parent = Q_NULLPTR); virtual void onEntry(QEvent *event) = 0; virtual void onExit(QEvent *event) = 0; diff --git a/src/corelib/statemachine/qabstractstate_p.h b/src/corelib/statemachine/qabstractstate_p.h index 087e355b7112a9a3fcfc9e0b04a6a1f71acefb48..1eb3cbd4204278f2a5a44f2b819ebfa7696af7d5 100644 --- a/src/corelib/statemachine/qabstractstate_p.h +++ b/src/corelib/statemachine/qabstractstate_p.h @@ -46,12 +46,13 @@ // #include <private/qobject_p.h> +#include <QtCore/qabstractstate.h> QT_BEGIN_NAMESPACE class QStateMachine; -class QAbstractState; +class QState; class QAbstractStatePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QAbstractState) @@ -66,8 +67,10 @@ public: QAbstractStatePrivate(StateType type); - static QAbstractStatePrivate *get(QAbstractState *q); - static const QAbstractStatePrivate *get(const QAbstractState *q); + static QAbstractStatePrivate *get(QAbstractState *q) + { return q->d_func(); } + static const QAbstractStatePrivate *get(const QAbstractState *q) + { return q->d_func(); } QStateMachine *machine() const; diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp index 81b38ea4c44c19b634338627ee9307a74602283d..5a7a95883b882a61b6c97cdda7a325d4749c88c8 100644 --- a/src/corelib/statemachine/qabstracttransition.cpp +++ b/src/corelib/statemachine/qabstracttransition.cpp @@ -37,6 +37,7 @@ #include "qabstracttransition_p.h" #include "qabstractstate.h" +#include "qhistorystate.h" #include "qstate.h" #include "qstatemachine.h" @@ -133,17 +134,14 @@ QAbstractTransitionPrivate::QAbstractTransitionPrivate() { } -QAbstractTransitionPrivate *QAbstractTransitionPrivate::get(QAbstractTransition *q) -{ - return q->d_func(); -} - QStateMachine *QAbstractTransitionPrivate::machine() const { - QState *source = sourceState(); - if (!source) - return 0; - return source->machine(); + if (QState *source = sourceState()) + return source->machine(); + Q_Q(const QAbstractTransition); + if (QHistoryState *parent = qobject_cast<QHistoryState *>(q->parent())) + return parent->machine(); + return 0; } bool QAbstractTransitionPrivate::callEventTest(QEvent *e) @@ -254,7 +252,7 @@ QList<QAbstractState*> QAbstractTransition::targetStates() const void QAbstractTransition::setTargetStates(const QList<QAbstractState*> &targets) { Q_D(QAbstractTransition); - QList<QPointer<QAbstractState> > copy(d->targetStates); + QVector<QPointer<QAbstractState> > copy(d->targetStates); bool sameList = true; for (int i = 0; i < targets.size(); ++i) { QAbstractState *target = targets.at(i); diff --git a/src/corelib/statemachine/qabstracttransition.h b/src/corelib/statemachine/qabstracttransition.h index bf32b3e825fc783628101d8cf34422a94d9a4d00..4398c41ca2389bb07fe4079adf89d8e4ece4df40 100644 --- a/src/corelib/statemachine/qabstracttransition.h +++ b/src/corelib/statemachine/qabstracttransition.h @@ -59,7 +59,7 @@ class Q_CORE_EXPORT QAbstractTransition : public QObject Q_PROPERTY(QState* sourceState READ sourceState) Q_PROPERTY(QAbstractState* targetState READ targetState WRITE setTargetState NOTIFY targetStateChanged) Q_PROPERTY(QList<QAbstractState*> targetStates READ targetStates WRITE setTargetStates NOTIFY targetStatesChanged) - Q_PROPERTY(TransitionType transitionType READ transitionType WRITE setTransitionType) + Q_PROPERTY(TransitionType transitionType READ transitionType WRITE setTransitionType REVISION 1) public: enum TransitionType { ExternalTransition, @@ -67,7 +67,7 @@ public: }; Q_ENUM(TransitionType) - QAbstractTransition(QState *sourceState = 0); + QAbstractTransition(QState *sourceState = Q_NULLPTR); virtual ~QAbstractTransition(); QState *sourceState() const; diff --git a/src/corelib/statemachine/qabstracttransition_p.h b/src/corelib/statemachine/qabstracttransition_p.h index 4b0644acd99ca7516fad2e9bb32224ec38a9f315..ed726fa6ef1d3de725eed1c31986ceafb484b37a 100644 --- a/src/corelib/statemachine/qabstracttransition_p.h +++ b/src/corelib/statemachine/qabstracttransition_p.h @@ -48,6 +48,7 @@ #include <private/qobject_p.h> #include <QtCore/qlist.h> +#include <QtCore/qvector.h> #include <QtCore/qsharedpointer.h> QT_BEGIN_NAMESPACE @@ -64,7 +65,8 @@ class Q_CORE_EXPORT QAbstractTransitionPrivate public: QAbstractTransitionPrivate(); - static QAbstractTransitionPrivate *get(QAbstractTransition *q); + static QAbstractTransitionPrivate *get(QAbstractTransition *q) + { return q->d_func(); } bool callEventTest(QEvent *e); virtual void callOnTransition(QEvent *e); @@ -72,7 +74,7 @@ public: QStateMachine *machine() const; void emitTriggered(); - QList<QPointer<QAbstractState> > targetStates; + QVector<QPointer<QAbstractState> > targetStates; QAbstractTransition::TransitionType transitionType; #ifndef QT_NO_ANIMATION diff --git a/src/corelib/statemachine/qeventtransition.cpp b/src/corelib/statemachine/qeventtransition.cpp index c10127fa6896b7aa4c1e933e057befb25e632184..de6858ae422949a22bc97c1757e36f754e79cc34 100644 --- a/src/corelib/statemachine/qeventtransition.cpp +++ b/src/corelib/statemachine/qeventtransition.cpp @@ -106,11 +106,6 @@ QEventTransitionPrivate::~QEventTransitionPrivate() { } -QEventTransitionPrivate *QEventTransitionPrivate::get(QEventTransition *q) -{ - return q->d_func(); -} - void QEventTransitionPrivate::unregister() { Q_Q(QEventTransition); diff --git a/src/corelib/statemachine/qeventtransition.h b/src/corelib/statemachine/qeventtransition.h index 6909e855b1711661d6fc77f9ca630a7e7b030a01..5ec3b7bb265a5d5761a7334b6e4fa93578062127 100644 --- a/src/corelib/statemachine/qeventtransition.h +++ b/src/corelib/statemachine/qeventtransition.h @@ -49,8 +49,8 @@ class Q_CORE_EXPORT QEventTransition : public QAbstractTransition Q_PROPERTY(QObject* eventSource READ eventSource WRITE setEventSource) Q_PROPERTY(QEvent::Type eventType READ eventType WRITE setEventType) public: - QEventTransition(QState *sourceState = 0); - QEventTransition(QObject *object, QEvent::Type type, QState *sourceState = 0); + QEventTransition(QState *sourceState = Q_NULLPTR); + QEventTransition(QObject *object, QEvent::Type type, QState *sourceState = Q_NULLPTR); ~QEventTransition(); QObject *eventSource() const; diff --git a/src/corelib/statemachine/qeventtransition_p.h b/src/corelib/statemachine/qeventtransition_p.h index 3e430d86a98b72dc4fe9301b36906f72cec7f426..3f6c9475ea25e3cef2126f79c67b86c692e17606 100644 --- a/src/corelib/statemachine/qeventtransition_p.h +++ b/src/corelib/statemachine/qeventtransition_p.h @@ -57,7 +57,8 @@ public: QEventTransitionPrivate(); ~QEventTransitionPrivate(); - static QEventTransitionPrivate *get(QEventTransition *q); + static QEventTransitionPrivate *get(QEventTransition *q) + { return q->d_func(); } void unregister(); void maybeRegister(); diff --git a/src/corelib/statemachine/qfinalstate.h b/src/corelib/statemachine/qfinalstate.h index 51c97b1545ff6ff7058f1e11361c670ad03e90df..2c76e7b6e68151cea0730f803bbc17b088c0e700 100644 --- a/src/corelib/statemachine/qfinalstate.h +++ b/src/corelib/statemachine/qfinalstate.h @@ -46,7 +46,7 @@ class Q_CORE_EXPORT QFinalState : public QAbstractState { Q_OBJECT public: - QFinalState(QState *parent = 0); + QFinalState(QState *parent = Q_NULLPTR); ~QFinalState(); protected: diff --git a/src/corelib/statemachine/qhistorystate.cpp b/src/corelib/statemachine/qhistorystate.cpp index e58b0c16fcbe5ce4aa277e5cadde9c57fc66b7cb..a0ebb9d239af44c218ce00d10bbbf879ad61db2a 100644 --- a/src/corelib/statemachine/qhistorystate.cpp +++ b/src/corelib/statemachine/qhistorystate.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE A history state is a pseudo-state that represents the child state that the parent state was in the last time the parent state was exited. A transition - with a history state as its target is in fact a transition to one of the + with a history state as its target is in fact a transition to one or more other child states of the parent state. QHistoryState is part of \l{The State Machine Framework}. @@ -79,10 +79,21 @@ QT_BEGIN_NAMESPACE s1->addTransition(button, SIGNAL(clicked()), s1h); \endcode + If more than one default state has to be entered, or if the transition to the default state(s) + has to be acted upon, the defaultTransition should be set instead. Note that the eventTest() + method of that transition will never be called: the selection and execution of the transition is + done automatically when entering the history state. + By default a history state is shallow, meaning that it won't remember nested states. This can be configured through the historyType property. */ +/*! + \property QHistoryState::defaultTransition + + \brief the default transition of this history state +*/ + /*! \property QHistoryState::defaultState @@ -113,14 +124,17 @@ QT_BEGIN_NAMESPACE */ QHistoryStatePrivate::QHistoryStatePrivate() - : QAbstractStatePrivate(HistoryState), - defaultState(0), historyType(QHistoryState::ShallowHistory) + : QAbstractStatePrivate(HistoryState) + , defaultTransition(0) + , historyType(QHistoryState::ShallowHistory) { } -QHistoryStatePrivate *QHistoryStatePrivate::get(QHistoryState *q) +DefaultStateTransition::DefaultStateTransition(QHistoryState *source, QAbstractState *target) + : QAbstractTransition() { - return q->d_func(); + setParent(source); + setTargetState(target); } /*! @@ -148,6 +162,33 @@ QHistoryState::~QHistoryState() { } +/*! + Returns this history state's default transition. The default transition is + taken when the history state has never been entered before. The target states + of the default transition therefore make up the default state. +*/ +QAbstractTransition *QHistoryState::defaultTransition() const +{ + Q_D(const QHistoryState); + return d->defaultTransition; +} + +/*! + Sets this history state's default transition to be the given \a transition. + This will set the source state of the \a transition to the history state. + + Note that the eventTest method of the \a transition will never be called. +*/ +void QHistoryState::setDefaultTransition(QAbstractTransition *transition) +{ + Q_D(QHistoryState); + if (d->defaultTransition != transition) { + d->defaultTransition = transition; + transition->setParent(this); + emit defaultTransitionChanged(QHistoryState::QPrivateSignal()); + } +} + /*! Returns this history state's default state. The default state indicates the state to transition to if the parent state has never been entered before. @@ -155,7 +196,7 @@ QHistoryState::~QHistoryState() QAbstractState *QHistoryState::defaultState() const { Q_D(const QHistoryState); - return d->defaultState; + return d->defaultTransition ? d->defaultTransition->targetState() : Q_NULLPTR; } /*! @@ -173,8 +214,15 @@ void QHistoryState::setDefaultState(QAbstractState *state) "to this history state's group (%p)", state, parentState()); return; } - if (d->defaultState != state) { - d->defaultState = state; + if (!d->defaultTransition + || d->defaultTransition->targetStates().size() != 1 + || d->defaultTransition->targetStates().first() != state) { + if (!d->defaultTransition || !qobject_cast<DefaultStateTransition*>(d->defaultTransition)) { + d->defaultTransition = new DefaultStateTransition(this, state); + emit defaultTransitionChanged(QHistoryState::QPrivateSignal()); + } else { + d->defaultTransition->setTargetState(state); + } emit defaultStateChanged(QHistoryState::QPrivateSignal()); } } diff --git a/src/corelib/statemachine/qhistorystate.h b/src/corelib/statemachine/qhistorystate.h index 549be15ab0f652e3b41441ef4778580e0bb8ab99..2f2081bf9cd2e15218d52067e47ed90082e26e88 100644 --- a/src/corelib/statemachine/qhistorystate.h +++ b/src/corelib/statemachine/qhistorystate.h @@ -41,11 +41,13 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_STATEMACHINE +class QAbstractTransition; class QHistoryStatePrivate; class Q_CORE_EXPORT QHistoryState : public QAbstractState { Q_OBJECT Q_PROPERTY(QAbstractState* defaultState READ defaultState WRITE setDefaultState NOTIFY defaultStateChanged) + Q_PROPERTY(QAbstractTransition* defaultTransition READ defaultTransition WRITE setDefaultTransition NOTIFY defaultTransitionChanged) Q_PROPERTY(HistoryType historyType READ historyType WRITE setHistoryType NOTIFY historyTypeChanged) public: enum HistoryType { @@ -54,10 +56,13 @@ public: }; Q_ENUM(HistoryType) - QHistoryState(QState *parent = 0); - QHistoryState(HistoryType type, QState *parent = 0); + QHistoryState(QState *parent = Q_NULLPTR); + QHistoryState(HistoryType type, QState *parent = Q_NULLPTR); ~QHistoryState(); + QAbstractTransition *defaultTransition() const; + void setDefaultTransition(QAbstractTransition *transition); + QAbstractState *defaultState() const; void setDefaultState(QAbstractState *state); @@ -65,6 +70,7 @@ public: void setHistoryType(HistoryType type); Q_SIGNALS: + void defaultTransitionChanged(QPrivateSignal); void defaultStateChanged(QPrivateSignal); void historyTypeChanged(QPrivateSignal); diff --git a/src/corelib/statemachine/qhistorystate_p.h b/src/corelib/statemachine/qhistorystate_p.h index b5c353fdff160a298c1175f45d5d3d817ec642ba..b0865f7f4622a9cd52a640e86b0e03fde722cda1 100644 --- a/src/corelib/statemachine/qhistorystate_p.h +++ b/src/corelib/statemachine/qhistorystate_p.h @@ -47,11 +47,12 @@ #include "private/qabstractstate_p.h" +#include <QtCore/qabstracttransition.h> +#include <QtCore/qhistorystate.h> #include <QtCore/qlist.h> QT_BEGIN_NAMESPACE -class QHistoryState; class QHistoryStatePrivate : public QAbstractStatePrivate { Q_DECLARE_PUBLIC(QHistoryState) @@ -59,13 +60,31 @@ class QHistoryStatePrivate : public QAbstractStatePrivate public: QHistoryStatePrivate(); - static QHistoryStatePrivate *get(QHistoryState *q); + static QHistoryStatePrivate *get(QHistoryState *q) + { return q->d_func(); } - QAbstractState *defaultState; + QAbstractTransition *defaultTransition; QHistoryState::HistoryType historyType; QList<QAbstractState*> configuration; }; +class DefaultStateTransition: public QAbstractTransition +{ + Q_OBJECT + +public: + DefaultStateTransition(QHistoryState *source, QAbstractState *target); + +protected: + // It doesn't matter whether this transition matches any event or not. It is always associated + // with a QHistoryState, and as soon as the state-machine detects that it enters a history + // state, it will handle this transition as a special case. The history state itself is never + // entered either: either the stored configuration will be used, or the target(s) of this + // transition are used. + virtual bool eventTest(QEvent *event) { Q_UNUSED(event); return false; } + virtual void onTransition(QEvent *event) { Q_UNUSED(event); } +}; + QT_END_NAMESPACE #endif diff --git a/src/corelib/statemachine/qsignaltransition.cpp b/src/corelib/statemachine/qsignaltransition.cpp index 41005fca418c0fd50ddd75e6d95ac1530c932467..7ec72df77c4e9ff4d149fa3485dddd2e1353e1f6 100644 --- a/src/corelib/statemachine/qsignaltransition.cpp +++ b/src/corelib/statemachine/qsignaltransition.cpp @@ -108,11 +108,6 @@ QSignalTransitionPrivate::QSignalTransitionPrivate() signalIndex = -1; } -QSignalTransitionPrivate *QSignalTransitionPrivate::get(QSignalTransition *q) -{ - return q->d_func(); -} - void QSignalTransitionPrivate::unregister() { Q_Q(QSignalTransition); diff --git a/src/corelib/statemachine/qsignaltransition.h b/src/corelib/statemachine/qsignaltransition.h index bc56f4e9b798aabc69e7c3df51ae6e3c0eb7a1e9..c388323ec4ba298059e15f46c41fcf35051c8afe 100644 --- a/src/corelib/statemachine/qsignaltransition.h +++ b/src/corelib/statemachine/qsignaltransition.h @@ -49,9 +49,9 @@ class Q_CORE_EXPORT QSignalTransition : public QAbstractTransition Q_PROPERTY(QByteArray signal READ signal WRITE setSignal NOTIFY signalChanged) public: - QSignalTransition(QState *sourceState = 0); + QSignalTransition(QState *sourceState = Q_NULLPTR); QSignalTransition(const QObject *sender, const char *signal, - QState *sourceState = 0); + QState *sourceState = Q_NULLPTR); ~QSignalTransition(); QObject *senderObject() const; diff --git a/src/corelib/statemachine/qsignaltransition_p.h b/src/corelib/statemachine/qsignaltransition_p.h index bed0abd9ff8fe381427fae650d50df1dd87a3c22..0bf4b1540bda49636070275ebbf5e7132190b794 100644 --- a/src/corelib/statemachine/qsignaltransition_p.h +++ b/src/corelib/statemachine/qsignaltransition_p.h @@ -56,7 +56,8 @@ class QSignalTransitionPrivate : public QAbstractTransitionPrivate public: QSignalTransitionPrivate(); - static QSignalTransitionPrivate *get(QSignalTransition *q); + static QSignalTransitionPrivate *get(QSignalTransition *q) + { return q->d_func(); } void unregister(); void maybeRegister(); diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp index 6e9fb63554e54c50b6d5c0953a59716e8703fc88..3b84230cb29531a6059cbdded8016c0cb50f149d 100644 --- a/src/corelib/statemachine/qstate.cpp +++ b/src/corelib/statemachine/qstate.cpp @@ -320,7 +320,7 @@ void QState::addTransition(QAbstractTransition *transition) } transition->setParent(this); - const QList<QPointer<QAbstractState> > &targets = QAbstractTransitionPrivate::get(transition)->targetStates; + const QVector<QPointer<QAbstractState> > &targets = QAbstractTransitionPrivate::get(transition)->targetStates; for (int i = 0; i < targets.size(); ++i) { QAbstractState *t = targets.at(i).data(); if (!t) { @@ -518,6 +518,14 @@ QState::ChildMode QState::childMode() const void QState::setChildMode(ChildMode mode) { Q_D(QState); + + if (mode == QState::ParallelStates && d->initialState) { + qWarning("QState::setChildMode: setting the child-mode of state %p to " + "parallel removes the initial state", this); + d->initialState = Q_NULLPTR; + emit initialStateChanged(QState::QPrivateSignal()); + } + if (d->childMode != mode) { d->childMode = mode; emit childModeChanged(QState::QPrivateSignal()); diff --git a/src/corelib/statemachine/qstate.h b/src/corelib/statemachine/qstate.h index a74c7820271d8abe38bdf1b8fe3845af8a259d3c..0300a9ef2d315c1d9273ac83cd3621ab03277b7e 100644 --- a/src/corelib/statemachine/qstate.h +++ b/src/corelib/statemachine/qstate.h @@ -66,8 +66,8 @@ public: }; Q_ENUM(RestorePolicy) - QState(QState *parent = 0); - QState(ChildMode childMode, QState *parent = 0); + QState(QState *parent = Q_NULLPTR); + QState(ChildMode childMode, QState *parent = Q_NULLPTR); ~QState(); QAbstractState *errorState() const; diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h index 2ce0c13522d757bab198f43f22a979e1da2a6c51..3b8dae94995d62b301514a4b04e88b059950a7cf 100644 --- a/src/corelib/statemachine/qstate_p.h +++ b/src/corelib/statemachine/qstate_p.h @@ -75,6 +75,7 @@ struct QPropertyAssignment QVariant value; bool explicitlySet; // false means the property is being restored to its old value }; +Q_DECLARE_TYPEINFO(QPropertyAssignment, Q_MOVABLE_TYPE); #endif // QT_NO_PROPERTIES @@ -108,7 +109,7 @@ public: mutable QList<QAbstractTransition*> transitionsList; #ifndef QT_NO_PROPERTIES - QList<QPropertyAssignment> propertyAssignments; + QVector<QPropertyAssignment> propertyAssignments; #endif }; diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 3a1a852ef5f4837af7a8de78b0a0ca7d6d7fc50f..237b19bc0e9a204e4da4130ec011592090a250b0 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -365,9 +365,9 @@ static QList<QAbstractState *> getEffectiveTargetStates(QAbstractTransition *tra if (!historyConfiguration.isEmpty()) { // There is a saved history, so apply that. targets.unite(historyConfiguration.toSet()); - } else if (QAbstractState *defaultState = historyState->defaultState()) { - // Qt does not support initial transitions, but uses the default state of the history state for this. - targets.insert(defaultState); + } else if (QAbstractTransition *defaultTransition = historyState->defaultTransition()) { + // No saved history, take all default transition targets. + targets.unite(defaultTransition->targetStates().toSet()); } else { // Woops, we found a history state without a default state. That's not valid! QStateMachinePrivate *m = QStateMachinePrivate::get(historyState->machine()); @@ -383,10 +383,6 @@ static QList<QAbstractState *> getEffectiveTargetStates(QAbstractTransition *tra return targetsList; } -template <class T> -static uint qHash(const QPointer<T> &p) -{ return qHash(p.data()); } - QStateMachinePrivate::QStateMachinePrivate() { isMachine = true; @@ -410,13 +406,6 @@ QStateMachinePrivate::~QStateMachinePrivate() qDeleteAll(externalEventQueue); } -QStateMachinePrivate *QStateMachinePrivate::get(QStateMachine *q) -{ - if (q) - return q->d_func(); - return 0; -} - QState *QStateMachinePrivate::rootState() const { return const_cast<QStateMachine*>(q_func()); @@ -684,7 +673,7 @@ void QStateMachinePrivate::microstep(QEvent *event, const QList<QAbstractTransit qDebug() << q_func() << ": computed entry set:" << enteredStates; #endif - QHash<QAbstractState*, QList<QPropertyAssignment> > assignmentsForEnteredStates = + QHash<QAbstractState*, QVector<QPropertyAssignment> > assignmentsForEnteredStates = computePropertyAssignments(enteredStates, pendingRestorables); if (!pendingRestorables.isEmpty()) { // Add "implicit" assignments for restored properties to the first @@ -795,7 +784,7 @@ QSet<QAbstractState*> QStateMachinePrivate::computeExitSet_Unordered(QAbstractTr } void QStateMachinePrivate::exitStates(QEvent *event, const QList<QAbstractState*> &statesToExit_sorted, - const QHash<QAbstractState*, QList<QPropertyAssignment> > &assignmentsForEnteredStates) + const QHash<QAbstractState*, QVector<QPropertyAssignment> > &assignmentsForEnteredStates) { for (int i = 0; i < statesToExit_sorted.size(); ++i) { QAbstractState *s = statesToExit_sorted.at(i); @@ -943,7 +932,7 @@ QAbstractState *QStateMachinePrivate::getTransitionDomain(QAbstractTransition *t void QStateMachinePrivate::enterStates(QEvent *event, const QList<QAbstractState*> &exitedStates_sorted, const QList<QAbstractState*> &statesToEnter_sorted, const QSet<QAbstractState*> &statesForDefaultEntry, - QHash<QAbstractState*, QList<QPropertyAssignment> > &propertyAssignmentsForState + QHash<QAbstractState*, QVector<QPropertyAssignment> > &propertyAssignmentsForState #ifndef QT_NO_ANIMATION , const QList<QAbstractAnimation *> &selectedAnimations #endif @@ -966,7 +955,7 @@ void QStateMachinePrivate::enterStates(QEvent *event, const QList<QAbstractState // Immediately set the properties that are not animated. { - QList<QPropertyAssignment> assignments = propertyAssignmentsForState.value(s); + QVector<QPropertyAssignment> assignments = propertyAssignmentsForState.value(s); for (int i = 0; i < assignments.size(); ++i) { const QPropertyAssignment &assn = assignments.at(i); if (globalRestorePolicy == QState::RestoreProperties) { @@ -989,9 +978,16 @@ void QStateMachinePrivate::enterStates(QEvent *event, const QList<QAbstractState QAbstractStatePrivate::get(s)->callOnEntry(event); QAbstractStatePrivate::get(s)->emitEntered(); - if (statesForDefaultEntry.contains(s)) { - // ### executeContent(s.initial.transition.children()) - } + + // FIXME: + // See the "initial transitions" comment in addDescendantStatesToEnter first, then implement: +// if (statesForDefaultEntry.contains(s)) { +// // ### executeContent(s.initial.transition.children()) +// } + Q_UNUSED(statesForDefaultEntry); + + if (QHistoryState *h = toHistoryState(s)) + QAbstractTransitionPrivate::get(h->defaultTransition())->callOnTransition(event); // Emit propertiesAssigned signal if the state has no animated properties. { @@ -1052,69 +1048,6 @@ void QStateMachinePrivate::enterStates(QEvent *event, const QList<QAbstractState // qDebug() << "configuration:" << configuration.toList(); } -void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root, - QSet<QAbstractState*> &statesToEnter, - QSet<QAbstractState*> &statesForDefaultEntry) -{ - if (QHistoryState *h = toHistoryState(s)) { - QList<QAbstractState*> hconf = QHistoryStatePrivate::get(h)->configuration; - if (!hconf.isEmpty()) { - for (int k = 0; k < hconf.size(); ++k) { - QAbstractState *s0 = hconf.at(k); - addStatesToEnter(s0, root, statesToEnter, statesForDefaultEntry); - } -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q_func() << ": restoring" - << ((QHistoryStatePrivate::get(h)->historyType == QHistoryState::DeepHistory) ? "deep" : "shallow") - << "history from" << s << ':' << hconf; -#endif - } else { - QList<QAbstractState*> hlst; - if (QHistoryStatePrivate::get(h)->defaultState) - hlst.append(QHistoryStatePrivate::get(h)->defaultState); - - if (hlst.isEmpty()) { - setError(QStateMachine::NoDefaultStateInHistoryStateError, h); - } else { - for (int k = 0; k < hlst.size(); ++k) { - QAbstractState *s0 = hlst.at(k); - addStatesToEnter(s0, root, statesToEnter, statesForDefaultEntry); - } -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q_func() << ": initial history targets for" << s << ':' << hlst; -#endif - } - } - } else { - if (s == rootState()) { - // Error has already been set by exitStates(). - Q_ASSERT(error != QStateMachine::NoError); - return; - } - statesToEnter.insert(s); - if (isParallel(s)) { - QState *grp = toStandardState(s); - QList<QAbstractState*> lst = QStatePrivate::get(grp)->childStates(); - for (int i = 0; i < lst.size(); ++i) { - QAbstractState *child = lst.at(i); - addStatesToEnter(child, grp, statesToEnter, statesForDefaultEntry); - } - } else if (isCompound(s)) { - statesForDefaultEntry.insert(s); - QState *grp = toStandardState(s); - QAbstractState *initial = grp->initialState(); - if (initial != 0) { - Q_ASSERT(initial->machine() == q_func()); - addStatesToEnter(initial, grp, statesToEnter, statesForDefaultEntry); - } else { - setError(QStateMachine::NoInitialStateError, grp); - return; - } - } - addAncestorStatesToEnter(s, root, statesToEnter, statesForDefaultEntry); - } -} - /* The algorithm as described in http://www.w3.org/TR/2014/WD-scxml-20140529/ has a bug. See * QTBUG-44963 for details. The algorithm here is as described in * http://www.w3.org/Voice/2013/scxml-irp/SCXML.htm as of Friday March 13, 2015. @@ -1165,8 +1098,8 @@ void QStateMachinePrivate::addDescendantStatesToEnter(QAbstractState *state, #endif } else { QList<QAbstractState*> defaultHistoryContent; - if (QHistoryStatePrivate::get(h)->defaultState) - defaultHistoryContent.append(QHistoryStatePrivate::get(h)->defaultState); + if (QAbstractTransition *t = QHistoryStatePrivate::get(h)->defaultTransition) + defaultHistoryContent = t->targetStates(); if (defaultHistoryContent.isEmpty()) { setError(QStateMachine::NoDefaultStateInHistoryStateError, h); @@ -1192,8 +1125,10 @@ void QStateMachinePrivate::addDescendantStatesToEnter(QAbstractState *state, if (QAbstractState *initial = toStandardState(state)->initialState()) { Q_ASSERT(initial->machine() == q_func()); + // FIXME: // Qt does not support initial transitions (which is a problem for parallel states). // The way it simulates this for other states, is by having a single initial state. + // See also the FIXME in enterStates. statesForDefaultEntry.insert(initial); addDescendantStatesToEnter(initial, statesToEnter, statesForDefaultEntry); @@ -1413,9 +1348,9 @@ void QStateMachinePrivate::unregisterRestorables(const QList<QAbstractState *> & } } -QList<QPropertyAssignment> QStateMachinePrivate::restorablesToPropertyList(const QHash<RestorableId, QVariant> &restorables) const +QVector<QPropertyAssignment> QStateMachinePrivate::restorablesToPropertyList(const QHash<RestorableId, QVariant> &restorables) const { - QList<QPropertyAssignment> result; + QVector<QPropertyAssignment> result; QHash<RestorableId, QVariant>::const_iterator it; for (it = restorables.constBegin(); it != restorables.constEnd(); ++it) { const RestorableId &id = it.key(); @@ -1470,16 +1405,16 @@ QHash<QStateMachinePrivate::RestorableId, QVariant> QStateMachinePrivate::comput properties that should not be restored because they are assigned by an entered state). */ -QHash<QAbstractState*, QList<QPropertyAssignment> > QStateMachinePrivate::computePropertyAssignments( +QHash<QAbstractState*, QVector<QPropertyAssignment> > QStateMachinePrivate::computePropertyAssignments( const QList<QAbstractState*> &statesToEnter_sorted, QHash<RestorableId, QVariant> &pendingRestorables) const { - QHash<QAbstractState*, QList<QPropertyAssignment> > assignmentsForState; + QHash<QAbstractState*, QVector<QPropertyAssignment> > assignmentsForState; for (int i = 0; i < statesToEnter_sorted.size(); ++i) { QState *s = toStandardState(statesToEnter_sorted.at(i)); if (!s) continue; - QList<QPropertyAssignment> &assignments = QStatePrivate::get(s)->propertyAssignments; + QVector<QPropertyAssignment> &assignments = QStatePrivate::get(s)->propertyAssignments; for (int j = 0; j < assignments.size(); ++j) { const QPropertyAssignment &assn = assignments.at(j); if (assn.objectDeleted()) { @@ -1556,8 +1491,11 @@ void QStateMachinePrivate::setError(QStateMachine::Error errorCode, QAbstractSta #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": entering error state" << currentErrorState << "from" << currentContext; #endif - QState *lca = findLCA(QList<QAbstractState*>() << currentErrorState << currentContext); - addStatesToEnter(currentErrorState, lca, pendingErrorStates, pendingErrorStatesForDefaultEntry); + pendingErrorStates.insert(currentErrorState); + addDescendantStatesToEnter(currentErrorState, pendingErrorStates, pendingErrorStatesForDefaultEntry); + addAncestorStatesToEnter(currentErrorState, rootState(), pendingErrorStates, pendingErrorStatesForDefaultEntry); + foreach (QAbstractState *s, configuration) + pendingErrorStates.remove(s); } else { qWarning("Unrecoverable error detected in running state machine: %s", qPrintable(errorString)); @@ -1652,7 +1590,7 @@ QList<QAbstractAnimation *> QStateMachinePrivate::selectAnimations(const QList<Q } void QStateMachinePrivate::terminateActiveAnimations(QAbstractState *state, - const QHash<QAbstractState*, QList<QPropertyAssignment> > &assignmentsForEnteredStates) + const QHash<QAbstractState*, QVector<QPropertyAssignment> > &assignmentsForEnteredStates) { Q_Q(QStateMachine); QList<QAbstractAnimation*> animations = animationsForState.take(state); @@ -1677,9 +1615,9 @@ void QStateMachinePrivate::terminateActiveAnimations(QAbstractState *state, // If there is no property assignment that sets this property, // set the property to its target value. bool found = false; - QHash<QAbstractState*, QList<QPropertyAssignment> >::const_iterator it; + QHash<QAbstractState*, QVector<QPropertyAssignment> >::const_iterator it; for (it = assignmentsForEnteredStates.constBegin(); it != assignmentsForEnteredStates.constEnd(); ++it) { - const QList<QPropertyAssignment> &assignments = it.value(); + const QVector<QPropertyAssignment> &assignments = it.value(); for (int j = 0; j < assignments.size(); ++j) { if (assignments.at(j).hasTarget(assn.object, assn.propertyName)) { found = true; @@ -1697,15 +1635,15 @@ void QStateMachinePrivate::terminateActiveAnimations(QAbstractState *state, void QStateMachinePrivate::initializeAnimations(QAbstractState *state, const QList<QAbstractAnimation *> &selectedAnimations, const QList<QAbstractState*> &exitedStates_sorted, - QHash<QAbstractState*, QList<QPropertyAssignment> > &assignmentsForEnteredStates) + QHash<QAbstractState*, QVector<QPropertyAssignment> > &assignmentsForEnteredStates) { Q_Q(QStateMachine); if (!assignmentsForEnteredStates.contains(state)) return; - QList<QPropertyAssignment> &assignments = assignmentsForEnteredStates[state]; + QVector<QPropertyAssignment> &assignments = assignmentsForEnteredStates[state]; for (int i = 0; i < selectedAnimations.size(); ++i) { QAbstractAnimation *anim = selectedAnimations.at(i); - QList<QPropertyAssignment>::iterator it; + QVector<QPropertyAssignment>::iterator it; for (it = assignments.begin(); it != assignments.end(); ) { QPair<QList<QAbstractAnimation*>, QList<QAbstractAnimation*> > ret; const QPropertyAssignment &assn = *it; @@ -1864,7 +1802,7 @@ void QStateMachinePrivate::_q_start() QSet<QAbstractState*> statesForDefaultEntry; QList<QAbstractState*> enteredStates = computeEntrySet(transitions, statesForDefaultEntry, &calculationCache); QHash<RestorableId, QVariant> pendingRestorables; - QHash<QAbstractState*, QList<QPropertyAssignment> > assignmentsForEnteredStates = + QHash<QAbstractState*, QVector<QPropertyAssignment> > assignmentsForEnteredStates = computePropertyAssignments(enteredStates, pendingRestorables); #ifndef QT_NO_ANIMATION QList<QAbstractAnimation*> selectedAnimations = selectAnimations(transitions); @@ -2454,6 +2392,7 @@ void QStateMachinePrivate::handleTransitionSignal(QObject *sender, int signalInd QMetaMethod method = meta->method(signalIndex); int argc = method.parameterCount(); QList<QVariant> vargs; + vargs.reserve(argc); for (int i = 0; i < argc; ++i) { int type = method.parameterType(i); vargs.append(QVariant(type, argv[i+1])); @@ -3273,7 +3212,7 @@ QStateMachine::WrappedEvent::~WrappedEvent() \fn QStateMachine::runningChanged(bool running) \since 5.4 - This signal is emitted when the running property is changed. + This signal is emitted when the running property is changed with \a running as argument. \sa QStateMachine::running */ diff --git a/src/corelib/statemachine/qstatemachine.h b/src/corelib/statemachine/qstatemachine.h index d6c3b7bfa7ca4a5a5d8ea1a6e9fbc6a6d8af9b3a..5fca0343860a40f94d5ffb011008588b19fab710 100644 --- a/src/corelib/statemachine/qstatemachine.h +++ b/src/corelib/statemachine/qstatemachine.h @@ -104,8 +104,8 @@ public: NoCommonAncestorForTransitionError }; - explicit QStateMachine(QObject *parent = 0); - explicit QStateMachine(QState::ChildMode childMode, QObject *parent = 0); + explicit QStateMachine(QObject *parent = Q_NULLPTR); + explicit QStateMachine(QState::ChildMode childMode, QObject *parent = Q_NULLPTR); ~QStateMachine(); void addState(QAbstractState *state); diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 426f2732df16b956b92d9d3359a85295f18dfffc..4419ebc7f3a5f0d47f491e87119f91a9462e89a3 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -99,7 +99,8 @@ public: QStateMachinePrivate(); ~QStateMachinePrivate(); - static QStateMachinePrivate *get(QStateMachine *q); + static QStateMachinePrivate *get(QStateMachine *q) + { return q ? q->d_func() : 0; } QState *findLCA(const QList<QAbstractState*> &states, bool onlyCompound = false) const; QState *findLCCA(const QList<QAbstractState*> &states) const; @@ -133,7 +134,7 @@ public: virtual void beginMacrostep(); virtual void endMacrostep(bool didChange); void exitStates(QEvent *event, const QList<QAbstractState *> &statesToExit_sorted, - const QHash<QAbstractState*, QList<QPropertyAssignment> > &assignmentsForEnteredStates); + const QHash<QAbstractState*, QVector<QPropertyAssignment> > &assignmentsForEnteredStates); QList<QAbstractState*> computeExitSet(const QList<QAbstractTransition*> &enabledTransitions, CalculationCache *cache); QSet<QAbstractState*> computeExitSet_Unordered(const QList<QAbstractTransition*> &enabledTransitions, CalculationCache *cache); QSet<QAbstractState*> computeExitSet_Unordered(QAbstractTransition *t, CalculationCache *cache); @@ -141,7 +142,7 @@ public: void enterStates(QEvent *event, const QList<QAbstractState*> &exitedStates_sorted, const QList<QAbstractState*> &statesToEnter_sorted, const QSet<QAbstractState*> &statesForDefaultEntry, - QHash<QAbstractState *, QList<QPropertyAssignment> > &propertyAssignmentsForState + QHash<QAbstractState *, QVector<QPropertyAssignment> > &propertyAssignmentsForState #ifndef QT_NO_ANIMATION , const QList<QAbstractAnimation*> &selectedAnimations #endif @@ -154,9 +155,6 @@ public: void addDescendantStatesToEnter(QAbstractState *state, QSet<QAbstractState*> &statesToEnter, QSet<QAbstractState*> &statesForDefaultEntry); - void addStatesToEnter(QAbstractState *s, QState *root, - QSet<QAbstractState*> &statesToEnter, - QSet<QAbstractState*> &statesForDefaultEntry); void addAncestorStatesToEnter(QAbstractState *s, QAbstractState *ancestor, QSet<QAbstractState*> &statesToEnter, QSet<QAbstractState*> &statesForDefaultEntry); @@ -232,9 +230,9 @@ public: const QVariant &value); void unregisterRestorables(const QList<QAbstractState*> &states, QObject *object, const QByteArray &propertyName); - QList<QPropertyAssignment> restorablesToPropertyList(const QHash<RestorableId, QVariant> &restorables) const; + QVector<QPropertyAssignment> restorablesToPropertyList(const QHash<RestorableId, QVariant> &restorables) const; QHash<RestorableId, QVariant> computePendingRestorables(const QList<QAbstractState*> &statesToExit_sorted) const; - QHash<QAbstractState*, QList<QPropertyAssignment> > computePropertyAssignments( + QHash<QAbstractState*, QVector<QPropertyAssignment> > computePropertyAssignments( const QList<QAbstractState*> &statesToEnter_sorted, QHash<RestorableId, QVariant> &pendingRestorables) const; #endif @@ -275,10 +273,10 @@ public: QList<QAbstractAnimation *> selectAnimations(const QList<QAbstractTransition *> &transitionList) const; void terminateActiveAnimations(QAbstractState *state, - const QHash<QAbstractState*, QList<QPropertyAssignment> > &assignmentsForEnteredStates); + const QHash<QAbstractState*, QVector<QPropertyAssignment> > &assignmentsForEnteredStates); void initializeAnimations(QAbstractState *state, const QList<QAbstractAnimation*> &selectedAnimations, const QList<QAbstractState *> &exitedStates_sorted, - QHash<QAbstractState *, QList<QPropertyAssignment> > &assignmentsForEnteredStates); + QHash<QAbstractState *, QVector<QPropertyAssignment> > &assignmentsForEnteredStates); #endif // QT_NO_ANIMATION QSignalEventGenerator *signalEventGenerator; diff --git a/src/corelib/thread/qexception.cpp b/src/corelib/thread/qexception.cpp index 01bbe70c88a1287ea69fa1c49c58bde5816a7c15..04a03b86233772de88df83398123531d26cc265d 100644 --- a/src/corelib/thread/qexception.cpp +++ b/src/corelib/thread/qexception.cpp @@ -108,7 +108,9 @@ QT_BEGIN_NAMESPACE */ QException::~QException() -#ifndef Q_COMPILER_NOEXCEPT +#ifdef Q_COMPILER_NOEXCEPT + noexcept +#else throw() #endif { @@ -127,7 +129,9 @@ QException *QException::clone() const } QUnhandledException::~QUnhandledException() -#ifndef Q_COMPILER_NOEXCEPT +#ifdef Q_COMPILER_NOEXCEPT + noexcept +#else throw() #endif { diff --git a/src/corelib/thread/qexception.h b/src/corelib/thread/qexception.h index edf361ebd35c69d8b8b02fb4d2148954df79733b..b15ae5095ab98e5063eca117be248b299c6aa994 100644 --- a/src/corelib/thread/qexception.h +++ b/src/corelib/thread/qexception.h @@ -54,7 +54,9 @@ class Q_CORE_EXPORT QException : public std::exception { public: ~QException() -#ifndef Q_COMPILER_NOEXCEPT +#ifdef Q_COMPILER_NOEXCEPT + noexcept +#else throw() #endif ; @@ -66,10 +68,12 @@ class Q_CORE_EXPORT QUnhandledException : public QException { public: ~QUnhandledException() -#ifndef Q_COMPILER_NOEXCEPT +#ifdef Q_COMPILER_NOEXCEPT + noexcept +#else throw() #endif -; + ; void raise() const Q_DECL_OVERRIDE; QUnhandledException *clone() const Q_DECL_OVERRIDE; }; @@ -80,7 +84,7 @@ class Base; class Q_CORE_EXPORT ExceptionHolder { public: - ExceptionHolder(QException *exception = 0); + ExceptionHolder(QException *exception = Q_NULLPTR); ExceptionHolder(const ExceptionHolder &other); void operator=(const ExceptionHolder &other); ~ExceptionHolder(); diff --git a/src/corelib/thread/qfuture.qdoc b/src/corelib/thread/qfuture.qdoc index be4cee2bd6bb030e322c6c377fe334870c4b8eb5..ed0b26e121e261cb4d161a3e83b53dbb6abbc738 100644 --- a/src/corelib/thread/qfuture.qdoc +++ b/src/corelib/thread/qfuture.qdoc @@ -352,6 +352,7 @@ /*! \class QFuture::const_iterator \reentrant \since 4.4 + \inmodule QtCore \brief The QFuture::const_iterator class provides an STL-style const iterator for QFuture. diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h index 01eb043a5e32d050259a859f0a7ee39ccb5f4172..8c1f7e7d8260969ca6e6920e619a608d5cff8dd0 100644 --- a/src/corelib/thread/qfutureinterface.h +++ b/src/corelib/thread/qfutureinterface.h @@ -299,7 +299,7 @@ public: void reportResult(const void *, int) { } void reportResults(const QVector<void> &, int) { } - void reportFinished(const void * = 0) { QFutureInterfaceBase::reportFinished(); } + void reportFinished(const void * = Q_NULLPTR) { QFutureInterfaceBase::reportFinished(); } }; QT_END_NAMESPACE diff --git a/src/corelib/thread/qfuturewatcher.h b/src/corelib/thread/qfuturewatcher.h index 63558d4a0fc878c2aa6b096d6cf9a03adc5dcd9f..42a22d906322efa76e0a8c2fe5ff98cf870ae594 100644 --- a/src/corelib/thread/qfuturewatcher.h +++ b/src/corelib/thread/qfuturewatcher.h @@ -52,7 +52,7 @@ class Q_CORE_EXPORT QFutureWatcherBase : public QObject Q_DECLARE_PRIVATE(QFutureWatcherBase) public: - explicit QFutureWatcherBase(QObject *parent = 0); + explicit QFutureWatcherBase(QObject *parent = Q_NULLPTR); // de-inline dtor int progressValue() const; @@ -179,7 +179,7 @@ template <> class QFutureWatcher<void> : public QFutureWatcherBase { public: - explicit QFutureWatcher(QObject *_parent = 0) + explicit QFutureWatcher(QObject *_parent = Q_NULLPTR) : QFutureWatcherBase(_parent) { } ~QFutureWatcher() diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h index 63c488747f92ce37c155811068a3487304d2a86f..0c5a73b4df60ad5a3cfd283e732ea3aef83cdf03 100644 --- a/src/corelib/thread/qmutex.h +++ b/src/corelib/thread/qmutex.h @@ -73,16 +73,16 @@ public: private: inline bool fastTryLock() Q_DECL_NOTHROW { - return d_ptr.testAndSetAcquire(0, dummyLocked()); + return d_ptr.testAndSetAcquire(Q_NULLPTR, dummyLocked()); } inline bool fastTryUnlock() Q_DECL_NOTHROW { - return d_ptr.testAndSetRelease(dummyLocked(), 0); + return d_ptr.testAndSetRelease(dummyLocked(), Q_NULLPTR); } inline bool fastTryLock(QMutexData *¤t) Q_DECL_NOTHROW { - return d_ptr.testAndSetAcquire(0, dummyLocked(), current); + return d_ptr.testAndSetAcquire(Q_NULLPTR, dummyLocked(), current); } inline bool fastTryUnlock(QMutexData *¤t) Q_DECL_NOTHROW { - return d_ptr.testAndSetRelease(dummyLocked(), 0, current); + return d_ptr.testAndSetRelease(dummyLocked(), Q_NULLPTR, current); } void lockInternal() QT_MUTEX_LOCK_NOEXCEPT; diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp index c4130fdba5e0bb08bc299e4cdb8d043e44ef135c..c24ea5886817030d70cfc09c030e62c4258ad13e 100644 --- a/src/corelib/thread/qmutex_win.cpp +++ b/src/corelib/thread/qmutex_win.cpp @@ -55,10 +55,10 @@ QMutexPrivate::~QMutexPrivate() bool QMutexPrivate::wait(int timeout) { -#ifndef Q_OS_WINRT - return (WaitForSingleObject(event, timeout < 0 ? INFINITE : timeout) == WAIT_OBJECT_0); -#else +#ifndef Q_OS_WINCE return (WaitForSingleObjectEx(event, timeout < 0 ? INFINITE : timeout, FALSE) == WAIT_OBJECT_0); +#else + return (WaitForSingleObject(event, timeout < 0 ? INFINITE : timeout) == WAIT_OBJECT_0); #endif } diff --git a/src/corelib/thread/qresultstore.h b/src/corelib/thread/qresultstore.h index fbcb8ad3cd4b0ab39513a72f4d19aaefc31501df..7ecaa231b296180a05f92d9ac539765ab5d4a5df 100644 --- a/src/corelib/thread/qresultstore.h +++ b/src/corelib/thread/qresultstore.h @@ -61,8 +61,8 @@ class ResultItem public: ResultItem(const void *_result, int _count) : m_count(_count), result(_result) { } // contruct with vector of results ResultItem(const void *_result) : m_count(0), result(_result) { } // construct with result - ResultItem() : m_count(0), result(0) { } - bool isValid() const { return result != 0; } + ResultItem() : m_count(0), result(Q_NULLPTR) { } + bool isValid() const { return result != Q_NULLPTR; } bool isVector() const { return m_count != 0; } int count() const { return (m_count == 0) ? 1 : m_count; } int m_count; // result is either a pointer to a result or to a vector of results, diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 767e4f93fccc1675f345ac7e5d27662d88a0e3d4..2309ea0595eed574c899af9cd621556f5578bc64 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -52,7 +52,8 @@ Q_LOGGING_CATEGORY(QT_QTHREAD, "qt.qthread"); QThreadData::QThreadData(int initialRefCount) : _ref(initialRefCount), loopLevel(0), thread(0), threadId(0), - eventDispatcher(0), quitNow(false), canWait(true), isAdopted(false) + eventDispatcher(0), + quitNow(false), canWait(true), isAdopted(false), requiresCoreApplication(true) { // fprintf(stderr, "QThreadData %p created\n", this); } @@ -873,4 +874,28 @@ bool QThread::isInterruptionRequested() const return d->interruptionRequested; } +/*! + \class QDaemonThread + \since 5.5 + \brief The QDaemonThread provides a class to manage threads that outlive QCoreApplication + \internal + + Note: don't try to deliver events from the started() signal. +*/ +static void setThreadDoesNotRequireCoreApplication() +{ + QThreadData::current()->requiresCoreApplication = false; +} + +QDaemonThread::QDaemonThread(QObject *parent) + : QThread(parent) +{ + // QThread::started() is emitted from the thread we start + connect(this, &QThread::started, setThreadDoesNotRequireCoreApplication); +} + +QDaemonThread::~QDaemonThread() +{ +} + QT_END_NAMESPACE diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h index ef3744677f52fd4b67d00b4492563019914593d0..c75809fd46018b3dd38098d431f9f4df71f1705c 100644 --- a/src/corelib/thread/qthread.h +++ b/src/corelib/thread/qthread.h @@ -57,7 +57,7 @@ public: static int idealThreadCount() Q_DECL_NOTHROW; static void yieldCurrentThread(); - explicit QThread(QObject *parent = 0); + explicit QThread(QObject *parent = Q_NULLPTR); ~QThread(); enum Priority { @@ -118,7 +118,7 @@ protected: static void setTerminationEnabled(bool enabled = true); protected: - QThread(QThreadPrivate &dd, QObject *parent = 0); + QThread(QThreadPrivate &dd, QObject *parent = Q_NULLPTR); private: Q_DECLARE_PRIVATE(QThread) diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 2008f76621e3171ebbda2024d90c6d18da368961..ffefe0b1d19b7608c22a69220d027f257c265440 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -135,6 +135,13 @@ private: #ifndef QT_NO_THREAD +class Q_CORE_EXPORT QDaemonThread : public QThread +{ +public: + QDaemonThread(QObject *parent = 0); + ~QDaemonThread(); +}; + class QThreadPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QThread) @@ -171,19 +178,10 @@ public: #endif // Q_OS_UNIX #ifdef Q_OS_WIN -# ifndef Q_OS_WINRT static unsigned int __stdcall start(void *); static void finish(void *, bool lockAnyway=true); -# else - HRESULT start(ABI::Windows::Foundation::IAsyncAction *); - void finish(bool lockAnyway = true); -# endif -# ifndef Q_OS_WINRT Qt::HANDLE handle; -# else - ABI::Windows::Foundation::IAsyncAction *handle; -# endif unsigned int id; int waiters; bool terminationEnabled, terminatePending; @@ -233,7 +231,7 @@ public: QThreadData(int initialRefCount = 1); ~QThreadData(); - static QThreadData *current(bool createIfNecessary = true); + static Q_AUTOTEST_EXPORT QThreadData *current(bool createIfNecessary = true); static void clearCurrentThreadData(); static QThreadData *get2(QThread *thread) { Q_ASSERT_X(thread != 0, "QThread", "internal error"); return thread->d_func()->data; } @@ -287,6 +285,7 @@ public: bool quitNow; bool canWait; bool isAdopted; + bool requiresCoreApplication; }; class QScopedLoopLevelCounter diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 6c488c3a335169d35c014482e76c82c4abd87e13..b79a238ce3d525c9c6a200cdf918b12f5baef5cb 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -320,14 +320,15 @@ void *QThreadPrivate::start(void *arg) createEventDispatcher(data); #if (defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_QNX)) - // sets the name of the current thread. - QString objectName = thr->objectName(); - - if (Q_LIKELY(objectName.isEmpty())) - setCurrentThreadName(thr->d_func()->thread_id, thr->metaObject()->className()); - else - setCurrentThreadName(thr->d_func()->thread_id, objectName.toLocal8Bit()); + { + // sets the name of the current thread. + QString objectName = thr->objectName(); + if (Q_LIKELY(objectName.isEmpty())) + setCurrentThreadName(thr->d_func()->thread_id, thr->metaObject()->className()); + else + setCurrentThreadName(thr->d_func()->thread_id, objectName.toLocal8Bit()); + } #endif emit thr->started(QThread::QPrivateSignal()); diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index feb189bf45f1350fe9836f9aec2a437c588ede4d..c16a2e958c6befce29502b89f38eea0b26ff106f 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -32,7 +32,7 @@ ****************************************************************************/ //#define WINVER 0x0500 -#if (_WIN32_WINNT < 0x0400) +#if !defined Q_OS_WINRT && (_WIN32_WINNT < 0x0400) #define _WIN32_WINNT 0x0400 #endif @@ -46,18 +46,25 @@ #include <qpointer.h> #include <private/qcoreapplication_p.h> +#ifndef Q_OS_WINRT #include <private/qeventdispatcher_win_p.h> +#else +#include <private/qeventdispatcher_winrt_p.h> +#endif #include <qt_windows.h> +#ifndef Q_OS_WINRT #ifndef Q_OS_WINCE #ifndef _MT #define _MT -#endif +#endif // _MT #include <process.h> -#else +#else // !Q_OS_WINCE #include "qfunctions_wince.h" -#endif +#endif // Q_OS_WINCE +#else // !Q_OS_WINRT +#endif // Q_OS_WINRT #ifndef QT_NO_THREAD QT_BEGIN_NAMESPACE @@ -171,7 +178,11 @@ void qt_watch_adopted_thread(const HANDLE adoptedThreadHandle, QThread *qthread) // Start watcher thread if it is not already running. if (qt_adopted_thread_watcher_id == 0) { if (qt_adopted_thread_wakeup == 0) { +#ifndef Q_OS_WINRT qt_adopted_thread_wakeup = CreateEvent(0, false, false, 0); +#else + qt_adopted_thread_wakeup = CreateEventEx(0, NULL, 0, EVENT_ALL_ACCESS); +#endif qt_adopted_thread_handles.prepend(qt_adopted_thread_wakeup); } @@ -210,13 +221,21 @@ DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID) // no need to loop, no timeout offset = 0; count = handlesCopy.count(); +#ifndef Q_OS_WINRT ret = WaitForMultipleObjects(handlesCopy.count(), handlesCopy.constData(), false, INFINITE); +#else + ret = WaitForMultipleObjectsEx(handlesCopy.count(), handlesCopy.constData(), false, INFINITE, false); +#endif } else { int loop = 0; do { offset = loop * MAXIMUM_WAIT_OBJECTS; count = qMin(handlesCopy.count() - offset, MAXIMUM_WAIT_OBJECTS); +#ifndef Q_OS_WINRT ret = WaitForMultipleObjects(count, handlesCopy.constData() + offset, false, 100); +#else + ret = WaitForMultipleObjectsEx(count, handlesCopy.constData() + offset, false, 100, false); +#endif loop = (loop + 1) % loops; } while (ret == WAIT_TIMEOUT); } @@ -263,7 +282,7 @@ DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID) return 0; } -#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE) +#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) #ifndef Q_OS_WIN64 # define ULONG_PTR DWORD @@ -293,7 +312,7 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName) { } } -#endif // !QT_NO_DEBUG && Q_CC_MSVC && !Q_OS_WINCE +#endif // !QT_NO_DEBUG && Q_CC_MSVC && !Q_OS_WINCE && !Q_OS_WINRT /************************************************************************** ** QThreadPrivate @@ -303,7 +322,11 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName) void QThreadPrivate::createEventDispatcher(QThreadData *data) { +#ifndef Q_OS_WINRT QEventDispatcherWin32 *theEventDispatcher = new QEventDispatcherWin32; +#else + QEventDispatcherWinRT *theEventDispatcher = new QEventDispatcherWinRT; +#endif data->eventDispatcher.storeRelease(theEventDispatcher); theEventDispatcher->startingUp(); } @@ -331,7 +354,7 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi else createEventDispatcher(data); -#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE) +#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) // sets the name of the current thread. QByteArray objectName = thr->objectName().toLocal8Bit(); qt_set_thread_name((HANDLE)-1, @@ -396,13 +419,17 @@ Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW int QThread::idealThreadCount() Q_DECL_NOTHROW { SYSTEM_INFO sysinfo; +#ifndef Q_OS_WINRT GetSystemInfo(&sysinfo); +#else + GetNativeSystemInfo(&sysinfo); +#endif return sysinfo.dwNumberOfProcessors; } void QThread::yieldCurrentThread() { -#ifndef Q_OS_WINCE +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) SwitchToThread(); #else ::Sleep(0); @@ -444,6 +471,7 @@ void QThread::start(Priority priority) d->returnCode = 0; d->interruptionRequested = false; +#ifndef Q_OS_WINRT /* NOTE: we create the thread in the suspended state, set the priority and then resume the thread. @@ -456,6 +484,10 @@ void QThread::start(Priority priority) */ d->handle = (Qt::HANDLE) _beginthreadex(NULL, d->stackSize, QThreadPrivate::start, this, CREATE_SUSPENDED, &(d->id)); +#else // !Q_OS_WINRT + d->handle = (Qt::HANDLE) CreateThread(NULL, d->stackSize, (LPTHREAD_START_ROUTINE)QThreadPrivate::start, + this, CREATE_SUSPENDED, reinterpret_cast<LPDWORD>(&d->id)); +#endif // Q_OS_WINRT if (!d->handle) { qErrnoWarning(errno, "QThread::start: Failed to create thread"); @@ -521,7 +553,10 @@ void QThread::terminate() return; } + // Calling ExitThread() in setTerminationEnabled is all we can do on WinRT +#ifndef Q_OS_WINRT TerminateThread(d->handle, 0); +#endif QThreadPrivate::finish(this, false); } @@ -541,7 +576,11 @@ bool QThread::wait(unsigned long time) locker.mutex()->unlock(); bool ret = false; +#ifndef Q_OS_WINRT switch (WaitForSingleObject(d->handle, time)) { +#else + switch (WaitForSingleObjectEx(d->handle, time, false)) { +#endif case WAIT_OBJECT_0: ret = true; break; @@ -582,7 +621,11 @@ void QThread::setTerminationEnabled(bool enabled) if (enabled && d->terminatePending) { QThreadPrivate::finish(thr, false); locker.unlock(); // don't leave the mutex locked! +#ifndef Q_OS_WINRT _endthreadex(0); +#else + ExitThread(0); +#endif } } diff --git a/src/corelib/thread/qthread_winrt.cpp b/src/corelib/thread/qthread_winrt.cpp deleted file mode 100644 index f4a7a662cb00f849b9ef15c7f223b61c6ac7bec4..0000000000000000000000000000000000000000 --- a/src/corelib/thread/qthread_winrt.cpp +++ /dev/null @@ -1,450 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qthread.h" -#include "qthread_p.h" -#include "qthreadstorage.h" - -#include <QtCore/QElapsedTimer> -#include <QtCore/QUuid> -#include <QtCore/qt_windows.h> -#include <QtCore/qfunctions_winrt.h> -#include <QtCore/private/qcoreapplication_p.h> -#include <QtCore/private/qeventdispatcher_winrt_p.h> - -#include <wrl.h> -#include <windows.system.threading.h> -#include <windows.system.threading.core.h> -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::System::Threading; -using namespace ABI::Windows::System::Threading::Core; - -#ifndef QT_NO_THREAD -QT_BEGIN_NAMESPACE - -static WorkItemPriority nativePriority(QThread::Priority priority) -{ - switch (priority) { - default: - case QThread::NormalPriority: - return WorkItemPriority_Normal; - case QThread::IdlePriority: - case QThread::LowestPriority: - case QThread::LowPriority: - return WorkItemPriority_Low; - case QThread::HighPriority: - case QThread::HighestPriority: - case QThread::TimeCriticalPriority: - return WorkItemPriority_High; - } -} - -class QWinRTThreadGlobal -{ -public: - QWinRTThreadGlobal() - { - HRESULT hr; - - hr = RoGetActivationFactory( - HString::MakeReference(RuntimeClass_Windows_System_Threading_Core_PreallocatedWorkItem).Get(), - IID_PPV_ARGS(&workItemFactory)); - Q_ASSERT_SUCCEEDED(hr); - - hr = RoGetActivationFactory( - HString::MakeReference(RuntimeClass_Windows_System_Threading_Core_SignalNotifier).Get(), - IID_PPV_ARGS(¬ifierFactory)); - Q_ASSERT_SUCCEEDED(hr); - - QString eventName = QUuid::createUuid().toString(); - dispatchEvent = CreateEventEx(NULL, reinterpret_cast<LPCWSTR>(eventName.utf16()), 0, EVENT_ALL_ACCESS); - - hr = notifierFactory->AttachToEvent( - HStringReference(reinterpret_cast<LPCWSTR>(eventName.utf16())).Get(), - Callback<ISignalHandler>(this, &QWinRTThreadGlobal::dispatch).Get(), ¬ifier); - Q_ASSERT_SUCCEEDED(hr); - hr = notifier->Enable(); - Q_ASSERT_SUCCEEDED(hr); - } - - ~QWinRTThreadGlobal() - { - CloseHandle(dispatchEvent); - } - - void dispatch() - { - SetEvent(dispatchEvent); - } - - void push(QThreadPrivate *d) - { - threads.append(d); - } - -private: - HRESULT dispatch(ISignalNotifier *notifier, boolean timedOut) - { - Q_UNUSED(timedOut); - notifier->Enable(); - if (threads.isEmpty()) - return S_OK; - - QThreadPrivate *thread = threads.takeFirst(); - ComPtr<IPreallocatedWorkItem> workItem; - HRESULT hr = workItemFactory->CreateWorkItemWithPriority( - Callback<IWorkItemHandler>(thread, &QThreadPrivate::start).Get(), - nativePriority(thread->priority), &workItem); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to create thread work item"); - thread->finish(); - return hr; - } - - hr = workItem->RunAsync(&thread->handle); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to run work item"); - thread->finish(); - return hr; - } - - return S_OK; - } - - HANDLE dispatchEvent; - ComPtr<ISignalNotifier> notifier; - ComPtr<ISignalNotifierStatics> notifierFactory; - ComPtr<IPreallocatedWorkItemFactory> workItemFactory; - - QList<QThreadPrivate *> threads; -}; -Q_GLOBAL_STATIC(QWinRTThreadGlobal, g) - -/************************************************************************** - ** QThreadData - *************************************************************************/ - -__declspec(thread) static QThreadData *qt_current_thread_data = 0; - -void QThreadData::clearCurrentThreadData() -{ - qt_current_thread_data = 0; -} - -QThreadData *QThreadData::current(bool createIfNecessary) -{ - static bool winmainThread = true; - QThreadData *threadData = qt_current_thread_data; - if (!threadData && createIfNecessary) { - threadData = new QThreadData; - // This needs to be called prior to new AdoptedThread() to - // avoid recursion. - qt_current_thread_data = threadData; - QT_TRY { - threadData->thread = new QAdoptedThread(threadData); - } QT_CATCH(...) { - qt_current_thread_data = 0; - threadData->deref(); - threadData = 0; - QT_RETHROW; - } - threadData->deref(); - threadData->isAdopted = true; - threadData->threadId = reinterpret_cast<Qt::HANDLE>(GetCurrentThreadId()); - - if (!QCoreApplicationPrivate::theMainThread && !winmainThread) - QCoreApplicationPrivate::theMainThread = threadData->thread; - - if (winmainThread) { - g->dispatch(); - threadData->thread->d_func()->createEventDispatcher(threadData); - winmainThread = false; - } - } - - return threadData; -} - -void QAdoptedThread::init() -{ - Q_D(QThread); - - d->handle = Q_NULLPTR; - d->id = 0; -} - -/************************************************************************** - ** QThreadPrivate - *************************************************************************/ - -#endif // QT_NO_THREAD - -void QThreadPrivate::createEventDispatcher(QThreadData *data) -{ - QEventDispatcherWinRT *eventDispatcher = new QEventDispatcherWinRT; - data->eventDispatcher.storeRelease(eventDispatcher); - eventDispatcher->startingUp(); -} - -#ifndef QT_NO_THREAD - -HRESULT QThreadPrivate::start(IAsyncAction *) -{ - Q_Q(QThread); - - qt_current_thread_data = data; - id = GetCurrentThreadId(); - data->threadId = reinterpret_cast<Qt::HANDLE>(id); - QThread::setTerminationEnabled(false); - - { - QMutexLocker locker(&mutex); - data->quitNow = exited; - } - - if (data->eventDispatcher.load()) - data->eventDispatcher.load()->startingUp(); - else - createEventDispatcher(data); - - running = true; - emit q->started(QThread::QPrivateSignal()); - - QThread::setTerminationEnabled(true); - - q->run(); - - finish(); - - return S_OK; -} - -void QThreadPrivate::finish(bool lockAnyway) -{ - Q_Q(QThread); - - QMutexLocker locker(lockAnyway ? &mutex : 0); - isInFinish = true; - priority = QThread::InheritPriority; - void **tls_data = reinterpret_cast<void **>(&data->tls); - locker.unlock(); - emit q->finished(QThread::QPrivateSignal()); - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QThreadStorageData::finish(tls_data); - locker.relock(); - - QAbstractEventDispatcher *eventDispatcher = data->eventDispatcher.load(); - if (eventDispatcher) { - data->eventDispatcher = 0; - locker.unlock(); - eventDispatcher->closingDown(); - delete eventDispatcher; - locker.relock(); - } - - running = false; - finished = true; - isInFinish = false; - interruptionRequested = false; - - if (!waiters) { - if (handle) - handle->Release(); - handle = Q_NULLPTR; - } - - id = 0; -} - -/************************************************************************** - ** QThread - *************************************************************************/ - -Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW -{ - return reinterpret_cast<Qt::HANDLE>(GetCurrentThreadId()); -} - -int QThread::idealThreadCount() Q_DECL_NOTHROW -{ - SYSTEM_INFO sysinfo; - GetNativeSystemInfo(&sysinfo); - return sysinfo.dwNumberOfProcessors; -} - -void QThread::yieldCurrentThread() -{ - msleep(1); -} - -void QThread::sleep(unsigned long secs) -{ - msleep(secs * 1000); -} - -void QThread::msleep(unsigned long msecs) -{ - WaitForSingleObjectEx(GetCurrentThread(), msecs, FALSE); -} - -void QThread::usleep(unsigned long usecs) -{ - msleep((usecs / 1000) + 1); -} - -void QThread::start(Priority priority) -{ - Q_D(QThread); - QMutexLocker locker(&d->mutex); - - if (d->isInFinish) { - locker.unlock(); - wait(); - locker.relock(); - } - - if (d->running) - return; - - d->finished = false; - d->exited = false; - d->returnCode = 0; - d->interruptionRequested = false; - d->priority = priority == QThread::InheritPriority ? currentThread()->priority() : priority; - g->push(d); - g->dispatch(); - - locker.unlock(); - while (!d->running && !d->finished) { - QAbstractEventDispatcher *eventDispatcher = QThread::currentThread()->eventDispatcher(); - if (eventDispatcher) - eventDispatcher->processEvents(QEventLoop::AllEvents); - else - yieldCurrentThread(); - } -} - -void QThread::terminate() -{ - Q_D(QThread); - QMutexLocker locker(&d->mutex); - if (!d->running) - return; - if (!d->terminationEnabled) { - d->terminatePending = true; - return; - } - - if (d->handle) { - ComPtr<IAsyncInfo> info; - HRESULT hr = d->handle->QueryInterface(IID_PPV_ARGS(&info)); - Q_ASSERT_SUCCEEDED(hr); - hr = info->Cancel(); - if (FAILED(hr)) - qErrnoWarning(hr, "Failed to cancel thread action"); - } - - d->finish(false); -} - -bool QThread::wait(unsigned long time) -{ - Q_D(QThread); - QMutexLocker locker(&d->mutex); - - if (d->id == GetCurrentThreadId()) { - qWarning("QThread::wait: Thread tried to wait on itself"); - return false; - } - if (d->finished || !d->running) - return true; - - ++d->waiters; - locker.mutex()->unlock(); - - // Alternatively, we could check the handle - bool ret = false; - if (!d->finished) { - QElapsedTimer timer; - timer.start(); - while (timer.elapsed() < time && !d->finished) - yieldCurrentThread(); - - ret = d->finished; - } - - locker.mutex()->lock(); - --d->waiters; - - if (ret && !d->finished) { - // thread was terminated by someone else - - d->finish(false); - } - - if (d->finished && !d->waiters) { - if (d->handle) - d->handle->Release(); - d->handle = Q_NULLPTR; - } - - return ret; -} - -void QThread::setTerminationEnabled(bool enabled) -{ - QThread *thr = currentThread(); - Q_ASSERT_X(thr != 0, "QThread::setTerminationEnabled()", - "Current thread was not started with QThread."); - QThreadPrivate *d = thr->d_func(); - QMutexLocker locker(&d->mutex); - d->terminationEnabled = enabled; - if (enabled && d->terminatePending) { - d->finish(false); - locker.unlock(); // don't leave the mutex locked! - } -} - -// Caller must hold the mutex -void QThreadPrivate::setPriority(QThread::Priority threadPriority) -{ - if (running) - qWarning("WinRT threads can't change priority while running."); - - priority = threadPriority; -} - -QT_END_NAMESPACE -#endif // QT_NO_THREAD diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h index b1ca808a9930811f10908c1b4eb58dfc8bfb2fbc..95b41a0417b5b34b0bfbc2ba999f050f7303d067 100644 --- a/src/corelib/thread/qthreadpool.h +++ b/src/corelib/thread/qthreadpool.h @@ -55,7 +55,7 @@ class Q_CORE_EXPORT QThreadPool : public QObject friend class QFutureInterfaceBase; public: - QThreadPool(QObject *parent = 0); + QThreadPool(QObject *parent = Q_NULLPTR); ~QThreadPool(); static QThreadPool *globalInstance(); diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp index ef8330570ee27a8d48be1a35dbf81dd5d7f11d64..3ea34461d32e47aeeef5de91cf9b11346e94f55b 100644 --- a/src/corelib/thread/qwaitcondition_win.cpp +++ b/src/corelib/thread/qwaitcondition_win.cpp @@ -109,10 +109,10 @@ bool QWaitConditionPrivate::wait(QWaitConditionEvent *wce, unsigned long time) { // wait for the event bool ret = false; -#ifndef Q_OS_WINRT - switch (WaitForSingleObject(wce->event, time)) { -#else +#ifndef Q_OS_WINCE switch (WaitForSingleObjectEx(wce->event, time, FALSE)) { +#else + switch (WaitForSingleObject(wce->event, time)) { #endif default: break; diff --git a/src/corelib/thread/thread.pri b/src/corelib/thread/thread.pri index 2e027c8e210d9e76f4ac212d1471a4afc300c8d2..3c1ddd984ab85cc8a9ec5eff54b40aebc0b472f8 100644 --- a/src/corelib/thread/thread.pri +++ b/src/corelib/thread/thread.pri @@ -50,11 +50,6 @@ win32:SOURCES += thread/qmutex_win.cpp \ thread/qthread_win.cpp \ thread/qwaitcondition_win.cpp -winrt { - SOURCES -= thread/qthread_win.cpp - SOURCES += thread/qthread_winrt.cpp -} - integrity:SOURCES += thread/qmutex_unix.cpp \ thread/qthread_unix.cpp \ thread/qwaitcondition_unix.cpp diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index ef15fae83a7a03fa59a02b8605375c7753bfbeea..d9519745b06591c0be9d7eb80baed670803ba593 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -103,7 +103,11 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment, quintptr data = (quintptr(header) + sizeof(QArrayData) + alignment - 1) & ~(alignment - 1); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) header->ref.atomic.store(bool(!(options & Unsharable))); +#else + header->ref.atomic.store(1); +#endif header->size = 0; header->alloc = capacity; header->capacityReserved = bool(options & CapacityReserved); diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h index df35a1cb62e20f5b4c98af7dabd3ef390a10b25a..865bd4325d5e8a7e8e79b047a987b2c78cd96cf4 100644 --- a/src/corelib/tools/qarraydata.h +++ b/src/corelib/tools/qarraydata.h @@ -132,7 +132,7 @@ struct QTypedArrayData typedef T *pointer; typedef T &reference; - inline iterator() : i(0) {} + inline iterator() : i(Q_NULLPTR) {} inline iterator(T *n) : i(n) {} inline iterator(const iterator &o): i(o.i){} // #### Qt 6: remove, the implicit version is fine inline T &operator*() const { return *i; } @@ -166,7 +166,7 @@ struct QTypedArrayData typedef const T *pointer; typedef const T &reference; - inline const_iterator() : i(0) {} + inline const_iterator() : i(Q_NULLPTR) {} inline const_iterator(const T *n) : i(n) {} inline const_iterator(const const_iterator &o): i(o.i) {} // #### Qt 6: remove, the default version is fine inline explicit const_iterator(const iterator &o): i(o.i) {} @@ -249,11 +249,13 @@ struct QTypedArrayData return allocate(/* capacity */ 0); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) static QTypedArrayData *unsharableEmpty() { Q_STATIC_ASSERT(sizeof(QTypedArrayData) == sizeof(QArrayData)); return allocate(/* capacity */ 0, Unsharable); } +#endif }; template <class T, size_t N> diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h index 103eb073a9a1e5ca622cf06ce3286c61fef11455..9804d2c2d57ef546747944ce51fbd143fb1d264f 100644 --- a/src/corelib/tools/qarraydatapointer.h +++ b/src/corelib/tools/qarraydatapointer.h @@ -46,7 +46,7 @@ private: typedef QArrayDataOps<T> DataOps; public: - QArrayDataPointer() + QArrayDataPointer() Q_DECL_NOTHROW : d(Data::sharedNull()) { } @@ -77,15 +77,16 @@ public: } #ifdef Q_COMPILER_RVALUE_REFS - QArrayDataPointer(QArrayDataPointer &&other) + QArrayDataPointer(QArrayDataPointer &&other) Q_DECL_NOTHROW : d(other.d) { other.d = Data::sharedNull(); } - QArrayDataPointer &operator=(QArrayDataPointer &&other) + QArrayDataPointer &operator=(QArrayDataPointer &&other) Q_DECL_NOTHROW { - this->swap(other); + QArrayDataPointer moved(std::move(other)); + this->swap(moved); return *this; } #endif @@ -143,7 +144,7 @@ public: bool isSharable() const { return d->isSharable(); } #endif - void swap(QArrayDataPointer &other) + void swap(QArrayDataPointer &other) Q_DECL_NOTHROW { qSwap(d, other.d); } diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 36c1f42995262c0fcd3ac2094e47ffe036630e93..0434cebc15cd39a618c07feaa85819aab8701082 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -41,6 +41,7 @@ #include "qlocale_p.h" #include "qstringalgorithms_p.h" #include "qscopedpointer.h" +#include "qbytearray_p.h" #include <qdatastream.h> #include <qmath.h> @@ -123,8 +124,8 @@ int qFindByteArray( int qAllocMore(int alloc, int extra) Q_DECL_NOTHROW { - Q_ASSERT(alloc >= 0 && extra >= 0); - Q_ASSERT_X(uint(alloc) <= QByteArray::MaxSize, "qAllocMore", "Requested size is too large!"); + Q_ASSERT(alloc >= 0 && extra >= 0 && extra <= MaxAllocSize); + Q_ASSERT_X(alloc <= MaxAllocSize - extra, "qAllocMore", "Requested size is too large!"); unsigned nalloc = qNextPowerOfTwo(alloc + extra); @@ -837,16 +838,6 @@ static inline char qToLower(char c) \sa QString, QBitArray */ -/*! - \variable QByteArray::MaxSize - \internal - \since 5.4 - - The maximum size of a QByteArray (including a '\0' terminator), in bytes. - Also applies to the maximum storage size of QString and QVector, though - not the number of elements. -*/ - /*! \enum QByteArray::Base64Option \since 5.2 @@ -928,6 +919,52 @@ static inline char qToLower(char c) \sa constBegin(), end() */ +/*! \fn QByteArray::reverse_iterator QByteArray::rbegin() + \since 5.6 + + Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to the first + character in the byte-array, in reverse order. + + \sa begin(), crbegin(), rend() +*/ + +/*! \fn QByteArray::const_reverse_iterator QByteArray::rbegin() const + \since 5.6 + \overload +*/ + +/*! \fn QByteArray::const_reverse_iterator QByteArray::crbegin() const + \since 5.6 + + Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to the first + character in the byte-array, in reverse order. + + \sa begin(), rbegin(), rend() +*/ + +/*! \fn QByteArray::reverse_iterator QByteArray::rend() + \since 5.6 + + Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to one past + the last character in the byte-array, in reverse order. + + \sa end(), crend(), rbegin() +*/ + +/*! \fn QByteArray::const_reverse_iterator QByteArray::rend() const + \since 5.6 + \overload +*/ + +/*! \fn QByteArray::const_reverse_iterator QByteArray::crend() const + \since 5.6 + + Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to one + past the last character in the byte-array, in reverse order. + + \sa end(), rend(), rbegin() +*/ + /*! \fn void QByteArray::push_back(const QByteArray &other) This function is provided for STL compatibility. It is equivalent @@ -1575,7 +1612,7 @@ void QByteArray::reallocData(uint alloc, Data::AllocationOptions options) d = x; } else { if (options & Data::Grow) { - if (alloc > uint(MaxAllocSize) - uint(sizeof(Data))) + if (alloc > MaxByteArraySize) qBadAlloc(); alloc = qAllocMore(alloc, sizeof(Data)); } @@ -4490,11 +4527,33 @@ QByteArray QByteArray::toPercentEncoding(const QByteArray &exclude, const QByteA */ /*! \typedef QByteArray::const_iterator - \internal + + This typedef provides an STL-style const iterator for QByteArray. + + \sa QByteArray::const_reverse_iterator, QByteArray::iterator */ /*! \typedef QByteArray::iterator - \internal + + This typedef provides an STL-style non-const iterator for QByteArray. + + \sa QByteArray::reverse_iterator, QByteArray::const_iterator +*/ + +/*! \typedef QByteArray::const_reverse_iterator + \since 5.6 + + This typedef provides an STL-style const reverse iterator for QByteArray. + + \sa QByteArray::reverse_iterator, QByteArray::const_iterator +*/ + +/*! \typedef QByteArray::reverse_iterator + \since 5.6 + + This typedef provides an STL-style non-const reverse iterator for QByteArray. + + \sa QByteArray::const_reverse_iterator, QByteArray::iterator */ /*! \typedef QByteArray::size_type diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 6d14cd513156cc59c49ec7d9b70e4131acbc3865..f0032227e8709b27ae377a4f9564ae0d691773e6 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -43,6 +43,7 @@ #include <stdarg.h> #include <string> +#include <iterator> #ifdef truncate #error qbytearray.h must be included before any header file that defines truncate @@ -162,9 +163,6 @@ private: typedef QTypedArrayData<char> Data; public: - // undocumented: - static const quint64 MaxSize = (1 << 30) - sizeof(Data); - enum Base64Option { Base64Encoding = 0, Base64UrlEncoding = 1, @@ -338,16 +336,16 @@ public: inline QT_ASCII_CAST_WARN bool operator>=(const QString &s2) const; #endif - short toShort(bool *ok = 0, int base = 10) const; - ushort toUShort(bool *ok = 0, int base = 10) const; - int toInt(bool *ok = 0, int base = 10) const; - uint toUInt(bool *ok = 0, int base = 10) const; - long toLong(bool *ok = 0, int base = 10) const; - ulong toULong(bool *ok = 0, int base = 10) const; - qlonglong toLongLong(bool *ok = 0, int base = 10) const; - qulonglong toULongLong(bool *ok = 0, int base = 10) const; - float toFloat(bool *ok = 0) const; - double toDouble(bool *ok = 0) const; + short toShort(bool *ok = Q_NULLPTR, int base = 10) const; + ushort toUShort(bool *ok = Q_NULLPTR, int base = 10) const; + int toInt(bool *ok = Q_NULLPTR, int base = 10) const; + uint toUInt(bool *ok = Q_NULLPTR, int base = 10) const; + long toLong(bool *ok = Q_NULLPTR, int base = 10) const; + ulong toULong(bool *ok = Q_NULLPTR, int base = 10) const; + qlonglong toLongLong(bool *ok = Q_NULLPTR, int base = 10) const; + qulonglong toULongLong(bool *ok = Q_NULLPTR, int base = 10) const; + float toFloat(bool *ok = Q_NULLPTR) const; + double toDouble(bool *ok = Q_NULLPTR) const; QByteArray toBase64(Base64Options options) const; QByteArray toBase64() const; // ### Qt6 merge with previous QByteArray toHex() const; @@ -393,14 +391,22 @@ public: typedef const char *const_iterator; typedef iterator Iterator; typedef const_iterator ConstIterator; - iterator begin(); - const_iterator begin() const; - const_iterator cbegin() const; - const_iterator constBegin() const; - iterator end(); - const_iterator end() const; - const_iterator cend() const; - const_iterator constEnd() const; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + inline iterator begin(); + inline const_iterator begin() const; + inline const_iterator cbegin() const; + inline const_iterator constBegin() const; + inline iterator end(); + inline const_iterator end() const; + inline const_iterator cend() const; + inline const_iterator constEnd() const; + reverse_iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } + const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } // stl compatibility typedef int size_type; diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h b/src/corelib/tools/qbytearray_p.h similarity index 66% rename from src/platformsupport/eglconvenience/qeglplatformscreen_p.h rename to src/corelib/tools/qbytearray_p.h index 4a987f6860ea149b98cbe9f6523a2be6244e7c91..78c667aa900d653ca6e66b1307319d9ee325296a 100644 --- a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h +++ b/src/corelib/tools/qbytearray_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL21$ ** Commercial License Usage @@ -31,49 +31,31 @@ ** ****************************************************************************/ -#ifndef QEGLPLATFORMSCREEN_H -#define QEGLPLATFORMSCREEN_H +#ifndef QBYTEARRAY_P_H +#define QBYTEARRAY_P_H // // W A R N I N G // ------------- // -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to // version without notice, or even be removed. // // We mean it. // -#include <QtCore/QList> -#include <QtCore/QPoint> -#include <QtCore/qtextstream.h> -#include <qpa/qplatformscreen.h> -#include <EGL/egl.h> +#include <QtCore/qbytearray.h> +#include <QtCore/qtypetraits.h> +#include "qtools_p.h" QT_BEGIN_NAMESPACE -class QOpenGLContext; -class QWindow; -class QEGLPlatformWindow; - -class QEGLPlatformScreen : public QPlatformScreen -{ -public: - QEGLPlatformScreen(EGLDisplay dpy); - ~QEGLPlatformScreen(); - - EGLDisplay display() const { return m_dpy; } - - void handleCursorMove(const QPoint &pos); - - QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE; - -private: - EGLDisplay m_dpy; - QWindow *m_pointerWindow; +enum { + // Define as enum to force inlining. Don't expose MaxAllocSize in a public header. + MaxByteArraySize = MaxAllocSize - sizeof(QtPrivate::remove_pointer<QByteArray::DataPtr>::type) }; QT_END_NAMESPACE -#endif // QEGLPLATFORMSCREEN_H +#endif // QBYTEARRAY_P_H diff --git a/src/corelib/tools/qbytearraylist.h b/src/corelib/tools/qbytearraylist.h index f8539ca07a35dd13c890d1bb8b1ac45c3629bfd4..8b832b77601bebde600b1cbe4f6cb111959a88d0 100644 --- a/src/corelib/tools/qbytearraylist.h +++ b/src/corelib/tools/qbytearraylist.h @@ -61,7 +61,7 @@ protected: #endif public: inline QByteArray join() const - { return QtPrivate::QByteArrayList_join(self(), 0, 0); } + { return QtPrivate::QByteArrayList_join(self(), Q_NULLPTR, 0); } inline QByteArray join(const QByteArray &sep) const { return QtPrivate::QByteArrayList_join(self(), sep.constData(), sep.size()); } inline QByteArray join(char sep) const diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp index 56904c91d7d2e5ea90643c22b9f39ac212161c70..e6c246e8e68d3cd670adb966ff4d5f46f59cc365 100644 --- a/src/corelib/tools/qchar.cpp +++ b/src/corelib/tools/qchar.cpp @@ -178,6 +178,7 @@ QT_BEGIN_NAMESPACE \value Unicode_6_1 Version 6.1 \value Unicode_6_2 Version 6.2 \value Unicode_6_3 Version 6.3 Since Qt 5.3 + \value Unicode_7_0 Version 7.0 Since Qt 5.5 \value Unicode_Unassigned The value is not assigned to any character in version 6.3 of Unicode. diff --git a/src/corelib/tools/qcollator.h b/src/corelib/tools/qcollator.h index e1fa1612575c0c8a6e958710786ad06e79ac2105..57133165c4f297bad764aeb41a693554640d01f9 100644 --- a/src/corelib/tools/qcollator.h +++ b/src/corelib/tools/qcollator.h @@ -83,7 +83,7 @@ public: QCollator &operator=(const QCollator &); #ifdef Q_COMPILER_RVALUE_REFS QCollator(QCollator &&other) Q_DECL_NOTHROW - : d(other.d) { other.d = 0; } + : d(other.d) { other.d = Q_NULLPTR; } QCollator &operator=(QCollator &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif diff --git a/src/corelib/tools/qcommandlineoption.cpp b/src/corelib/tools/qcommandlineoption.cpp index 51723f4a576f54dfad641f34e8bdd29d1b9c5ac3..eb50cee5bb8f31e9aae3a3103aa1a84efb60e1ad 100644 --- a/src/corelib/tools/qcommandlineoption.cpp +++ b/src/corelib/tools/qcommandlineoption.cpp @@ -41,11 +41,19 @@ QT_BEGIN_NAMESPACE class QCommandLineOptionPrivate : public QSharedData { public: - inline QCommandLineOptionPrivate() - : hidden(false) + Q_NEVER_INLINE + explicit QCommandLineOptionPrivate(const QString &name) + : names(removeInvalidNames(QStringList(name))), + hidden(false) { } - void setNames(const QStringList &nameList); + Q_NEVER_INLINE + explicit QCommandLineOptionPrivate(const QStringList &names) + : names(removeInvalidNames(names)), + hidden(false) + { } + + static QStringList removeInvalidNames(QStringList nameList); //! The list of names used for this option. QStringList names; @@ -102,9 +110,8 @@ public: \sa setDescription(), setValueName(), setDefaultValues() */ QCommandLineOption::QCommandLineOption(const QString &name) - : d(new QCommandLineOptionPrivate) + : d(new QCommandLineOptionPrivate(name)) { - d->setNames(QStringList(name)); } /*! @@ -121,9 +128,8 @@ QCommandLineOption::QCommandLineOption(const QString &name) \sa setDescription(), setValueName(), setDefaultValues() */ QCommandLineOption::QCommandLineOption(const QStringList &names) - : d(new QCommandLineOptionPrivate) + : d(new QCommandLineOptionPrivate(names)) { - d->setNames(names); } /*! @@ -152,9 +158,8 @@ QCommandLineOption::QCommandLineOption(const QStringList &names) QCommandLineOption::QCommandLineOption(const QString &name, const QString &description, const QString &valueName, const QString &defaultValue) - : d(new QCommandLineOptionPrivate) + : d(new QCommandLineOptionPrivate(name)) { - d->setNames(QStringList(name)); setValueName(valueName); setDescription(description); setDefaultValue(defaultValue); @@ -189,9 +194,8 @@ QCommandLineOption::QCommandLineOption(const QString &name, const QString &descr QCommandLineOption::QCommandLineOption(const QStringList &names, const QString &description, const QString &valueName, const QString &defaultValue) - : d(new QCommandLineOptionPrivate) + : d(new QCommandLineOptionPrivate(names)) { - d->setNames(names); setValueName(valueName); setDescription(description); setDefaultValue(defaultValue); @@ -240,29 +244,47 @@ QStringList QCommandLineOption::names() const return d->names; } -void QCommandLineOptionPrivate::setNames(const QStringList &nameList) -{ - QStringList newNames; - newNames.reserve(nameList.size()); - if (nameList.isEmpty()) - qWarning("QCommandLineOption: Options must have at least one name"); - foreach (const QString &name, nameList) { - if (name.isEmpty()) { - qWarning("QCommandLineOption: Option names cannot be empty"); - } else { +namespace { + struct IsInvalidName + { + typedef bool result_type; + typedef QString argument_type; + + Q_NEVER_INLINE + result_type operator()(const QString &name) const Q_DECL_NOEXCEPT + { + if (Q_UNLIKELY(name.isEmpty())) + return warn("be empty"); + const QChar c = name.at(0); - if (c == QLatin1Char('-')) - qWarning("QCommandLineOption: Option names cannot start with a '-'"); - else if (c == QLatin1Char('/')) - qWarning("QCommandLineOption: Option names cannot start with a '/'"); - else if (name.contains(QLatin1Char('='))) - qWarning("QCommandLineOption: Option names cannot contain a '='"); - else - newNames.append(name); + if (Q_UNLIKELY(c == QLatin1Char('-'))) + return warn("start with a '-'"); + if (Q_UNLIKELY(c == QLatin1Char('/'))) + return warn("start with a '/'"); + if (Q_UNLIKELY(name.contains(QLatin1Char('=')))) + return warn("contain a '='"); + + return false; } - } - // commit - names.swap(newNames); + + Q_NEVER_INLINE + static bool warn(const char *what) Q_DECL_NOEXCEPT + { + qWarning("QCommandLineOption: Option names cannot %s", what); + return true; + } + }; +} // unnamed namespace + +// static +QStringList QCommandLineOptionPrivate::removeInvalidNames(QStringList nameList) +{ + if (Q_UNLIKELY(nameList.isEmpty())) + qWarning("QCommandLineOption: Options must have at least one name"); + else + nameList.erase(std::remove_if(nameList.begin(), nameList.end(), IsInvalidName()), + nameList.end()); + return qMove(nameList); } /*! diff --git a/src/corelib/tools/qcommandlineoption.h b/src/corelib/tools/qcommandlineoption.h index 85fc5ca6dd337b98e0ef7573c98bb8b58fc09ba9..828522cbc52c58a1a39cf0c964c065c19716f6e8 100644 --- a/src/corelib/tools/qcommandlineoption.h +++ b/src/corelib/tools/qcommandlineoption.h @@ -58,11 +58,10 @@ public: QCommandLineOption &operator=(const QCommandLineOption &other); #ifdef Q_COMPILER_RVALUE_REFS - inline QCommandLineOption &operator=(QCommandLineOption &&other) - { qSwap(d, other.d); return *this; } + QCommandLineOption &operator=(QCommandLineOption &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif - inline void swap(QCommandLineOption &other) + void swap(QCommandLineOption &other) Q_DECL_NOTHROW { qSwap(d, other.d); } QStringList names() const; diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp index 4cc3a2c2932523c1a48d77905c19cea254ac06d6..20e0688f45f8549edbec160b30ab04b460a5dff5 100644 --- a/src/corelib/tools/qcommandlineparser.cpp +++ b/src/corelib/tools/qcommandlineparser.cpp @@ -116,6 +116,7 @@ public: //! True if parse() needs to be called bool needsParsing; }; +Q_DECLARE_TYPEINFO(QCommandLineParserPrivate::PositionalArgumentDefinition, Q_MOVABLE_TYPE); QStringList QCommandLineParserPrivate::aliases(const QString &optionName) const { diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index 78ec2b156a915cb48087e7efe348f80d842df358..c44f7f8fee880cf5b047276edff37a2a98573b07 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -59,7 +59,7 @@ public: StandaloneFormat }; private: - Q_DECL_CONSTEXPR QDate(qint64 julianDay) : jd(julianDay) {} + explicit Q_DECL_CONSTEXPR QDate(qint64 julianDay) : jd(julianDay) {} public: Q_DECL_CONSTEXPR QDate() : jd(nullJd()) {} QDate(int y, int m, int d); @@ -74,7 +74,7 @@ public: int dayOfYear() const; int daysInMonth() const; int daysInYear() const; - int weekNumber(int *yearNum = 0) const; + int weekNumber(int *yearNum = Q_NULLPTR) const; #ifndef QT_NO_TEXTDATE static QString shortMonthName(int month, MonthNameType type = DateFormat); @@ -138,7 +138,7 @@ Q_DECLARE_TYPEINFO(QDate, Q_MOVABLE_TYPE); class Q_CORE_EXPORT QTime { - Q_DECL_CONSTEXPR QTime(int ms) : mds(ms) + explicit Q_DECL_CONSTEXPR QTime(int ms) : mds(ms) #if defined(Q_OS_WINCE) , startTick(NullTime) #endif @@ -222,9 +222,12 @@ public: QDateTime(const QDateTime &other); ~QDateTime(); +#ifdef Q_COMPILER_RVALUE_REFS + QDateTime &operator=(QDateTime &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QDateTime &operator=(const QDateTime &other); - inline void swap(QDateTime &other) { qSwap(d, other.d); } + void swap(QDateTime &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool isNull() const; bool isValid() const; diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h index 9457e35ad5dd539e63e00612e1bb462eabebe7a1..a1cf8f283fbbd4b0eef3b2303b6554021ac79b1c 100644 --- a/src/corelib/tools/qdatetimeparser_p.h +++ b/src/corelib/tools/qdatetimeparser_p.h @@ -252,6 +252,7 @@ public: Qt::TimeSpec spec; // spec if used by QDateTimeEdit Context context; }; +Q_DECLARE_TYPEINFO(QDateTimeParser::SectionNode, Q_PRIMITIVE_TYPE); Q_CORE_EXPORT bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::SectionNode &s2); diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index 1bd9c5ebb92b86e85df7598e9d0aabfadbd7f20e..22f5c65a40bc43b9d50e434a51b6b88fc2ad5d81 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -340,6 +340,7 @@ struct TCBPoint { qFuzzyCompare(_b, other._b); } }; +Q_DECLARE_TYPEINFO(TCBPoint, Q_PRIMITIVE_TYPE); typedef QVector<TCBPoint> TCBPoints; @@ -1219,6 +1220,7 @@ QVector<QPointF> static inline tcbToBezier(const TCBPoints &tcbPoints) { const int count = tcbPoints.count(); QVector<QPointF> bezierPoints; + bezierPoints.reserve(3 * (count - 1)); for (int i = 1; i < count; i++) { const qreal t_0 = tcbPoints.at(i - 1)._t; diff --git a/src/corelib/tools/qeasingcurve.h b/src/corelib/tools/qeasingcurve.h index 4065de1366345cc2d1b951f9b6ff60b5c1e1d293..d04d5ef30a709b899271071ef68fd030b75a8b0c 100644 --- a/src/corelib/tools/qeasingcurve.h +++ b/src/corelib/tools/qeasingcurve.h @@ -75,7 +75,7 @@ public: QEasingCurve &operator=(const QEasingCurve &other) { if ( this != &other ) { QEasingCurve copy(other); swap(copy); } return *this; } #ifdef Q_COMPILER_RVALUE_REFS - QEasingCurve(QEasingCurve &&other) : d_ptr(other.d_ptr) { other.d_ptr = 0; } + QEasingCurve(QEasingCurve &&other) : d_ptr(other.d_ptr) { other.d_ptr = Q_NULLPTR; } QEasingCurve &operator=(QEasingCurve &&other) { qSwap(d_ptr, other.d_ptr); return *this; } #endif diff --git a/src/corelib/tools/qelapsedtimer_win.cpp b/src/corelib/tools/qelapsedtimer_win.cpp index eab2f8ef6cd3b38fee1b5ae7036c4add4ceb08b9..b80c23cf8f932af01aba9b1adf75a119c50d590e 100644 --- a/src/corelib/tools/qelapsedtimer_win.cpp +++ b/src/corelib/tools/qelapsedtimer_win.cpp @@ -117,7 +117,7 @@ static quint64 getTickCount() #endif // Q_OS_WINRT } -int qt_msectime() +quint64 qt_msectime() { return ticksToNanoseconds(getTickCount()) / 1000000; } diff --git a/src/corelib/tools/qharfbuzz.cpp b/src/corelib/tools/qharfbuzz.cpp index afc8b23473443eb6d8b588a262870c3a143c6c19..fa279949ea0b9ec97684322842e37d4f9e27fe6d 100644 --- a/src/corelib/tools/qharfbuzz.cpp +++ b/src/corelib/tools/qharfbuzz.cpp @@ -65,6 +65,9 @@ HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch) void (*HB_Library_Resolve(const char *library, int version, const char *symbol))() { #ifdef QT_NO_LIBRARY + Q_UNUSED(library); + Q_UNUSED(version); + Q_UNUSED(symbol); return 0; #else return QLibrary::resolve(QLatin1String(library), version, symbol); diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index a8a461e868c88c8e3e84c01441cf1db75bd6a5ac..87a59c67c8949153755e5ddfcd0e11582a448a51 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -1536,6 +1536,15 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW \sa begin(), constEnd() */ +/*! \fn QHash::key_iterator QHash::keyBegin() const + \since 5.6 + + Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first key + in the hash. + + \sa keyEnd() +*/ + /*! \fn QHash::iterator QHash::end() Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item @@ -1566,6 +1575,15 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW \sa cbegin(), end() */ +/*! \fn QHash::key_iterator QHash::keyEnd() const + \since 5.6 + + Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary + item after the last key in the hash. + + \sa keyBegin() +*/ + /*! \fn QHash::iterator QHash::erase(iterator pos) Removes the (key, value) pair associated with the iterator \a pos @@ -1729,6 +1747,26 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW \internal */ +/*! \typedef QHash::key_iterator::difference_type + \internal +*/ + +/*! \typedef QHash::key_iterator::iterator_category + \internal +*/ + +/*! \typedef QHash::key_iterator::pointer + \internal +*/ + +/*! \typedef QHash::key_iterator::reference + \internal +*/ + +/*! \typedef QHash::key_iterator::value_type + \internal +*/ + /*! \class QHash::iterator \inmodule QtCore \brief The QHash::iterator class provides an STL-style non-const iterator for QHash and QMultiHash. @@ -1802,7 +1840,7 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW while iterators are active on that container. For more information, read \l{Implicit sharing iterator problem}. - \sa QHash::const_iterator, QMutableHashIterator + \sa QHash::const_iterator, QHash::key_iterator, QMutableHashIterator */ /*! \fn QHash::iterator::iterator() @@ -2155,6 +2193,114 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW \sa operator+=(), operator-() */ +/*! \class QHash::key_iterator + \inmodule QtCore + \since 5.6 + \brief The QHash::key_iterator class provides an STL-style const iterator for QHash and QMultiHash keys. + + QHash::key_iterator is essentially the same as QHash::const_iterator + with the difference that operator*() and operator->() return a key + instead of a value. + + For most uses QHash::iterator and QHash::const_iterator should be used, + you can easily access the key by calling QHash::iterator::key(): + + \snippet code/src_corelib_tools_qhash.cpp 27 + + However, to have interoperability between QHash's keys and STL-style + algorithms we need an iterator that dereferences to a key instead + of a value. With QHash::key_iterator we can apply an algorithm to a + range of keys without having to call QHash::keys(), which is inefficient + as it costs one QHash iteration and memory allocation to create a temporary + QList. + + \snippet code/src_corelib_tools_qhash.cpp 28 + + QHash::key_iterator is const, it's not possible to modify the key. + + The default QHash::key_iterator constructor creates an uninitialized + iterator. You must initialize it using a QHash function like + QHash::keyBegin() or QHash::keyEnd(). + + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + + \sa QHash::const_iterator, QHash::iterator +*/ + +/*! \fn const T &QHash::key_iterator::operator*() const + + Returns the current item's key. +*/ + +/*! \fn const T *QHash::key_iterator::operator->() const + + Returns a pointer to the current item's key. +*/ + +/*! \fn bool QHash::key_iterator::operator==(key_iterator other) + + Returns \c true if \a other points to the same item as this + iterator; otherwise returns \c false. + + \sa operator!=() +*/ + +/*! \fn bool QHash::key_iterator::operator!=(key_iterator other) + + Returns \c true if \a other points to a different item than this + iterator; otherwise returns \c false. + + \sa operator==() +*/ + +/*! + \fn QHash::key_iterator &QHash::key_iterator::operator++() + + The prefix ++ operator (\c{++i}) advances the iterator to the + next item in the hash and returns an iterator to the new current + item. + + Calling this function on QHash::keyEnd() leads to undefined results. + + \sa operator--() +*/ + +/*! \fn QHash::key_iterator QHash::key_iterator::operator++(int) + + \overload + + The postfix ++ operator (\c{i++}) advances the iterator to the + next item in the hash and returns an iterator to the previous + item. +*/ + +/*! \fn QHash::key_iterator &QHash::key_iterator::operator--() + + The prefix -- operator (\c{--i}) makes the preceding item + current and returns an iterator pointing to the new current item. + + Calling this function on QHash::keyBegin() leads to undefined + results. + + \sa operator++() +*/ + +/*! \fn QHash::key_iterator QHash::key_iterator::operator--(int) + + \overload + + The postfix -- operator (\c{i--}) makes the preceding item + current and returns an iterator pointing to the previous + item. +*/ + +/*! \fn const_iterator QHash::key_iterator::base() const + Returns the underlying const_iterator this key_iterator is based on. +*/ + /*! \fn QDataStream &operator<<(QDataStream &out, const QHash<Key, T>& hash) \relates QHash diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 2080a22e23bc883a658fa74a5a105914d8795334..e367cc00685fd5377e6141ff291511b787b38111 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -249,7 +249,7 @@ public: #ifdef Q_COMPILER_RVALUE_REFS QHash(QHash &&other) Q_DECL_NOTHROW : d(other.d) { other.d = const_cast<QHashData *>(&QHashData::shared_null); } QHash &operator=(QHash &&other) Q_DECL_NOTHROW - { qSwap(d, other.d); return *this; } + { QHash moved(std::move(other)); swap(moved); return *this; } #endif void swap(QHash &other) Q_DECL_NOTHROW { qSwap(d, other.d); } @@ -306,7 +306,7 @@ public: typedef T *pointer; typedef T &reference; - inline iterator() : i(0) { } + inline iterator() : i(Q_NULLPTR) { } explicit inline iterator(void *node) : i(reinterpret_cast<QHashData::Node *>(node)) { } inline const Key &key() const { return concrete(i)->key; } @@ -363,7 +363,7 @@ public: typedef const T *pointer; typedef const T &reference; - inline const_iterator() : i(0) { } + inline const_iterator() : i(Q_NULLPTR) { } explicit inline const_iterator(void *node) : i(reinterpret_cast<QHashData::Node *>(node)) { } #ifdef QT_STRICT_ITERATORS @@ -413,6 +413,31 @@ public: }; friend class const_iterator; + class key_iterator + { + const_iterator i; + + public: + typedef typename const_iterator::iterator_category iterator_category; + typedef typename const_iterator::difference_type difference_type; + typedef Key value_type; + typedef const Key *pointer; + typedef const Key &reference; + + explicit key_iterator(const_iterator o) : i(o) { } + + const Key &operator*() const { return i.key(); } + const Key *operator->() const { return &i.key(); } + bool operator==(key_iterator o) const { return i == o.i; } + bool operator!=(key_iterator o) const { return i != o.i; } + + inline key_iterator &operator++() { ++i; return *this; } + inline key_iterator operator++(int) { return key_iterator(i++);} + inline key_iterator &operator--() { --i; return *this; } + inline key_iterator operator--(int) { return key_iterator(i--); } + const_iterator base() const { return i; } + }; + // STL style inline iterator begin() { detach(); return iterator(d->firstNode()); } inline const_iterator begin() const { return const_iterator(d->firstNode()); } @@ -422,6 +447,9 @@ public: inline const_iterator end() const { return const_iterator(e); } inline const_iterator cend() const { return const_iterator(e); } inline const_iterator constEnd() const { return const_iterator(e); } + inline key_iterator keyBegin() const { return key_iterator(begin()); } + inline key_iterator keyEnd() const { return key_iterator(end()); } + iterator erase(iterator it); // more Qt @@ -451,7 +479,7 @@ public: private: void detach_helper(); void freeData(QHashData *d); - Node **findNode(const Key &key, uint *hp = 0) const; + Node **findNode(const Key &key, uint *hp = Q_NULLPTR) const; Node **findNode(const Key &key, uint h) const; Node *createNode(uint h, const Key &key, const T &value, Node **nextNode); void deleteNode(Node *node); @@ -496,7 +524,7 @@ template <class Key, class T> Q_INLINE_TEMPLATE void QHash<Key, T>::duplicateNode(QHashData::Node *node, void *newNode) { Node *concreteNode = concrete(node); - new (newNode) Node(concreteNode->key, concreteNode->value, concreteNode->h, 0); + new (newNode) Node(concreteNode->key, concreteNode->value, concreteNode->h, Q_NULLPTR); } template <class Key, class T> @@ -916,6 +944,9 @@ public: insert(it->first, it->second); } #endif + // compiler-generated copy/move ctors/assignment operators are fine! + // compiler-generated destructor is fine! + QMultiHash(const QHash<Key, T> &other) : QHash<Key, T>(other) {} void swap(QMultiHash &other) { QHash<Key, T>::swap(other); } // prevent QMultiHash<->QHash swaps diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h index 7908bf5137407722e69760012261999ae509aa74..f216aa121cbcbec080053cfd3d9cf5dcc5bcda08 100644 --- a/src/corelib/tools/qlinkedlist.h +++ b/src/corelib/tools/qlinkedlist.h @@ -88,7 +88,7 @@ public: #ifdef Q_COMPILER_RVALUE_REFS inline QLinkedList(QLinkedList<T> &&other) : d(other.d) { other.d = const_cast<QLinkedListData *>(&QLinkedListData::shared_null); } inline QLinkedList<T> &operator=(QLinkedList<T> &&other) - { qSwap(d, other.d); return *this; } + { QLinkedList moved(std::move(other)); swap(moved); return *this; } #endif inline void swap(QLinkedList<T> &other) { qSwap(d, other.d); } bool operator==(const QLinkedList<T> &l) const; diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index f4901d336e3514a78194a5a6c26ca5c21f3b8965..2e4ecbf5c938304e7122ff94f8c5ffea05feb6ea 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -332,41 +332,56 @@ void **QListData::erase(void **xi) \reentrant QList\<T\> is one of Qt's generic \l{container classes}. It - stores a list of values and provides fast index-based access as - well as fast insertions and removals. + stores items in a list that provides fast index-based access + and index-based insertions and removals. QList\<T\>, QLinkedList\<T\>, and QVector\<T\> provide similar - functionality. Here's an overview: + APIs and functionality. They are often interchangeable, but there + are performance consequences. Here is an overview of use cases: \list - \li For most purposes, QList is the right class to use. Its - index-based API is more convenient than QLinkedList's - iterator-based API, and it is usually faster than - QVector because of the way it stores its items in - memory. It also expands to less code in your executable. - \li If you need a real linked list, with guarantees of \l{constant - time} insertions in the middle of the list and iterators to - items rather than indexes, use QLinkedList. - \li If you want the items to occupy adjacent memory positions, - use QVector. + \li QVector should be your default first choice. + QVector\<T\> will usually give better performance than QList\<T\>, + because QVector\<T\> always stores its items sequentially in memory, + where QList\<T\> will allocate its items on the heap unless + \c {sizeof(T) <= sizeof(void*)} and T has been declared to be + either a \c{Q_MOVABLE_TYPE} or a \c{Q_PRIMITIVE_TYPE} using + \l {Q_DECLARE_TYPEINFO}. See the \l {Pros and Cons of Using QList} + for an explanation. + \li However, QList is used throughout the Qt APIs for passing + parameters and for returning values. Use QList to interface with + those APIs. + \li If you need a real linked list, which guarantees + \l {Algorithmic Complexity}{constant time} insertions mid-list and + uses iterators to items rather than indexes, use QLinkedList. \endlist + \note QVector and QVarLengthArray both guarantee C-compatible + array layout. QList does not. This might be important if your + application must interface with a C API. - Internally, QList\<T\> is represented as an array of pointers to - items of type T. If T is itself a pointer type or a basic type - that is no larger than a pointer, or if T is one of Qt's \l{shared - classes}, then QList\<T\> stores the items directly in the pointer - array. For lists under a thousand items, this array representation - allows for very fast insertions in the middle, and it allows - index-based access. Furthermore, operations like prepend() and - append() are very fast, because QList preallocates memory at both + \note Iterators into a QLinkedList and references into + heap-allocating QLists remain valid long as the referenced items + remain in the container. This is not true for iterators and + references into a QVector and non-heap-allocating QLists. + + Internally, QList\<T\> is represented as an array of T if + If \c{sizeof(T) <= sizeof(void*)} and T has been declared to be + either a \c{Q_MOVABLE_TYPE} or a \c{Q_PRIMITIVE_TYPE} using + \l {Q_DECLARE_TYPEINFO}. Otherwise, QList\<T\> is represented + as an array of T* and the items are allocated on the heap. + + The array representation allows very fast insertions and + index-based access. The prepend() and append() operations are + also very fast because QList preallocates memory at both ends of its internal array. (See \l{Algorithmic Complexity} for - details.) Note, however, that for unshared list items that are - larger than a pointer, each append or insert of a new item - requires allocating the new item on the heap, and this per item - allocation might make QVector a better choice in cases that do - lots of appending or inserting, since QVector allocates memory for - its items in a single heap allocation. + details. + + Note, however, that when the conditions specified above are not met, + each append or insert of a new item requires allocating the new item + on the heap, and this per item allocation will make QVector a better + choice for use cases that do a lot of appending or inserting, because + QVector can allocate memory for many items in a single heap allocation. Note that the internal array only ever gets bigger over the life of the list. It never shrinks. The internal array is deallocated @@ -401,9 +416,10 @@ void **QListData::erase(void **xi) \snippet code/src_corelib_tools_qlistdata.cpp 2 - Because QList is implemented as an array of pointers, this - operation is very fast (\l{constant time}). For read-only access, - an alternative syntax is to use at(): + Because QList is implemented as an array of pointers for types + that are larger than a pointer or are not movable, this operation + requires (\l{Algorithmic Complexity}{constant time}). For read-only + access, an alternative syntax is to use at(): \snippet code/src_corelib_tools_qlistdata.cpp 3 @@ -417,10 +433,10 @@ void **QListData::erase(void **xi) \snippet code/src_corelib_tools_qlistdata.cpp 4 - Inserting and removing items at either ends of the list is very - fast (\l{constant time} in most cases), because QList - preallocates extra space on both sides of its internal buffer to - allow for fast growth at both ends of the list. + Inserting and removing items at either end of the list is very + fast (\l{Algorithmic Complexity}{constant time} in most cases), + because QList preallocates extra space on both sides of its + internal buffer to allow for fast growth at both ends of the list. If you want to find all occurrences of a particular value in a list, use indexOf() or lastIndexOf(). The former searches forward @@ -481,6 +497,11 @@ void **QListData::erase(void **xi) \l{QStringList::removeDuplicates()}{removeDuplicates}, \l{QStringList::sort()}{sort}. + \section1 More Information on Using Qt Containers + + For a detailed discussion comparing Qt containers with each other and + with STL containers, see \l {Understand the Qt Containers}. + \sa QListIterator, QMutableListIterator, QLinkedList, QVector */ @@ -512,10 +533,11 @@ void **QListData::erase(void **xi) Constructs a copy of \a other. - This operation takes \l{constant time}, because QList is - \l{implicitly shared}. This makes returning a QList from a - function very fast. If a shared instance is modified, it will be - copied (copy-on-write), and that takes \l{linear time}. + This operation takes \l{Algorithmic Complexity}{constant time}, + because QList is \l{implicitly shared}. This makes returning a + QList from a function very fast. If a shared instance is modified, + it will be copied (copy-on-write), and that takes + \l{Algorithmic Complexity}{linear time}. \sa operator=() */ @@ -700,7 +722,7 @@ void **QListData::erase(void **xi) Returns the item at index position \a i in the list. \a i must be a valid index position in the list (i.e., 0 <= \a i < size()). - This function is very fast (\l{constant time}). + This function is very fast (\l{Algorithmic Complexity}{constant time}). \sa value(), operator[]() */ @@ -713,8 +735,8 @@ void **QListData::erase(void **xi) If this function is called on a list that is currently being shared, it will trigger a copy of all elements. Otherwise, this function runs in - \l{constant time}. If you do not want to modify the list you should use - QList::at(). + \l{Algorithmic Complexity}{constant time}. If you do not want to modify + the list you should use QList::at(). \sa at(), value() */ @@ -723,7 +745,7 @@ void **QListData::erase(void **xi) \overload - Same as at(). This function runs in \l{constant time}. + Same as at(). This function runs in \l{Algorithmic Complexity}{constant time}. */ /*! \fn QList::reserve(int alloc) @@ -749,9 +771,9 @@ void **QListData::erase(void **xi) This is the same as list.insert(size(), \a value). If this list is not shared, this operation is typically - very fast (amortized \l{constant time}), because QList - preallocates extra space on both sides of its internal - buffer to allow for fast growth at both ends of the list. + very fast (amortized \l{Algorithmic Complexity}{constant time}), + because QList preallocates extra space on both sides of its + internal buffer to allow for fast growth at both ends of the list. \sa operator<<(), prepend(), insert() */ @@ -777,9 +799,9 @@ void **QListData::erase(void **xi) This is the same as list.insert(0, \a value). If this list is not shared, this operation is typically - very fast (amortized \l{constant time}), because QList - preallocates extra space on both sides of its internal - buffer to allow for fast growth at both ends of the list. + very fast (amortized \l{Algorithmic Complexity}{constant time}), + because QList preallocates extra space on both sides of its + internal buffer to allow for fast growth at both ends of the list. \sa append(), insert() */ @@ -870,7 +892,8 @@ void **QListData::erase(void **xi) same as takeAt(0). This function assumes the list is not empty. To avoid failure, call isEmpty() before calling this function. - If this list is not shared, this operation takes \l{constant time}. + If this list is not shared, this operation takes + \l {Algorithmic Complexity}{constant time}. If you don't use the return value, removeFirst() is more efficient. @@ -885,7 +908,8 @@ void **QListData::erase(void **xi) not empty. To avoid failure, call isEmpty() before calling this function. - If this list is not shared, this operation takes \l{constant time}. + If this list is not shared, this operation takes + \l {Algorithmic Complexity}{constant time}. If you don't use the return value, removeLast() is more efficient. @@ -1227,7 +1251,7 @@ void **QListData::erase(void **xi) not be empty. If the list can be empty, call isEmpty() before calling this function. - \sa last(), isEmpty() + \sa constFirst(), last(), isEmpty() */ /*! \fn const T& QList::first() const @@ -1235,13 +1259,23 @@ void **QListData::erase(void **xi) \overload */ +/*! \fn const T& QList::constFirst() const + \since 5.6 + + Returns a const reference to the first item in the list. The list must + not be empty. If the list can be empty, call isEmpty() before + calling this function. + + \sa constLast(), isEmpty(), first() +*/ + /*! \fn T& QList::last() Returns a reference to the last item in the list. The list must not be empty. If the list can be empty, call isEmpty() before calling this function. - \sa first(), isEmpty() + \sa constLast(), first(), isEmpty() */ /*! \fn const T& QList::last() const @@ -1249,6 +1283,16 @@ void **QListData::erase(void **xi) \overload */ +/*! \fn const T& QList::constLast() const + \since 5.6 + + Returns a reference to the last item in the list. The list must + not be empty. If the list can be empty, call isEmpty() before + calling this function. + + \sa constFirst(), isEmpty(), last() +*/ + /*! \fn void QList::removeFirst() Removes the first item in the list. Calling this function is diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index e446a6625b97a3488d08b515406ce44d91bdb01c..e1804e17e534d520a8c3beb31dff5b45d26b6b97 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -103,11 +103,11 @@ struct Q_CORE_EXPORT QListData { void remove(int i); void remove(int i, int n); void move(int from, int to); - inline int size() const { return d->end - d->begin; } - inline bool isEmpty() const { return d->end == d->begin; } - inline void **at(int i) const { return d->array + d->begin + i; } - inline void **begin() const { return d->array + d->begin; } - inline void **end() const { return d->array + d->end; } + inline int size() const Q_DECL_NOTHROW { return d->end - d->begin; } + inline bool isEmpty() const Q_DECL_NOTHROW { return d->end == d->begin; } + inline void **at(int i) const Q_DECL_NOTHROW { return d->array + d->begin + i; } + inline void **begin() const Q_DECL_NOTHROW { return d->array + d->begin; } + inline void **end() const Q_DECL_NOTHROW { return d->array + d->end; } }; template <typename T> @@ -144,7 +144,7 @@ public: #ifdef Q_COMPILER_RVALUE_REFS inline QList(QList<T> &&other) : d(other.d) { other.d = const_cast<QListData::Data *>(&QListData::shared_null); } inline QList &operator=(QList<T> &&other) - { qSwap(d, other.d); return *this; } + { QList moved(std::move(other)); swap(moved); return *this; } #endif inline void swap(QList<T> &other) { qSwap(d, other.d); } #ifdef Q_COMPILER_INITIALIZER_LISTS @@ -155,7 +155,7 @@ public: bool operator==(const QList<T> &l) const; inline bool operator!=(const QList<T> &l) const { return !(*this == l); } - inline int size() const { return p.size(); } + inline int size() const Q_DECL_NOTHROW { return p.size(); } inline void detach() { if (d->ref.isShared()) detach_helper(); } @@ -178,9 +178,9 @@ public: d->ref.setSharable(sharable); } #endif - inline bool isSharedWith(const QList<T> &other) const { return d == other.d; } + inline bool isSharedWith(const QList<T> &other) const Q_DECL_NOTHROW { return d == other.d; } - inline bool isEmpty() const { return p.isEmpty(); } + inline bool isEmpty() const Q_DECL_NOTHROW { return p.isEmpty(); } void clear(); @@ -219,34 +219,34 @@ public: typedef T *pointer; typedef T &reference; - inline iterator() : i(0) {} - inline iterator(Node *n) : i(n) {} + inline iterator() Q_DECL_NOTHROW : i(Q_NULLPTR) {} + inline iterator(Node *n) Q_DECL_NOTHROW : i(n) {} #if QT_VERSION < QT_VERSION_CHECK(6,0,0) // can't remove it in Qt 5, since doing so would make the type trivial, // which changes the way it's passed to functions by value. - inline iterator(const iterator &o): i(o.i){} + inline iterator(const iterator &o) Q_DECL_NOTHROW : i(o.i){} #endif inline T &operator*() const { return i->t(); } inline T *operator->() const { return &i->t(); } inline T &operator[](difference_type j) const { return i[j].t(); } - inline bool operator==(const iterator &o) const { return i == o.i; } - inline bool operator!=(const iterator &o) const { return i != o.i; } - inline bool operator<(const iterator& other) const { return i < other.i; } - inline bool operator<=(const iterator& other) const { return i <= other.i; } - inline bool operator>(const iterator& other) const { return i > other.i; } - inline bool operator>=(const iterator& other) const { return i >= other.i; } + inline bool operator==(const iterator &o) const Q_DECL_NOTHROW { return i == o.i; } + inline bool operator!=(const iterator &o) const Q_DECL_NOTHROW { return i != o.i; } + inline bool operator<(const iterator& other) const Q_DECL_NOTHROW { return i < other.i; } + inline bool operator<=(const iterator& other) const Q_DECL_NOTHROW { return i <= other.i; } + inline bool operator>(const iterator& other) const Q_DECL_NOTHROW { return i > other.i; } + inline bool operator>=(const iterator& other) const Q_DECL_NOTHROW { return i >= other.i; } #ifndef QT_STRICT_ITERATORS - inline bool operator==(const const_iterator &o) const + inline bool operator==(const const_iterator &o) const Q_DECL_NOTHROW { return i == o.i; } - inline bool operator!=(const const_iterator &o) const + inline bool operator!=(const const_iterator &o) const Q_DECL_NOTHROW { return i != o.i; } - inline bool operator<(const const_iterator& other) const + inline bool operator<(const const_iterator& other) const Q_DECL_NOTHROW { return i < other.i; } - inline bool operator<=(const const_iterator& other) const + inline bool operator<=(const const_iterator& other) const Q_DECL_NOTHROW { return i <= other.i; } - inline bool operator>(const const_iterator& other) const + inline bool operator>(const const_iterator& other) const Q_DECL_NOTHROW { return i > other.i; } - inline bool operator>=(const const_iterator& other) const + inline bool operator>=(const const_iterator& other) const Q_DECL_NOTHROW { return i >= other.i; } #endif inline iterator &operator++() { ++i; return *this; } @@ -271,27 +271,27 @@ public: typedef const T *pointer; typedef const T &reference; - inline const_iterator() : i(0) {} - inline const_iterator(Node *n) : i(n) {} + inline const_iterator() Q_DECL_NOTHROW : i(Q_NULLPTR) {} + inline const_iterator(Node *n) Q_DECL_NOTHROW : i(n) {} #if QT_VERSION < QT_VERSION_CHECK(6,0,0) // can't remove it in Qt 5, since doing so would make the type trivial, // which changes the way it's passed to functions by value. - inline const_iterator(const const_iterator &o): i(o.i) {} + inline const_iterator(const const_iterator &o) Q_DECL_NOTHROW : i(o.i) {} #endif #ifdef QT_STRICT_ITERATORS - inline explicit const_iterator(const iterator &o): i(o.i) {} + inline explicit const_iterator(const iterator &o) Q_DECL_NOTHROW : i(o.i) {} #else - inline const_iterator(const iterator &o): i(o.i) {} + inline const_iterator(const iterator &o) Q_DECL_NOTHROW : i(o.i) {} #endif inline const T &operator*() const { return i->t(); } inline const T *operator->() const { return &i->t(); } inline const T &operator[](difference_type j) const { return i[j].t(); } - inline bool operator==(const const_iterator &o) const { return i == o.i; } - inline bool operator!=(const const_iterator &o) const { return i != o.i; } - inline bool operator<(const const_iterator& other) const { return i < other.i; } - inline bool operator<=(const const_iterator& other) const { return i <= other.i; } - inline bool operator>(const const_iterator& other) const { return i > other.i; } - inline bool operator>=(const const_iterator& other) const { return i >= other.i; } + inline bool operator==(const const_iterator &o) const Q_DECL_NOTHROW { return i == o.i; } + inline bool operator!=(const const_iterator &o) const Q_DECL_NOTHROW { return i != o.i; } + inline bool operator<(const const_iterator& other) const Q_DECL_NOTHROW { return i < other.i; } + inline bool operator<=(const const_iterator& other) const Q_DECL_NOTHROW { return i <= other.i; } + inline bool operator>(const const_iterator& other) const Q_DECL_NOTHROW { return i > other.i; } + inline bool operator>=(const const_iterator& other) const Q_DECL_NOTHROW { return i >= other.i; } inline const_iterator &operator++() { ++i; return *this; } inline const_iterator operator++(int) { Node *n = i; ++i; return n; } inline const_iterator &operator--() { i--; return *this; } @@ -308,19 +308,19 @@ public: typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; inline iterator begin() { detach(); return reinterpret_cast<Node *>(p.begin()); } - inline const_iterator begin() const { return reinterpret_cast<Node *>(p.begin()); } - inline const_iterator cbegin() const { return reinterpret_cast<Node *>(p.begin()); } - inline const_iterator constBegin() const { return reinterpret_cast<Node *>(p.begin()); } + inline const_iterator begin() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.begin()); } + inline const_iterator cbegin() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.begin()); } + inline const_iterator constBegin() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.begin()); } inline iterator end() { detach(); return reinterpret_cast<Node *>(p.end()); } - inline const_iterator end() const { return reinterpret_cast<Node *>(p.end()); } - inline const_iterator cend() const { return reinterpret_cast<Node *>(p.end()); } - inline const_iterator constEnd() const { return reinterpret_cast<Node *>(p.end()); } + inline const_iterator end() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.end()); } + inline const_iterator cend() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.end()); } + inline const_iterator constEnd() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.end()); } reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } - const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } - const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } - const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } + const_reverse_iterator rbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); } + const_reverse_iterator rend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); } + const_reverse_iterator crbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); } + const_reverse_iterator crend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); } iterator insert(iterator before, const T &t); iterator erase(iterator pos); iterator erase(iterator first, iterator last); @@ -331,9 +331,11 @@ public: inline int count() const { return p.size(); } inline int length() const { return p.size(); } // Same as count() inline T& first() { Q_ASSERT(!isEmpty()); return *begin(); } + inline const T& constFirst() const { return first(); } inline const T& first() const { Q_ASSERT(!isEmpty()); return at(0); } T& last() { Q_ASSERT(!isEmpty()); return *(--end()); } const T& last() const { Q_ASSERT(!isEmpty()); return at(count() - 1); } + inline const T& constLast() const { return last(); } inline void removeFirst() { Q_ASSERT(!isEmpty()); erase(begin()); } inline void removeLast() { Q_ASSERT(!isEmpty()); erase(--end()); } inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; } @@ -395,7 +397,7 @@ private: void node_copy(Node *from, Node *to, Node *src); void node_destruct(Node *from, Node *to); - bool isValidIterator(const iterator &i) const + bool isValidIterator(const iterator &i) const Q_DECL_NOTHROW { return (constBegin().i <= i.i) && (i.i <= constEnd().i); } diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index c3367cbb92d293a78e8b330b0abc4837a7b9618a..4cf802e249c62e1ffd77cebbe904c5a24f4cbd65 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -42,6 +42,7 @@ #include "qdatastream.h" #include "qdebug.h" +#include "qhashfunctions.h" #include "qstring.h" #include "qlocale.h" #include "qlocale_p.h" @@ -875,6 +876,21 @@ bool QLocale::operator!=(const QLocale &other) const return d->m_data != other.d->m_data || d->m_numberOptions != other.d->m_numberOptions; } +/*! + \since 5.6 + \relates QLocale + + Returns the hash value for \a key, using + \a seed to seed the calculation. +*/ +uint qHash(const QLocale &key, uint seed) Q_DECL_NOTHROW +{ + QtPrivate::QHashCombine hash; + seed = hash(seed, key.d->m_data); + seed = hash(seed, key.d->m_numberOptions); + return seed; +} + /*! \since 4.2 @@ -3516,7 +3532,7 @@ QString QLocale::toCurrencyString(double value, const QString &symbol) const \since 4.8 Returns an ordered list of locale names for translation purposes in - preference order (like "en", "en-US", "en-Latn-US"). + preference order (like "en-Latn-US", "en-US", "en"). The return value represents locale names that the user expects to see the UI translation in. diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h index 61574ba44fe94353c835a1d58adc2917be91cc31..0cbfa6710c7de56caab7c16038be4242cfab69be 100644 --- a/src/corelib/tools/qlocale.h +++ b/src/corelib/tools/qlocale.h @@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE class QDataStream; class QDate; class QDateTime; +class QLocale; class QTime; class QVariant; class QTextStream; @@ -52,6 +53,8 @@ class QTextStreamPrivate; class QLocalePrivate; +Q_CORE_EXPORT uint qHash(const QLocale &key, uint seed = 0) Q_DECL_NOTHROW; + class Q_CORE_EXPORT QLocale { Q_GADGET @@ -868,23 +871,23 @@ public: QString nativeLanguageName() const; QString nativeCountryName() const; - short toShort(const QString &s, bool *ok = 0) const; - ushort toUShort(const QString &s, bool *ok = 0) const; - int toInt(const QString &s, bool *ok = 0) const; - uint toUInt(const QString &s, bool *ok = 0) const; - qlonglong toLongLong(const QString &s, bool *ok = 0) const; - qulonglong toULongLong(const QString &s, bool *ok = 0) const; - float toFloat(const QString &s, bool *ok = 0) const; - double toDouble(const QString &s, bool *ok = 0) const; - - short toShort(const QStringRef &s, bool *ok = 0) const; - ushort toUShort(const QStringRef &s, bool *ok = 0) const; - int toInt(const QStringRef &s, bool *ok = 0) const; - uint toUInt(const QStringRef &s, bool *ok = 0) const; - qlonglong toLongLong(const QStringRef &s, bool *ok = 0) const; - qulonglong toULongLong(const QStringRef &s, bool *ok = 0) const; - float toFloat(const QStringRef &s, bool *ok = 0) const; - double toDouble(const QStringRef &s, bool *ok = 0) const; + short toShort(const QString &s, bool *ok = Q_NULLPTR) const; + ushort toUShort(const QString &s, bool *ok = Q_NULLPTR) const; + int toInt(const QString &s, bool *ok = Q_NULLPTR) const; + uint toUInt(const QString &s, bool *ok = Q_NULLPTR) const; + qlonglong toLongLong(const QString &s, bool *ok = Q_NULLPTR) const; + qulonglong toULongLong(const QString &s, bool *ok = Q_NULLPTR) const; + float toFloat(const QString &s, bool *ok = Q_NULLPTR) const; + double toDouble(const QString &s, bool *ok = Q_NULLPTR) const; + + short toShort(const QStringRef &s, bool *ok = Q_NULLPTR) const; + ushort toUShort(const QStringRef &s, bool *ok = Q_NULLPTR) const; + int toInt(const QStringRef &s, bool *ok = Q_NULLPTR) const; + uint toUInt(const QStringRef &s, bool *ok = Q_NULLPTR) const; + qlonglong toLongLong(const QStringRef &s, bool *ok = Q_NULLPTR) const; + qulonglong toULongLong(const QStringRef &s, bool *ok = Q_NULLPTR) const; + float toFloat(const QStringRef &s, bool *ok = Q_NULLPTR) const; + double toDouble(const QStringRef &s, bool *ok = Q_NULLPTR) const; QString toString(qlonglong i) const; QString toString(qulonglong i) const; @@ -979,6 +982,8 @@ public: private: QLocale(QLocalePrivate &dd); friend class QLocalePrivate; + friend Q_CORE_EXPORT uint qHash(const QLocale &key, uint seed) Q_DECL_NOTHROW; + QSharedDataPointer<QLocalePrivate> d; }; Q_DECLARE_TYPEINFO(QLocale, Q_MOVABLE_TYPE); diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h index 430f95dcdaf797a53603279e595906358b38dbcf..b3fd7a96b8e666ece1cceb7a695f851a1ce66eb9 100644 --- a/src/corelib/tools/qlocale_p.h +++ b/src/corelib/tools/qlocale_p.h @@ -122,6 +122,8 @@ private: QSystemLocale(bool); friend class QSystemLocaleSingleton; }; +Q_DECLARE_TYPEINFO(QSystemLocale::QueryType, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(QSystemLocale::CurrencyToStringArgument, Q_MOVABLE_TYPE); #endif #ifdef QT_USE_ICU @@ -153,6 +155,7 @@ struct QLocaleId ushort language_id, script_id, country_id; }; +Q_DECLARE_TYPEINFO(QLocaleId, Q_PRIMITIVE_TYPE); struct QLocaleData { diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index 1b7a8007cdcaa7a88915113461b572eb5937fcda..f7aa7332ddd8bffc26d12826c6861f03559b3953 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -858,6 +858,15 @@ void QMapDataBase::freeData(QMapDataBase *d) \sa begin(), constEnd() */ +/*! \fn QMap::key_iterator QMap::keyBegin() const + \since 5.6 + + Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first key + in the map. + + \sa keyEnd(), firstKey() +*/ + /*! \fn QMap::iterator QMap::end() Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item @@ -888,6 +897,15 @@ void QMapDataBase::freeData(QMapDataBase *d) \sa constBegin(), end() */ +/*! \fn QMap::key_iterator QMap::keyEnd() const + \since 5.6 + + Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary + item after the last key in the map. + + \sa keyBegin(), lastKey() +*/ + /*! \fn const Key &QMap::firstKey() const \since 5.2 @@ -896,7 +914,7 @@ void QMapDataBase::freeData(QMapDataBase *d) This executes in \l{constant time}. - \sa lastKey(), first(), isEmpty() + \sa lastKey(), first(), keyBegin(), isEmpty() */ /*! \fn const Key &QMap::lastKey() const @@ -907,7 +925,7 @@ void QMapDataBase::freeData(QMapDataBase *d) This executes in \l{logarithmic time}. - \sa firstKey(), last(), isEmpty() + \sa firstKey(), last(), keyEnd(), isEmpty() */ /*! \fn T &QMap::first() @@ -1161,6 +1179,12 @@ void QMapDataBase::freeData(QMapDataBase *d) are stored under \a key. */ +/*! + \fn QPair<const_iterator, const_iterator> QMap::equal_range(const Key &key) const + \overload + \since 5.6 +*/ + /*! \class QMap::iterator \inmodule QtCore @@ -1229,7 +1253,7 @@ void QMapDataBase::freeData(QMapDataBase *d) while iterators are active on that container. For more information, read \l{Implicit sharing iterator problem}. - \sa QMap::const_iterator, QMutableMapIterator + \sa QMap::const_iterator, QMap::key_iterator, QMutableMapIterator */ /*! \typedef QMap::iterator::difference_type @@ -1452,7 +1476,7 @@ void QMapDataBase::freeData(QMapDataBase *d) while iterators are active on that container. For more information, read \l{Implicit sharing iterator problem}. - \sa QMap::iterator, QMapIterator + \sa QMap::iterator, QMap::key_iterator, QMapIterator */ /*! \typedef QMap::const_iterator::difference_type @@ -1628,6 +1652,134 @@ void QMapDataBase::freeData(QMapDataBase *d) \sa operator+=(), operator-() */ +/*! \class QMap::key_iterator + \inmodule QtCore + \since 5.6 + \brief The QMap::key_iterator class provides an STL-style const iterator for QMap and QMultiMap keys. + + QMap::key_iterator is essentially the same as QMap::const_iterator + with the difference that operator*() and operator->() return a key + instead of a value. + + For most uses QMap::iterator and QMap::const_iterator should be used, + you can easily access the key by calling QMap::iterator::key(): + + \snippet code/src_corelib_tools_qmap.cpp keyiterator1 + + However, to have interoperability between QMap's keys and STL-style + algorithms we need an iterator that dereferences to a key instead + of a value. With QMap::key_iterator we can apply an algorithm to a + range of keys without having to call QMap::keys(), which is inefficient + as it costs one QMap iteration and memory allocation to create a temporary + QList. + + \snippet code/src_corelib_tools_qmap.cpp keyiterator2 + + QMap::key_iterator is const, it's not possible to modify the key. + + The default QMap::key_iterator constructor creates an uninitialized + iterator. You must initialize it using a QMap function like + QMap::keyBegin() or QMap::keyEnd(). + + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + + \sa QMap::const_iterator, QMap::iterator +*/ + +/*! \typedef QMap::key_iterator::difference_type + \internal +*/ + +/*! \typedef QMap::key_iterator::iterator_category + \internal +*/ + +/*! \typedef QMap::key_iterator::pointer + \internal +*/ + +/*! \typedef QMap::key_iterator::reference + \internal +*/ + +/*! \typedef QMap::key_iterator::value_type + \internal +*/ + +/*! \fn const T &QMap::key_iterator::operator*() const + + Returns the current item's key. +*/ + +/*! \fn const T *QMap::key_iterator::operator->() const + + Returns a pointer to the current item's key. +*/ + +/*! \fn bool QMap::key_iterator::operator==(key_iterator other) + + Returns \c true if \a other points to the same item as this + iterator; otherwise returns \c false. + + \sa operator!=() +*/ + +/*! \fn bool QMap::key_iterator::operator!=(key_iterator other) + + Returns \c true if \a other points to a different item than this + iterator; otherwise returns \c false. + + \sa operator==() +*/ + +/*! + \fn QMap::key_iterator &QMap::key_iterator::operator++() + + The prefix ++ operator (\c{++i}) advances the iterator to the + next item in the hash and returns an iterator to the new current + item. + + Calling this function on QMap::keyEnd() leads to undefined results. + + \sa operator--() +*/ + +/*! \fn QMap::key_iterator QMap::key_iterator::operator++(int) + + \overload + + The postfix ++ operator (\c{i++}) advances the iterator to the + next item in the hash and returns an iterator to the previous + item. +*/ + +/*! \fn QMap::key_iterator &QMap::key_iterator::operator--() + + The prefix -- operator (\c{--i}) makes the preceding item + current and returns an iterator pointing to the new current item. + + Calling this function on QMap::keyBegin() leads to undefined + results. + + \sa operator++() +*/ + +/*! \fn QMap::key_iterator QMap::key_iterator::operator--(int) + + \overload + + The postfix -- operator (\c{i--}) makes the preceding item + current and returns an iterator pointing to the previous + item. +*/ + +/*! \fn const_iterator QMap::key_iterator::base() const + Returns the underlying const_iterator this key_iterator is based on. +*/ + /*! \fn QDataStream &operator<<(QDataStream &out, const QMap<Key, T> &map) \relates QMap diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 1f80e8f0f49ddfc09293dd977305ff38f083dd53..b7bd268bdaab7ee2149ef12085864befcfe9508b 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -38,6 +38,7 @@ #include <QtCore/qlist.h> #include <QtCore/qrefcount.h> #include <QtCore/qpair.h> +#include <QtCore/qtypetraits.h> #ifdef Q_MAP_DEBUG #include <QtCore/qdebug.h> @@ -94,6 +95,13 @@ struct Q_CORE_EXPORT QMapNodeBase void setColor(Color c) { if (c == Black) p |= Black; else p &= ~Black; } QMapNodeBase *parent() const { return reinterpret_cast<QMapNodeBase *>(p & ~Mask); } void setParent(QMapNodeBase *pp) { p = (p & Mask) | quintptr(pp); } + + template <typename T> + static typename QtPrivate::QEnableIf<QTypeInfo<T>::isComplex>::Type + callDestructorIfNecessary(T &t) Q_DECL_NOTHROW { Q_UNUSED(t); t.~T(); } // Q_UNUSED: silence MSVC unused 't' warning + template <typename T> + static typename QtPrivate::QEnableIf<!QTypeInfo<T>::isComplex>::Type + callDestructorIfNecessary(T &) Q_DECL_NOTHROW {} }; template <class Key, class T> @@ -112,12 +120,26 @@ struct QMapNode : public QMapNodeBase QMapNode<Key, T> *copy(QMapData<Key, T> *d) const; - void destroySubTree(); + void destroySubTree() + { + callDestructorIfNecessary(key); + callDestructorIfNecessary(value); + doDestroySubTree(QtPrivate::integral_constant<bool, QTypeInfo<T>::isComplex || QTypeInfo<Key>::isComplex>()); + } QMapNode<Key, T> *lowerBound(const Key &key); QMapNode<Key, T> *upperBound(const Key &key); private: + void doDestroySubTree(QtPrivate::false_type) {} + void doDestroySubTree(QtPrivate::true_type) + { + if (left) + leftNode()->destroySubTree(); + if (right) + rightNode()->destroySubTree(); + } + QMapNode() Q_DECL_EQ_DELETE; Q_DISABLE_COPY(QMapNode) }; @@ -126,7 +148,7 @@ template <class Key, class T> inline QMapNode<Key, T> *QMapNode<Key, T>::lowerBound(const Key &akey) { QMapNode<Key, T> *n = this; - QMapNode<Key, T> *lastNode = 0; + QMapNode<Key, T> *lastNode = Q_NULLPTR; while (n) { if (!qMapLessThanKey(n->key, akey)) { lastNode = n; @@ -142,7 +164,7 @@ template <class Key, class T> inline QMapNode<Key, T> *QMapNode<Key, T>::upperBound(const Key &akey) { QMapNode<Key, T> *n = this; - QMapNode<Key, T> *lastNode = 0; + QMapNode<Key, T> *lastNode = Q_NULLPTR; while (n) { if (qMapLessThanKey(akey, n->key)) { lastNode = n; @@ -194,7 +216,7 @@ struct QMapData : public QMapDataBase Node *findNode(const Key &akey) const; void nodeRange(const Key &akey, Node **firstNode, Node **lastNode); - Node *createNode(const Key &k, const T &v, Node *parent = 0, bool left = false) + Node *createNode(const Key &k, const T &v, Node *parent = Q_NULLPTR, bool left = false) { Node *n = static_cast<Node *>(QMapDataBase::createNode(sizeof(Node), Q_ALIGNOF(Node), parent, left)); @@ -235,48 +257,22 @@ QMapNode<Key, T> *QMapNode<Key, T>::copy(QMapData<Key, T> *d) const n->left = leftNode()->copy(d); n->left->setParent(n); } else { - n->left = 0; + n->left = Q_NULLPTR; } if (right) { n->right = rightNode()->copy(d); n->right->setParent(n); } else { - n->right = 0; + n->right = Q_NULLPTR; } return n; } -#if defined(Q_CC_MSVC) -#pragma warning( push ) -#pragma warning( disable : 4127 ) // conditional expression is constant -#endif - -template <class Key, class T> -void QMapNode<Key, T>::destroySubTree() -{ - if (QTypeInfo<Key>::isComplex) - key.~Key(); - if (QTypeInfo<T>::isComplex) - value.~T(); - if (QTypeInfo<Key>::isComplex || QTypeInfo<T>::isComplex) { - if (left) - leftNode()->destroySubTree(); - if (right) - rightNode()->destroySubTree(); - } -} - -#if defined(Q_CC_MSVC) -#pragma warning( pop ) -#endif - template <class Key, class T> void QMapData<Key, T>::deleteNode(QMapNode<Key, T> *z) { - if (QTypeInfo<Key>::isComplex) - z->key.~Key(); - if (QTypeInfo<T>::isComplex) - z->value.~T(); + QMapNodeBase::callDestructorIfNecessary(z->key); + QMapNodeBase::callDestructorIfNecessary(z->value); freeNodeAndRebalance(z); } @@ -288,7 +284,7 @@ QMapNode<Key, T> *QMapData<Key, T>::findNode(const Key &akey) const if (lb && !qMapLessThanKey(akey, lb->key)) return lb; } - return 0; + return Q_NULLPTR; } @@ -304,10 +300,10 @@ void QMapData<Key, T>::nodeRange(const Key &akey, QMapNode<Key, T> **firstNode, } else if (qMapLessThanKey(n->key, akey)) { n = n->rightNode(); } else { - *firstNode = n->leftNode() ? n->leftNode()->lowerBound(akey) : 0; + *firstNode = n->leftNode() ? n->leftNode()->lowerBound(akey) : Q_NULLPTR; if (!*firstNode) *firstNode = n; - *lastNode = n->rightNode() ? n->rightNode()->upperBound(akey) : 0; + *lastNode = n->rightNode() ? n->rightNode()->upperBound(akey) : Q_NULLPTR; if (!*lastNode) *lastNode = l; return; @@ -348,7 +344,7 @@ public: } inline QMap<Key, T> &operator=(QMap<Key, T> &&other) - { qSwap(d, other.d); return *this; } + { QMap moved(std::move(other)); swap(moved); return *this; } #endif inline void swap(QMap<Key, T> &other) { qSwap(d, other.d); } explicit QMap(const typename std::map<Key, T> &other); @@ -416,7 +412,7 @@ public: typedef T *pointer; typedef T &reference; - inline iterator() : i(0) { } + inline iterator() : i(Q_NULLPTR) { } inline iterator(Node *node) : i(node) { } inline const Key &key() const { return i->key; } @@ -473,7 +469,7 @@ public: typedef const T *pointer; typedef const T &reference; - inline const_iterator() : i(0) { } + inline const_iterator() : i(Q_NULLPTR) { } inline const_iterator(const Node *node) : i(node) { } #ifdef QT_STRICT_ITERATORS explicit inline const_iterator(const iterator &o) @@ -522,6 +518,32 @@ public: }; friend class const_iterator; + class key_iterator + { + const_iterator i; + + public: + typedef typename const_iterator::iterator_category iterator_category; + typedef typename const_iterator::difference_type difference_type; + typedef Key value_type; + typedef const Key *pointer; + typedef const Key &reference; + + explicit key_iterator(const_iterator o) : i(o) { } + + const Key &operator*() const { return i.key(); } + const Key *operator->() const { return &i.key(); } + bool operator==(key_iterator o) const { return i == o.i; } + bool operator!=(key_iterator o) const { return i != o.i; } + + inline key_iterator &operator++() { ++i; return *this; } + inline key_iterator operator++(int) { return key_iterator(i++);} + inline key_iterator &operator--() { --i; return *this; } + inline key_iterator operator--(int) { return key_iterator(i--); } + const_iterator base() const { return i; } + }; + + // STL style inline iterator begin() { detach(); return iterator(d->begin()); } inline const_iterator begin() const { return const_iterator(d->begin()); } @@ -531,6 +553,8 @@ public: inline const_iterator end() const { return const_iterator(d->end()); } inline const_iterator constEnd() const { return const_iterator(d->end()); } inline const_iterator cend() const { return const_iterator(d->end()); } + inline key_iterator keyBegin() const { return key_iterator(begin()); } + inline key_iterator keyEnd() const { return key_iterator(end()); } iterator erase(iterator it); // more Qt @@ -557,6 +581,7 @@ public: typedef int size_type; inline bool empty() const { return isEmpty(); } QPair<iterator, iterator> equal_range(const Key &akey); + QPair<const_iterator, const_iterator> equal_range(const Key &akey) const; #ifdef Q_MAP_DEBUG void dump() const; @@ -653,7 +678,7 @@ Q_INLINE_TEMPLATE int QMap<Key, T>::count(const Key &akey) const template <class Key, class T> Q_INLINE_TEMPLATE bool QMap<Key, T>::contains(const Key &akey) const { - return d->findNode(akey) != 0; + return d->findNode(akey) != Q_NULLPTR; } template <class Key, class T> @@ -662,7 +687,7 @@ Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::insert(const Key detach(); Node *n = d->root(); Node *y = d->end(); - Node *lastNode = 0; + Node *lastNode = Q_NULLPTR; bool left = true; while (n) { y = n; @@ -737,15 +762,15 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insert(const_iterator pos, const K } // we need to insert (not overwrite) - if (prev->right == 0) { + if (prev->right == Q_NULLPTR) { Node *z = d->createNode(akey, avalue, prev, false); return iterator(z); } - if (next->left == 0) { + if (next->left == Q_NULLPTR) { Node *z = d->createNode(akey, avalue, next, true); return iterator(z); } - Q_ASSERT(false); // We should have prev->right == 0 or next->left == 0. + Q_ASSERT(false); // We should have prev->right == Q_NULLPTR or next->left == Q_NULLPTR. return this->insert(akey, avalue); } } @@ -759,7 +784,7 @@ Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(cons Node* y = d->end(); Node* x = static_cast<Node *>(d->root()); bool left = true; - while (x != 0) { + while (x != Q_NULLPTR) { left = !qMapLessThanKey(x->key, akey); y = x; x = left ? x->leftNode() : x->rightNode(); @@ -806,15 +831,15 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const_iterator pos, co return this->insertMulti(akey, avalue); // ignore hint // Hint is ok - do insert - if (prev->right == 0) { + if (prev->right == Q_NULLPTR) { Node *z = d->createNode(akey, avalue, prev, false); return iterator(z); } - if (next->left == 0) { + if (next->left == Q_NULLPTR) { Node *z = d->createNode(akey, avalue, next, true); return iterator(z); } - Q_ASSERT(false); // We should have prev->right == 0 or next->left == 0. + Q_ASSERT(false); // We should have prev->right == Q_NULLPTR or next->left == Q_NULLPTR. return this->insertMulti(akey, avalue); } } @@ -864,6 +889,15 @@ QPair<typename QMap<Key, T>::iterator, typename QMap<Key, T>::iterator> QMap<Key return QPair<iterator, iterator>(iterator(firstNode), iterator(lastNode)); } +template <class Key, class T> +QPair<typename QMap<Key, T>::const_iterator, typename QMap<Key, T>::const_iterator> +QMap<Key, T>::equal_range(const Key &akey) const +{ + Node *firstNode, *lastNode; + d->nodeRange(akey, &firstNode, &lastNode); + return qMakePair(const_iterator(firstNode), const_iterator(lastNode)); +} + #ifdef Q_MAP_DEBUG template <class Key, class T> void QMap<Key, T>::dump() const @@ -1051,7 +1085,7 @@ Q_OUTOFLINE_TEMPLATE QList<T> QMap<Key, T>::values(const Key &akey) const template <class Key, class T> Q_INLINE_TEMPLATE typename QMap<Key, T>::const_iterator QMap<Key, T>::lowerBound(const Key &akey) const { - Node *lb = d->root() ? d->root()->lowerBound(akey) : 0; + Node *lb = d->root() ? d->root()->lowerBound(akey) : Q_NULLPTR; if (!lb) lb = d->end(); return const_iterator(lb); @@ -1061,7 +1095,7 @@ template <class Key, class T> Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::lowerBound(const Key &akey) { detach(); - Node *lb = d->root() ? d->root()->lowerBound(akey) : 0; + Node *lb = d->root() ? d->root()->lowerBound(akey) : Q_NULLPTR; if (!lb) lb = d->end(); return iterator(lb); @@ -1071,7 +1105,7 @@ template <class Key, class T> Q_INLINE_TEMPLATE typename QMap<Key, T>::const_iterator QMap<Key, T>::upperBound(const Key &akey) const { - Node *ub = d->root() ? d->root()->upperBound(akey) : 0; + Node *ub = d->root() ? d->root()->upperBound(akey) : Q_NULLPTR; if (!ub) ub = d->end(); return const_iterator(ub); @@ -1081,7 +1115,7 @@ template <class Key, class T> Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::upperBound(const Key &akey) { detach(); - Node *ub = d->root() ? d->root()->upperBound(akey) : 0; + Node *ub = d->root() ? d->root()->upperBound(akey) : Q_NULLPTR; if (!ub) ub = d->end(); return iterator(ub); diff --git a/src/corelib/tools/qpair.qdoc b/src/corelib/tools/qpair.qdoc index 4452d2f0b86215802de1aa539e4fd0c0e25f043f..2a421a1bbf1c4f2b43bf3e18add8e85015eda133 100644 --- a/src/corelib/tools/qpair.qdoc +++ b/src/corelib/tools/qpair.qdoc @@ -96,6 +96,7 @@ \sa qMakePair() */ +/*! \fn void QPair::swap(QPair &other) \since 5.5 diff --git a/src/corelib/tools/qqueue.cpp b/src/corelib/tools/qqueue.cpp index 65b50c4e03fbb048730f44b2ca39f8831ce9bf61..a8b505161678e6f24eb509cedfa6f0f2152595dc 100644 --- a/src/corelib/tools/qqueue.cpp +++ b/src/corelib/tools/qqueue.cpp @@ -70,19 +70,6 @@ \sa QList, QStack */ -/*! - \fn QQueue::QQueue() - - Constructs an empty queue. -*/ - -/*! - \fn QQueue::~QQueue() - - Destroys the queue. References to the values in the queue, and all - iterators over this queue, become invalid. -*/ - /*! \fn void QQueue::swap(QQueue<T> &other) \since 4.8 diff --git a/src/corelib/tools/qqueue.h b/src/corelib/tools/qqueue.h index 9d5bda12108b78e6fd1ee0bb81b810060e83911f..7a7abab070a1e130ddd33e6b17ec9cd45e6e9a3a 100644 --- a/src/corelib/tools/qqueue.h +++ b/src/corelib/tools/qqueue.h @@ -43,8 +43,7 @@ template <class T> class QQueue : public QList<T> { public: - inline QQueue() {} - inline ~QQueue() {} + // compiler-generated special member functions are fine! inline void swap(QQueue<T> &other) { QList<T>::swap(other); } // prevent QList<->QQueue swaps #ifndef Q_QDOC // bring in QList::swap(int, int). We cannot say using QList<T>::swap, diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index 5aa9d5484386f58c8a4f91442fcf1e144ee7f550..8000dc8688c712c897991eddb4e3ef1480b24784 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -1025,9 +1025,6 @@ class QRegExpCharClass { public: QRegExpCharClass(); - inline QRegExpCharClass(const QRegExpCharClass &cc) { operator=(cc); } - - QRegExpCharClass &operator=(const QRegExpCharClass &cc); void clear(); bool negative() const { return n; } @@ -2325,17 +2322,6 @@ QRegExpCharClass::QRegExpCharClass() #endif } -QRegExpCharClass &QRegExpCharClass::operator=(const QRegExpCharClass &cc) -{ - c = cc.c; - r = cc.r; - n = cc.n; -#ifndef QT_NO_REGEXP_OPTIM - occ1 = cc.occ1; -#endif - return *this; -} - void QRegExpCharClass::clear() { c = 0; diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp index 47cad6349c4dcdb589b5fb56b93b538a07d41b73..88a048d8264c1b26d56a5349793410dc3db611e8 100644 --- a/src/corelib/tools/qregularexpression.cpp +++ b/src/corelib/tools/qregularexpression.cpp @@ -2128,7 +2128,8 @@ QStringRef QRegularExpressionMatch::capturedRef(const QString &name) const QStringList QRegularExpressionMatch::capturedTexts() const { QStringList texts; - for (int i = 0; i <= lastCapturedIndex(); ++i) + texts.reserve(d->capturedCount); + for (int i = 0; i < d->capturedCount; ++i) texts << captured(i); return texts; } diff --git a/src/corelib/tools/qringbuffer.cpp b/src/corelib/tools/qringbuffer.cpp index bcf6d2646ea18a26cd201d4291e6240799ba9269..85cfdaf129428b3b11ef259e15850a178b4bd94e 100644 --- a/src/corelib/tools/qringbuffer.cpp +++ b/src/corelib/tools/qringbuffer.cpp @@ -33,6 +33,7 @@ ****************************************************************************/ #include "private/qringbuffer_p.h" +#include "private/qbytearray_p.h" #include <string.h> QT_BEGIN_NAMESPACE @@ -79,7 +80,7 @@ void QRingBuffer::free(qint64 bytes) clear(); // try to minify/squeeze us } } else { - Q_ASSERT(quint64(bytes) < QByteArray::MaxSize); + Q_ASSERT(bytes < MaxByteArraySize); head += int(bytes); bufferSize -= bytes; } @@ -96,14 +97,14 @@ void QRingBuffer::free(qint64 bytes) char *QRingBuffer::reserve(qint64 bytes) { - if (bytes <= 0 || quint64(bytes) >= QByteArray::MaxSize) + if (bytes <= 0 || bytes >= MaxByteArraySize) return 0; const qint64 newSize = bytes + tail; // if need buffer reallocation if (newSize > buffers.last().size()) { if (newSize > buffers.last().capacity() && (tail >= basicBlockSize - || quint64(newSize) >= QByteArray::MaxSize)) { + || newSize >= MaxByteArraySize)) { // shrink this buffer to its current size buffers.last().resize(tail); @@ -117,7 +118,7 @@ char *QRingBuffer::reserve(qint64 bytes) char *writePtr = buffers.last().data() + tail; bufferSize += bytes; - Q_ASSERT(quint64(bytes) < QByteArray::MaxSize); + Q_ASSERT(bytes < MaxByteArraySize); tail += int(bytes); return writePtr; } @@ -129,7 +130,7 @@ char *QRingBuffer::reserve(qint64 bytes) */ char *QRingBuffer::reserveFront(qint64 bytes) { - if (bytes <= 0 || quint64(bytes) >= QByteArray::MaxSize) + if (bytes <= 0 || bytes >= MaxByteArraySize) return 0; if (head < bytes) { @@ -137,10 +138,14 @@ char *QRingBuffer::reserveFront(qint64 bytes) if (tailBuffer == 0) tail -= head; - buffers.prepend(QByteArray()); head = qMax(basicBlockSize, int(bytes)); + if (bufferSize == 0) { + tail = head; + } else { + buffers.prepend(QByteArray()); + ++tailBuffer; + } buffers.first().resize(head); - ++tailBuffer; } head -= int(bytes); @@ -163,7 +168,7 @@ void QRingBuffer::chop(qint64 bytes) clear(); // try to minify/squeeze us } } else { - Q_ASSERT(quint64(bytes) < QByteArray::MaxSize); + Q_ASSERT(bytes < MaxByteArraySize); tail -= int(bytes); bufferSize -= bytes; } diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h index 819ab005849e5261ff6f7be3b06e0bd20aeb277b..8d478f81f9e90a3359d1522e9c1e5b3233f77af9 100644 --- a/src/corelib/tools/qscopedpointer.h +++ b/src/corelib/tools/qscopedpointer.h @@ -91,7 +91,7 @@ class QScopedPointer { typedef T *QScopedPointer:: *RestrictedBool; public: - explicit inline QScopedPointer(T *p = 0) : d(p) + explicit inline QScopedPointer(T *p = Q_NULLPTR) : d(p) { } @@ -121,12 +121,12 @@ public: #if defined(Q_QDOC) inline operator bool() const { - return isNull() ? 0 : &QScopedPointer::d; + return isNull() ? Q_NULLPTR : &QScopedPointer::d; } #else inline operator RestrictedBool() const { - return isNull() ? 0 : &QScopedPointer::d; + return isNull() ? Q_NULLPTR : &QScopedPointer::d; } #endif @@ -140,7 +140,7 @@ public: return !d; } - inline void reset(T *other = 0) + inline void reset(T *other = Q_NULLPTR) { if (d == other) return; @@ -152,7 +152,7 @@ public: inline T *take() { T *oldD = d; - d = 0; + d = Q_NULLPTR; return oldD; } @@ -206,10 +206,10 @@ template <typename T, typename Cleanup = QScopedPointerArrayDeleter<T> > class QScopedArrayPointer : public QScopedPointer<T, Cleanup> { public: - inline QScopedArrayPointer() : QScopedPointer<T, Cleanup>(0) {} + inline QScopedArrayPointer() : QScopedPointer<T, Cleanup>(Q_NULLPTR) {} template <typename D> - explicit inline QScopedArrayPointer(D *p, typename QtPrivate::QScopedArrayEnsureSameType<T,D>::Type = 0) + explicit inline QScopedArrayPointer(D *p, typename QtPrivate::QScopedArrayEnsureSameType<T,D>::Type = Q_NULLPTR) : QScopedPointer<T, Cleanup>(p) { } diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index 5a9c75fe071b7afa62cadf78ffc670820021d9b0..aeba6cf68df2f02db06ffe716e6e987266e2c889 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.h @@ -57,15 +57,9 @@ public: insert(*it); } #endif - inline QSet(const QSet<T> &other) : q_hash(other.q_hash) {} - - inline QSet<T> &operator=(const QSet<T> &other) - { q_hash = other.q_hash; return *this; } -#ifdef Q_COMPILER_RVALUE_REFS - inline QSet(QSet &&other) : q_hash(qMove(other.q_hash)) {} - inline QSet<T> &operator=(QSet<T> &&other) - { qSwap(q_hash, other.q_hash); return *this; } -#endif + // compiler-generated copy/move ctor/assignment operators are fine! + // compiler-generated destructor is fine! + inline void swap(QSet<T> &other) { q_hash.swap(other.q_hash); } inline bool operator==(const QSet<T> &other) const diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc index 495329b90df2ae035c45f97c5bc5bceab6e35bc1..d91a589aa11ae91ea95be7e80c757bce5c48dd42 100644 --- a/src/corelib/tools/qset.qdoc +++ b/src/corelib/tools/qset.qdoc @@ -113,39 +113,6 @@ compiled in C++11 mode. */ -/*! - \fn QSet::QSet(const QSet<T> &other) - - Constructs a copy of \a other. - - This operation occurs in \l{constant time}, because QSet is - \l{implicitly shared}. This makes returning a QSet from a - function very fast. If a shared instance is modified, it will be - copied (copy-on-write), and this takes \l{linear time}. - - \sa operator=() -*/ - -/*! - \fn QSet::QSet(QSet && other) - - Move-constructs a QSet instance, making it point to the same object that \a other was pointing to. -*/ - - -/*! - \fn QSet<T> &QSet::operator=(const QSet<T> &other) - - Assigns the \a other set to this set and returns a reference to - this set. -*/ - -/*! - \fn QSet<T> &QSet::operator=(QSet<T> &&other) - - Move-assigns the \a other set to this set. -*/ - /*! \fn void QSet::swap(QSet<T> &other) diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h index a9f71c7b57f968b8e4a0d855c8fbd8ce111a863d..6a0900cf3f08177d0bcbf4125a5643760366c771 100644 --- a/src/corelib/tools/qshareddata.h +++ b/src/corelib/tools/qshareddata.h @@ -79,7 +79,7 @@ public: inline bool operator==(const QSharedDataPointer<T> &other) const { return d == other.d; } inline bool operator!=(const QSharedDataPointer<T> &other) const { return d != other.d; } - inline QSharedDataPointer() { d = 0; } + inline QSharedDataPointer() { d = Q_NULLPTR; } inline ~QSharedDataPointer() { if (d && !d->ref.deref()) delete d; } explicit QSharedDataPointer(T *data) Q_DECL_NOTHROW; @@ -145,17 +145,17 @@ public: if(d && !d->ref.deref()) delete d; - d = 0; + d = Q_NULLPTR; } - inline operator bool () const { return d != 0; } + inline operator bool () const { return d != Q_NULLPTR; } inline bool operator==(const QExplicitlySharedDataPointer<T> &other) const { return d == other.d; } inline bool operator!=(const QExplicitlySharedDataPointer<T> &other) const { return d != other.d; } inline bool operator==(const T *ptr) const { return d == ptr; } inline bool operator!=(const T *ptr) const { return d != ptr; } - inline QExplicitlySharedDataPointer() { d = 0; } + inline QExplicitlySharedDataPointer() { d = Q_NULLPTR; } inline ~QExplicitlySharedDataPointer() { if (d && !d->ref.deref()) delete d; } explicit QExplicitlySharedDataPointer(T *data) Q_DECL_NOTHROW; diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 3d20f4dca96f2593b2604bbfad1ae42e55ca9352..1323dd6b1c3abb6ae5b22598381dbfb04b154c5d 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -300,12 +300,12 @@ public: inline T *data() const { return value; } inline bool isNull() const { return !data(); } - inline operator RestrictedBool() const { return isNull() ? 0 : &QSharedPointer::value; } + inline operator RestrictedBool() const { return isNull() ? Q_NULLPTR : &QSharedPointer::value; } inline bool operator !() const { return isNull(); } inline T &operator*() const { return *data(); } inline T *operator->() const { return data(); } - QSharedPointer() : value(0), d(0) { } + QSharedPointer() : value(Q_NULLPTR), d(Q_NULLPTR) { } ~QSharedPointer() { deref(); } inline explicit QSharedPointer(T *ptr) : value(ptr) // noexcept @@ -327,14 +327,32 @@ public: inline QSharedPointer(QSharedPointer &&other) : value(other.value), d(other.d) { - other.d = 0; - other.value = 0; + other.d = Q_NULLPTR; + other.value = Q_NULLPTR; } inline QSharedPointer &operator=(QSharedPointer &&other) { - swap(other); + QSharedPointer moved(std::move(other)); + swap(moved); return *this; } + + template <class X> + QSharedPointer(QSharedPointer<X> &&other) Q_DECL_NOTHROW + : value(other.value), d(other.d) + { + other.d = Q_NULLPTR; + other.value = Q_NULLPTR; + } + + template <class X> + QSharedPointer &operator=(QSharedPointer<X> &&other) Q_DECL_NOTHROW + { + QSharedPointer moved(std::move(other)); + swap(moved); + return *this; + } + #endif template <class X> @@ -344,13 +362,13 @@ public: template <class X> inline QSharedPointer &operator=(const QSharedPointer<X> &other) { - QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X); // if you get an error in this line, the cast is invalid - internalCopy(other); + QSharedPointer copy(other); + swap(copy); return *this; } template <class X> - inline QSharedPointer(const QWeakPointer<X> &other) : value(0), d(0) + inline QSharedPointer(const QWeakPointer<X> &other) : value(Q_NULLPTR), d(Q_NULLPTR) { *this = other; } template <class X> @@ -466,9 +484,9 @@ public: private: explicit QSharedPointer(Qt::Initialization) {} - inline void deref() + void deref() Q_DECL_NOTHROW { deref(d); } - static inline void deref(Data *d) + static void deref(Data *d) Q_DECL_NOTHROW { if (!d) return; if (!d->strongref.deref()) { @@ -490,7 +508,7 @@ private: inline void internalConstruct(T *ptr, Deleter deleter) { if (!ptr) { - d = 0; + d = Q_NULLPTR; return; } @@ -509,19 +527,7 @@ private: enableSharedFromThis(ptr); } - template <class X> - inline void internalCopy(const QSharedPointer<X> &other) - { - Data *o = other.d; - T *actual = other.value; - if (o) - other.ref(); - qSwap(d, o); - qSwap(this->value, actual); - deref(o); - } - - inline void internalSwap(QSharedPointer &other) + void internalSwap(QSharedPointer &other) Q_DECL_NOTHROW { qSwap(d, other.d); qSwap(this->value, other.value); @@ -534,7 +540,7 @@ public: template <class X> friend class QWeakPointer; template <class X, class Y> friend QSharedPointer<X> QtSharedPointer::copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src); #endif - inline void ref() const { d->weakref.ref(); d->strongref.ref(); } + void ref() const Q_DECL_NOTHROW { d->weakref.ref(); d->strongref.ref(); } inline void internalSet(Data *o, T *actual) { @@ -553,14 +559,14 @@ public: o->weakref.ref(); } else { o->checkQObjectShared(actual); - o = 0; + o = Q_NULLPTR; } } qSwap(d, o); qSwap(this->value, actual); if (!d || d->strongref.load() == 0) - this->value = 0; + this->value = Q_NULLPTR; // dereference saved data deref(o); @@ -585,19 +591,19 @@ public: typedef const value_type &const_reference; typedef qptrdiff difference_type; - inline bool isNull() const { return d == 0 || d->strongref.load() == 0 || value == 0; } - inline operator RestrictedBool() const { return isNull() ? 0 : &QWeakPointer::value; } + inline bool isNull() const { return d == Q_NULLPTR || d->strongref.load() == 0 || value == Q_NULLPTR; } + inline operator RestrictedBool() const { return isNull() ? Q_NULLPTR : &QWeakPointer::value; } inline bool operator !() const { return isNull(); } - inline T *data() const { return d == 0 || d->strongref.load() == 0 ? 0 : value; } + inline T *data() const { return d == Q_NULLPTR || d->strongref.load() == 0 ? Q_NULLPTR : value; } - Q_DECL_CONSTEXPR inline QWeakPointer() : d(0), value(0) { } + inline QWeakPointer() : d(Q_NULLPTR), value(Q_NULLPTR) { } inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; } #ifndef QT_NO_QOBJECT // special constructor that is enabled only if X derives from QObject #if QT_DEPRECATED_SINCE(5, 0) template <class X> - QT_DEPRECATED inline QWeakPointer(X *ptr) : d(ptr ? Data::getAndRef(ptr) : 0), value(ptr) + QT_DEPRECATED inline QWeakPointer(X *ptr) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr) { } #endif #endif @@ -631,7 +637,7 @@ public: } template <class X> - inline QWeakPointer(const QWeakPointer<X> &o) : d(0), value(0) + inline QWeakPointer(const QWeakPointer<X> &o) : d(Q_NULLPTR), value(Q_NULLPTR) { *this = o; } template <class X> @@ -652,7 +658,7 @@ public: { return !(*this == o); } template <class X> - inline QWeakPointer(const QSharedPointer<X> &o) : d(0), value(0) + inline QWeakPointer(const QSharedPointer<X> &o) : d(Q_NULLPTR), value(Q_NULLPTR) { *this = o; } template <class X> @@ -696,7 +702,7 @@ public: #ifndef QT_NO_QOBJECT template <class X> - inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : 0), value(ptr) + inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr) { } #endif diff --git a/src/corelib/tools/qstack.cpp b/src/corelib/tools/qstack.cpp index e367622c0dab78d6ddf676caf50fd2e08a0ae2f8..224f72926b32e46cec74a4a625c5c8a277e3e5b6 100644 --- a/src/corelib/tools/qstack.cpp +++ b/src/corelib/tools/qstack.cpp @@ -70,19 +70,6 @@ \sa QVector, QQueue */ -/*! - \fn QStack::QStack() - - Constructs an empty stack. -*/ - -/*! - \fn QStack::~QStack() - - Destroys the stack. References to the values in the stack, and all - iterators over this stack, become invalid. -*/ - /*! \fn void QStack::swap(QStack<T> &other) \since 4.8 diff --git a/src/corelib/tools/qstack.h b/src/corelib/tools/qstack.h index fa05e22de1617fce701064391ccef232f573acbb..278e89ca2fdbefb2100b39b88519d29404605083 100644 --- a/src/corelib/tools/qstack.h +++ b/src/corelib/tools/qstack.h @@ -43,8 +43,7 @@ template<class T> class QStack : public QVector<T> { public: - inline QStack() {} - inline ~QStack() {} + // compiler-generated special member functions are fine! inline void swap(QStack<T> &other) { QVector<T>::swap(other); } // prevent QVector<->QStack swaps inline void push(const T &t) { QVector<T>::append(t); } T pop(); diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 2585686156677b95b2866ac39d51c4ead29526b7..345114d90783343cbea01400cee4084330d023c6 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -273,9 +273,9 @@ static inline __m128i mergeQuestionMarks(__m128i chunk) // that they are doing the right thing. Inverting the arguments in the // instruction does cause a bunch of test failures. - const int mode = _SIDD_UWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK; const __m128i rangeMatch = _mm_cvtsi32_si128(0xffff0100); - const __m128i offLimitMask = _mm_cmpestrm(rangeMatch, 2, chunk, 8, mode); + const __m128i offLimitMask = _mm_cmpestrm(rangeMatch, 2, chunk, 8, + _SIDD_UWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK); // replace the non-Latin 1 characters in the chunk with question marks chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask); @@ -1200,6 +1200,22 @@ const QString::Null QString::null = { }; \sa QString::const_iterator */ +/*! \typedef QString::const_reverse_iterator + \since 5.6 + + This typedef provides an STL-style const reverse iterator for QString. + + \sa QString::reverse_iterator, QString::const_iterator +*/ + +/*! \typedef QString::reverse_iterator + \since 5.6 + + This typedef provides an STL-style non-const reverse iterator for QString. + + \sa QString::const_reverse_iterator, QString::iterator +*/ + /*! \typedef QString::size_type @@ -1303,6 +1319,52 @@ const QString::Null QString::null = { }; \sa constBegin(), end() */ +/*! \fn QString::reverse_iterator QString::rbegin() + \since 5.6 + + Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to the first + character in the string, in reverse order. + + \sa begin(), crbegin(), rend() +*/ + +/*! \fn QString::const_reverse_iterator QString::rbegin() const + \since 5.6 + \overload +*/ + +/*! \fn QString::const_reverse_iterator QString::crbegin() const + \since 5.6 + + Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to the first + character in the string, in reverse order. + + \sa begin(), rbegin(), rend() +*/ + +/*! \fn QString::reverse_iterator QString::rend() + \since 5.6 + + Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to one past + the last character in the string, in reverse order. + + \sa end(), crend(), rbegin() +*/ + +/*! \fn QString::const_reverse_iterator QString::rend() const + \since 5.6 + \overload +*/ + +/*! \fn QString::const_reverse_iterator QString::crend() const + \since 5.6 + + Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to one + past the last character in the string, in reverse order. + + \sa end(), rend(), rbegin() +*/ + /*! \fn QString::QString() @@ -2719,9 +2781,9 @@ bool QString::operator<(QLatin1String other) const go through QObject::tr(), for example. */ -/*! \fn bool QString::operator<=(const QString &s1, const QString &s2) +/*! \fn bool operator<=(const QString &s1, const QString &s2) - \relates Qstring + \relates QString Returns \c true if string \a s1 is lexically less than or equal to string \a s2; otherwise returns \c false. @@ -2767,7 +2829,7 @@ bool QString::operator<(QLatin1String other) const go through QObject::tr(), for example. */ -/*! \fn bool QString::operator>(const QString &s1, const QString &s2) +/*! \fn bool operator>(const QString &s1, const QString &s2) \relates QString Returns \c true if string \a s1 is lexically greater than string \a s2; @@ -3244,6 +3306,7 @@ struct QStringCapture int len; int no; }; +Q_DECLARE_TYPEINFO(QStringCapture, Q_PRIMITIVE_TYPE); #endif #ifndef QT_NO_REGEXP @@ -4207,8 +4270,8 @@ QString QString::section(const QRegularExpression &re, int start, int end, Secti Returns a substring that contains the \a n leftmost characters of the string. - The entire string is returned if \a n is greater than size() or - less than zero. + The entire string is returned if \a n is greater than or equal + to size(), or less than zero. \snippet qstring/main.cpp 31 @@ -4225,8 +4288,8 @@ QString QString::left(int n) const Returns a substring that contains the \a n rightmost characters of the string. - The entire string is returned if \a n is greater than size() or - less than zero. + The entire string is returned if \a n is greater than or equal + to size(), or less than zero. \snippet qstring/main.cpp 48 @@ -4880,7 +4943,7 @@ modifiable reference. If \a position is negative, it is equivalent to passing zero. - \sa chop(), resize(), left() + \sa chop(), resize(), left(), QStringRef::truncate() */ void QString::truncate(int pos) @@ -4893,7 +4956,8 @@ void QString::truncate(int pos) /*! Removes \a n characters from the end of the string. - If \a n is greater than size(), the result is an empty string. + If \a n is greater than or equal to size(), the result is an + empty string. Example: \snippet qstring/main.cpp 15 @@ -7264,6 +7328,25 @@ QString QString::arg(const QString &a, int fieldWidth, QChar fillChar) const difference if \a a1 contains e.g. \c{%1}: \snippet qstring/main.cpp 13 + + A similar problem occurs when the numbered place markers are not + white space separated: + + \snippet qstring/main.cpp 12 + \snippet qstring/main.cpp 97 + + Let's look at the substitutions: + \list + \li First, \c Hello replaces \c {%1} so the string becomes \c {"Hello%3%2"}. + \li Then, \c 20 replaces \c {%2} so the string becomes \c {"Hello%320"}. + \li Since the maximum numbered place marker value is 99, \c 50 replaces \c {%32}. + \endlist + Thus the string finally becomes \c {"Hello500"}. + + In such cases, the following yields the expected results: + + \snippet qstring/main.cpp 12 + \snippet qstring/main.cpp 98 */ /*! @@ -9233,8 +9316,8 @@ QString &QString::append(const QStringRef &str) Returns a substring reference to the \a n leftmost characters of the string. - If \a n is greater than size() or less than zero, a reference to the entire - string is returned. + If \a n is greater than or equal to size(), or less than zero, + a reference to the entire string is returned. \sa right(), mid(), startsWith() */ @@ -9251,8 +9334,8 @@ QStringRef QStringRef::left(int n) const Returns a substring reference to the \a n leftmost characters of the string. - If \a n is greater than size() or less than zero, a reference to the entire - string is returned. + If \a n is greater than or equal to size(), or less than zero, + a reference to the entire string is returned. \snippet qstring/main.cpp leftRef @@ -9272,8 +9355,8 @@ QStringRef QString::leftRef(int n) const Returns a substring reference to the \a n rightmost characters of the string. - If \a n is greater than size() or less than zero, a reference to the entire - string is returned. + If \a n is greater than or equal to size(), or less than zero, + a reference to the entire string is returned. \sa left(), mid(), endsWith() */ @@ -9290,8 +9373,8 @@ QStringRef QStringRef::right(int n) const Returns a substring reference to the \a n rightmost characters of the string. - If \a n is greater than size() or less than zero, a reference to the entire - string is returned. + If \a n is greater than or equal to size(), or less than zero, + a reference to the entire string is returned. \snippet qstring/main.cpp rightRef @@ -9375,6 +9458,20 @@ QStringRef QString::midRef(int position, int n) const return QStringRef(); } +/*! + \fn void QStringRef::truncate(int position) + \since 5.6 + + Truncates the string at the given \a position index. + + If the specified \a position index is beyond the end of the + string, nothing happens. + + If \a position is negative, it is equivalent to passing zero. + + \sa QString::truncate() +*/ + /*! \since 4.8 diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 670d94279d8dabf47402d6603b826614c8dac08c..643378a7bda1c949a54af0c386149e2ecf13bcaf 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -44,6 +44,7 @@ #include <QtCore/qnamespace.h> #include <string> +#include <iterator> #if defined(Q_OS_ANDROID) // std::wstring is disabled on android's glibc, as bionic lacks certain features @@ -594,16 +595,16 @@ public: static int localeAwareCompare(const QString& s1, const QStringRef& s2); // ### Qt6: make inline except for the long long versions - short toShort(bool *ok=0, int base=10) const; - ushort toUShort(bool *ok=0, int base=10) const; - int toInt(bool *ok=0, int base=10) const; - uint toUInt(bool *ok=0, int base=10) const; - long toLong(bool *ok=0, int base=10) const; - ulong toULong(bool *ok=0, int base=10) const; - qlonglong toLongLong(bool *ok=0, int base=10) const; - qulonglong toULongLong(bool *ok=0, int base=10) const; - float toFloat(bool *ok=0) const; - double toDouble(bool *ok=0) const; + short toShort(bool *ok=Q_NULLPTR, int base=10) const; + ushort toUShort(bool *ok=Q_NULLPTR, int base=10) const; + int toInt(bool *ok=Q_NULLPTR, int base=10) const; + uint toUInt(bool *ok=Q_NULLPTR, int base=10) const; + long toLong(bool *ok=Q_NULLPTR, int base=10) const; + ulong toULong(bool *ok=Q_NULLPTR, int base=10) const; + qlonglong toLongLong(bool *ok=Q_NULLPTR, int base=10) const; + qulonglong toULongLong(bool *ok=Q_NULLPTR, int base=10) const; + float toFloat(bool *ok=Q_NULLPTR) const; + double toDouble(bool *ok=Q_NULLPTR) const; QString &setNum(short, int base=10); QString &setNum(ushort, int base=10); @@ -715,14 +716,22 @@ public: typedef const QChar *const_iterator; typedef iterator Iterator; typedef const_iterator ConstIterator; - iterator begin(); - const_iterator begin() const; - const_iterator cbegin() const; - const_iterator constBegin() const; - iterator end(); - const_iterator end() const; - const_iterator cend() const; - const_iterator constEnd() const; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + inline iterator begin(); + inline const_iterator begin() const; + inline const_iterator cbegin() const; + inline const_iterator constBegin() const; + inline iterator end(); + inline const_iterator end() const; + inline const_iterator cend() const; + inline const_iterator constEnd() const; + reverse_iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } + const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } // STL compatibility typedef int size_type; @@ -1350,28 +1359,32 @@ public: typedef QString::const_reference const_reference; // ### Qt 6: make this constructor constexpr, after the destructor is made trivial - inline QStringRef():m_string(0), m_position(0), m_size(0){} + inline QStringRef() : m_string(Q_NULLPTR), m_position(0), m_size(0) {} inline QStringRef(const QString *string, int position, int size); inline QStringRef(const QString *string); - // ### Qt 6: remove this copy constructor, the implicit one is fine - inline QStringRef(const QStringRef &other) +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) + // ### Qt 6: remove all of these, the implicit ones are fine + QStringRef(const QStringRef &other) Q_DECL_NOTHROW :m_string(other.m_string), m_position(other.m_position), m_size(other.m_size) {} - - // ### Qt 6: remove this destructor, the implicit one is fine +#ifdef Q_COMPILER_RVALUE_REFS + QStringRef(QStringRef &&other) Q_DECL_NOTHROW : m_string(other.m_string), m_position(other.m_position), m_size(other.m_size) {} + QStringRef &operator=(QStringRef &&other) Q_DECL_NOTHROW { return *this = other; } +#endif + QStringRef &operator=(const QStringRef &other) Q_DECL_NOTHROW { + m_string = other.m_string; m_position = other.m_position; + m_size = other.m_size; return *this; + } inline ~QStringRef(){} +#endif // Qt < 6.0.0 + inline const QString *string() const { return m_string; } inline int position() const { return m_position; } inline int size() const { return m_size; } inline int count() const { return m_size; } inline int length() const { return m_size; } - inline QStringRef &operator=(const QStringRef &other) { - m_string = other.m_string; m_position = other.m_position; - m_size = other.m_size; return *this; - } - int indexOf(const QString &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; int indexOf(QChar ch, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; int indexOf(QLatin1String str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; @@ -1399,6 +1412,8 @@ public: QStringRef right(int n) const Q_REQUIRED_RESULT; QStringRef mid(int pos, int n = -1) const Q_REQUIRED_RESULT; + void truncate(int pos) Q_DECL_NOTHROW { m_size = qBound(0, pos, m_size); } + bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; bool startsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; bool startsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; @@ -1432,10 +1447,10 @@ public: QByteArray toLocal8Bit() const Q_REQUIRED_RESULT; QVector<uint> toUcs4() const Q_REQUIRED_RESULT; - inline void clear() { m_string = 0; m_position = m_size = 0; } + inline void clear() { m_string = Q_NULLPTR; m_position = m_size = 0; } QString toString() const; inline bool isEmpty() const { return m_size == 0; } - inline bool isNull() const { return m_string == 0 || m_string->isNull(); } + inline bool isNull() const { return m_string == Q_NULLPTR || m_string->isNull(); } QStringRef appendTo(QString *string) const; @@ -1468,16 +1483,16 @@ public: static int localeAwareCompare(const QStringRef &s1, const QStringRef &s2); QStringRef trimmed() const Q_REQUIRED_RESULT; - short toShort(bool *ok = 0, int base = 10) const; - ushort toUShort(bool *ok = 0, int base = 10) const; - int toInt(bool *ok = 0, int base = 10) const; - uint toUInt(bool *ok = 0, int base = 10) const; - long toLong(bool *ok = 0, int base = 10) const; - ulong toULong(bool *ok = 0, int base = 10) const; - qlonglong toLongLong(bool *ok = 0, int base = 10) const; - qulonglong toULongLong(bool *ok = 0, int base = 10) const; - float toFloat(bool *ok = 0) const; - double toDouble(bool *ok = 0) const; + short toShort(bool *ok = Q_NULLPTR, int base = 10) const; + ushort toUShort(bool *ok = Q_NULLPTR, int base = 10) const; + int toInt(bool *ok = Q_NULLPTR, int base = 10) const; + uint toUInt(bool *ok = Q_NULLPTR, int base = 10) const; + long toLong(bool *ok = Q_NULLPTR, int base = 10) const; + ulong toULong(bool *ok = Q_NULLPTR, int base = 10) const; + qlonglong toLongLong(bool *ok = Q_NULLPTR, int base = 10) const; + qulonglong toULongLong(bool *ok = Q_NULLPTR, int base = 10) const; + float toFloat(bool *ok = Q_NULLPTR) const; + double toDouble(bool *ok = Q_NULLPTR) const; }; Q_DECLARE_TYPEINFO(QStringRef, Q_PRIMITIVE_TYPE); diff --git a/src/corelib/tools/qtextboundaryfinder.h b/src/corelib/tools/qtextboundaryfinder.h index beec5de60710d485af3b1567110da609e91cd013..a79fb50dad218d08b4a94d68914e5d4baf33024d 100644 --- a/src/corelib/tools/qtextboundaryfinder.h +++ b/src/corelib/tools/qtextboundaryfinder.h @@ -68,7 +68,7 @@ public: Q_DECLARE_FLAGS( BoundaryReasons, BoundaryReason ) QTextBoundaryFinder(BoundaryType type, const QString &string); - QTextBoundaryFinder(BoundaryType type, const QChar *chars, int length, unsigned char *buffer = 0, int bufferSize = 0); + QTextBoundaryFinder(BoundaryType type, const QChar *chars, int length, unsigned char *buffer = Q_NULLPTR, int bufferSize = 0); inline bool isValid() const { return d; } diff --git a/src/corelib/tools/qtimeline.h b/src/corelib/tools/qtimeline.h index 21139b37a847d5e584fee3386e11bb60d1d68ab1..94e60dce459f1928772a0862b5956924dcba075d 100644 --- a/src/corelib/tools/qtimeline.h +++ b/src/corelib/tools/qtimeline.h @@ -70,7 +70,7 @@ public: CosineCurve }; - explicit QTimeLine(int duration = 1000, QObject *parent = 0); + explicit QTimeLine(int duration = 1000, QObject *parent = Q_NULLPTR); virtual ~QTimeLine(); State state() const; diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp index 3627045a4001d09883d083257c8ad9031c34900f..45ae23cdf523bd5dd2a2a0484ae661c3efc1c5f5 100644 --- a/src/corelib/tools/qtimezone.cpp +++ b/src/corelib/tools/qtimezone.cpp @@ -312,7 +312,7 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz); \typedef QTimeZone::OffsetDataList \relates QTimeZone - Synonym for QList<OffsetData>. + Synonym for QVector<OffsetData>. */ /*! @@ -764,6 +764,7 @@ QTimeZone::OffsetDataList QTimeZone::transitions(const QDateTime &fromDateTime, if (hasTransitions()) { QTimeZonePrivate::DataList plist = d->transitions(fromDateTime.toMSecsSinceEpoch(), toDateTime.toMSecsSinceEpoch()); + list.reserve(plist.count()); foreach (const QTimeZonePrivate::Data &pdata, plist) list.append(d->toOffsetData(pdata)); } diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp index 8e6a0a0578514174ea7c692e06a97abb8bd8920c..5bc3610af00f268fe89dd041d32e460b7d815b59 100644 --- a/src/corelib/tools/qtimezoneprivate.cpp +++ b/src/corelib/tools/qtimezoneprivate.cpp @@ -700,6 +700,7 @@ QByteArray QUtcTimeZonePrivate::systemTimeZoneId() const QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds() const { QList<QByteArray> result; + result.reserve(utcDataTableSize); for (int i = 0; i < utcDataTableSize; ++i) result << utcId(utcData(i)); std::sort(result.begin(), result.end()); // ### or already sorted?? diff --git a/src/corelib/tools/qtimezoneprivate_p.h b/src/corelib/tools/qtimezoneprivate_p.h index e15ac801bc9ebe012a5942daf6943f4004554df7..14aeac3a0223fe2d412db3eba6f03f4f03858e22 100644 --- a/src/corelib/tools/qtimezoneprivate_p.h +++ b/src/corelib/tools/qtimezoneprivate_p.h @@ -165,6 +165,7 @@ public: protected: QByteArray m_id; }; +Q_DECLARE_TYPEINFO(QTimeZonePrivate::Data, Q_MOVABLE_TYPE); template<> QTimeZonePrivate *QSharedDataPointer<QTimeZonePrivate>::clone(); diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp index 29f0e17012a1ef99dea4d313e8d44c4ba5eecf96..7c5e5bd2cf8b2a629c3a11d89366c434bae97c55 100644 --- a/src/corelib/tools/qtimezoneprivate_tz.cpp +++ b/src/corelib/tools/qtimezoneprivate_tz.cpp @@ -630,6 +630,7 @@ void QTzTimeZonePrivate::init(const QByteArray &ianaId) } // Now for each transition time calculate our rule and save them + m_tranTimes.reserve(tranList.count()); foreach (const QTzTransition &tz_tran, tranList) { QTzTransitionTime tran; QTzTransitionRule rule; diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp index b57954dc03c2c64badfd800cd7c28f5f47a020bd..9afd2c624a55ef06a5878e22bbeceea91467ad29 100644 --- a/src/corelib/tools/qvector.cpp +++ b/src/corelib/tools/qvector.cpp @@ -45,34 +45,42 @@ stores its items in adjacent memory locations and provides fast index-based access. - QList\<T\>, QLinkedList\<T\>, and QVarLengthArray\<T\> provide - similar functionality. Here's an overview: + QList\<T\>, QLinkedList\<T\>, QVector\<T\>, and QVarLengthArray\<T\> + provide similar APIs and functionality. They are often interchangeable, + but there are performance consequences. Here is an overview of use cases: \list - \li For most purposes, QList is the right class to use. Operations - like prepend() and insert() are usually faster than with - QVector because of the way QList stores its items in memory - (see \l{Algorithmic Complexity} for details), - and its index-based API is more convenient than QLinkedList's - iterator-based API. It also expands to less code in your - executable. - \li If you need a real linked list, with guarantees of \l{constant - time} insertions in the middle of the list and iterators to - items rather than indexes, use QLinkedList. - \li If you want the items to occupy adjacent memory positions, or - if your items are larger than a pointer and you want to avoid - the overhead of allocating them on the heap individually at - insertion time, then use QVector. - \li If you want a low-level variable-size array, QVarLengthArray - may be sufficient. + \li QVector should be your default first choice. + QVector\<T\> will usually give better performance than QList\<T\>, + because QVector\<T\> always stores its items sequentially in memory, + where QList\<T\> will allocate its items on the heap unless + \c {sizeof(T) <= sizeof(void*)} and T has been declared to be + either a \c{Q_MOVABLE_TYPE} or a \c{Q_PRIMITIVE_TYPE} using + \l {Q_DECLARE_TYPEINFO}. See the \l {Pros and Cons of Using QList} + for an explanation. + \li However, QList is used throughout the Qt APIs for passing + parameters and for returning values. Use QList to interface with + those APIs. + \li If you need a real linked list, which guarantees + \l{Algorithmic Complexity}{constant time} insertions mid-list and + uses iterators to items rather than indexes, use QLinkedList. \endlist + \note QVector and QVarLengthArray both guarantee C-compatible + array layout. QList does not. This might be important if your + application must interface with a C API. + + \note Iterators into a QLinkedList and references into + heap-allocating QLists remain valid long as the referenced items + remain in the container. This is not true for iterators and + references into a QVector and non-heap-allocating QLists. + Here's an example of a QVector that stores integers and a QVector that stores QString values: \snippet code/src_corelib_tools_qvector.cpp 0 - QVector stores a vector (or array) of items. Typically, vectors + QVector stores its items in a vector (array). Typically, vectors are created with an initial size. For example, the following code constructs a QVector with 200 elements: @@ -166,6 +174,11 @@ with references to its own values. Doing so will cause your application to abort with an error message. + \section2 More Information on Using Qt Containers + + For a detailed discussion comparing Qt containers with each other and + with STL containers, see \l {Understand the Qt Containers}. + \sa QVectorIterator, QMutableVectorIterator, QList, QLinkedList */ @@ -218,10 +231,11 @@ Constructs a copy of \a other. - This operation takes \l{constant time}, because QVector is - \l{implicitly shared}. This makes returning a QVector from a - function very fast. If a shared instance is modified, it will be - copied (copy-on-write), and that takes \l{linear time}. + This operation takes \l{Algorithmic Complexity}{constant time}, + because QVector is \l{implicitly shared}. This makes returning + a QVector from a function very fast. If a shared instance is + modified, it will be copied (copy-on-write), and that takes + \l{Algorithmic Complexity}{linear time}. \sa operator=() */ @@ -522,6 +536,16 @@ \sa operator<<(), prepend(), insert() */ +/*! + \fn void QVector::append(T &&value) + \since 5.6 + + \overload + + Example: + \snippet code/src_corelib_tools_qvector.cpp move-append +*/ + /*! \fn void QVector::append(const QVector<T> &value) \overload @@ -688,6 +712,16 @@ \sa takeFirst(), takeLast(), QList::takeAt() */ +/*! \fn void QVector::move(int from, int to) + \since 5.6 + + Moves the item at index position \a from to index position \a to. + + Provided for compatibility with QList. + + \sa QList::move() +*/ + /*! \fn void QVector::removeFirst() \since 5.1 Removes the first item in the vector. Calling this function is @@ -1016,6 +1050,11 @@ to append(\a value). */ +/*! \fn void QVector::push_back(T &&value) + \since 5.6 + \overload +*/ + /*! \fn void QVector::push_front(const T &value) This function is provided for STL compatibility. It is equivalent diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 2adf2d4522bea14fae0cb57c8f0a6650e4dc43d1..890dbd317da63ba8eecf656f00a679ea163f7c2a 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -69,11 +69,11 @@ public: inline ~QVector() { if (!d->ref.deref()) freeData(d); } QVector<T> &operator=(const QVector<T> &v); #ifdef Q_COMPILER_RVALUE_REFS - inline QVector(QVector<T> &&other) : d(other.d) { other.d = Data::sharedNull(); } - inline QVector<T> operator=(QVector<T> &&other) - { qSwap(d, other.d); return *this; } + QVector(QVector<T> &&other) Q_DECL_NOTHROW : d(other.d) { other.d = Data::sharedNull(); } + QVector<T> &operator=(QVector<T> &&other) Q_DECL_NOTHROW + { QVector moved(std::move(other)); swap(moved); return *this; } #endif - inline void swap(QVector<T> &other) { qSwap(d, other.d); } + void swap(QVector<T> &other) Q_DECL_NOTHROW { qSwap(d, other.d); } #ifdef Q_COMPILER_INITIALIZER_LISTS inline QVector(std::initializer_list<T> args); #endif @@ -129,6 +129,9 @@ public: T &operator[](int i); const T &operator[](int i) const; void append(const T &t); +#ifdef Q_COMPILER_RVALUE_REFS + void append(T &&t); +#endif inline void append(const QVector<T> &l) { *this += l; } void prepend(const T &t); void insert(int i, const T &t); @@ -172,6 +175,19 @@ public: } int length() const { return size(); } T takeAt(int i) { T t = at(i); remove(i); return t; } + void move(int from, int to) + { + Q_ASSERT_X(from >= 0 && from < size(), "QVector::move(int,int)", "'from' is out-of-range"); + Q_ASSERT_X(to >= 0 && to < size(), "QVector::move(int,int)", "'to' is out-of-range"); + if (from == to) // don't detach when no-op + return; + detach(); + T * const b = d->begin(); + if (from < to) + std::rotate(b + from, b + from + 1, b + to + 1); + else + std::rotate(b + to, b + from, b + from + 1); + } // STL-style typedef typename Data::iterator iterator; @@ -180,29 +196,29 @@ public: typedef std::reverse_iterator<const_iterator> const_reverse_iterator; #if !defined(QT_STRICT_ITERATORS) || defined(Q_QDOC) inline iterator begin() { detach(); return d->begin(); } - inline const_iterator begin() const { return d->constBegin(); } - inline const_iterator cbegin() const { return d->constBegin(); } - inline const_iterator constBegin() const { return d->constBegin(); } + inline const_iterator begin() const Q_DECL_NOTHROW { return d->constBegin(); } + inline const_iterator cbegin() const Q_DECL_NOTHROW { return d->constBegin(); } + inline const_iterator constBegin() const Q_DECL_NOTHROW { return d->constBegin(); } inline iterator end() { detach(); return d->end(); } - inline const_iterator end() const { return d->constEnd(); } - inline const_iterator cend() const { return d->constEnd(); } - inline const_iterator constEnd() const { return d->constEnd(); } + inline const_iterator end() const Q_DECL_NOTHROW { return d->constEnd(); } + inline const_iterator cend() const Q_DECL_NOTHROW { return d->constEnd(); } + inline const_iterator constEnd() const Q_DECL_NOTHROW { return d->constEnd(); } #else inline iterator begin(iterator = iterator()) { detach(); return d->begin(); } - inline const_iterator begin(const_iterator = const_iterator()) const { return d->constBegin(); } - inline const_iterator cbegin(const_iterator = const_iterator()) const { return d->constBegin(); } - inline const_iterator constBegin(const_iterator = const_iterator()) const { return d->constBegin(); } + inline const_iterator begin(const_iterator = const_iterator()) const Q_DECL_NOTHROW { return d->constBegin(); } + inline const_iterator cbegin(const_iterator = const_iterator()) const Q_DECL_NOTHROW { return d->constBegin(); } + inline const_iterator constBegin(const_iterator = const_iterator()) const Q_DECL_NOTHROW { return d->constBegin(); } inline iterator end(iterator = iterator()) { detach(); return d->end(); } - inline const_iterator end(const_iterator = const_iterator()) const { return d->constEnd(); } - inline const_iterator cend(const_iterator = const_iterator()) const { return d->constEnd(); } - inline const_iterator constEnd(const_iterator = const_iterator()) const { return d->constEnd(); } + inline const_iterator end(const_iterator = const_iterator()) const Q_DECL_NOTHROW { return d->constEnd(); } + inline const_iterator cend(const_iterator = const_iterator()) const Q_DECL_NOTHROW { return d->constEnd(); } + inline const_iterator constEnd(const_iterator = const_iterator()) const Q_DECL_NOTHROW { return d->constEnd(); } #endif reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } - const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } - const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } - const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } + const_reverse_iterator rbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); } + const_reverse_iterator rend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); } + const_reverse_iterator crbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); } + const_reverse_iterator crend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); } iterator insert(iterator before, int n, const T &x); inline iterator insert(iterator before, const T &x) { return insert(before, 1, x); } iterator erase(iterator begin, iterator end); @@ -234,6 +250,9 @@ public: typedef const_iterator ConstIterator; typedef int size_type; inline void push_back(const T &t) { append(t); } +#ifdef Q_COMPILER_RVALUE_REFS + void push_back(T &&t) { append(std::move(t)); } +#endif inline void push_front(const T &t) { prepend(t); } void pop_back() { removeLast(); } void pop_front() { removeFirst(); } @@ -612,14 +631,14 @@ void QVector<T>::append(const T &t) { const bool isTooSmall = uint(d->size + 1) > d->alloc; if (!isDetached() || isTooSmall) { - const T copy(t); + T copy(t); QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default); reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt); if (QTypeInfo<T>::isComplex) - new (d->end()) T(copy); + new (d->end()) T(qMove(copy)); else - *d->end() = copy; + *d->end() = qMove(copy); } else { if (QTypeInfo<T>::isComplex) @@ -630,6 +649,22 @@ void QVector<T>::append(const T &t) ++d->size; } +#ifdef Q_COMPILER_RVALUE_REFS +template <typename T> +void QVector<T>::append(T &&t) +{ + const bool isTooSmall = uint(d->size + 1) > d->alloc; + if (!isDetached() || isTooSmall) { + QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default); + reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt); + } + + new (d->end()) T(std::move(t)); + + ++d->size; +} +#endif + template <typename T> void QVector<T>::removeLast() { diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp index 660f40b107d685c762c544f0d727b16fb88bd25e..4197fc47b1ad814bc1b8fae7c773a8d1173d0490 100644 --- a/src/corelib/tools/qversionnumber.cpp +++ b/src/corelib/tools/qversionnumber.cpp @@ -32,7 +32,7 @@ ** ****************************************************************************/ -#include <QtCore/private/qversionnumber_p.h> +#include <QtCore/qversionnumber.h> #include <QtCore/qhash.h> #include <QtCore/private/qlocale_tools_p.h> #include <QtCore/qcollator.h> @@ -53,8 +53,7 @@ QT_BEGIN_NAMESPACE /*! \class QVersionNumber \inmodule QtCore - \internal - \since 5.4 + \since 5.6 \brief The QVersionNumber class contains a version number with an arbitrary number of segments. @@ -168,6 +167,17 @@ QT_BEGIN_NAMESPACE \sa majorVersion(), minorVersion(), microVersion() */ +QVector<int> QVersionNumber::segments() const +{ + if (m_segments.isUsingPointer()) + return *m_segments.pointer_segments; + + QVector<int> result; + result.resize(segmentCount()); + for (int i = 0; i < segmentCount(); ++i) + result[i] = segmentAt(i); + return result; +} /*! \fn int QVersionNumber::segmentAt(int index) const @@ -196,6 +206,17 @@ QT_BEGIN_NAMESPACE \snippet qversionnumber/main.cpp 4 */ +QVersionNumber QVersionNumber::normalized() const +{ + int i; + for (i = m_segments.size(); i; --i) + if (m_segments.at(i - 1) != 0) + break; + + QVersionNumber result(*this); + result.m_segments.resize(i); + return result; +} /*! \fn bool QVersionNumber::isPrefixOf(const QVersionNumber &other) const @@ -209,8 +230,13 @@ QT_BEGIN_NAMESPACE */ bool QVersionNumber::isPrefixOf(const QVersionNumber &other) const Q_DECL_NOTHROW { - return m_segments.size() <= other.m_segments.size() && - std::equal(m_segments.begin(), m_segments.end(), other.m_segments.begin()); + if (segmentCount() > other.segmentCount()) + return false; + for (int i = 0; i < segmentCount(); ++i) { + if (segmentAt(i) != other.segmentAt(i)) + return false; + } + return true; } /*! @@ -228,30 +254,37 @@ bool QVersionNumber::isPrefixOf(const QVersionNumber &other) const Q_DECL_NOTHRO */ int QVersionNumber::compare(const QVersionNumber &v1, const QVersionNumber &v2) Q_DECL_NOTHROW { - QVector<int>::const_iterator i1 = v1.m_segments.constBegin(); - const QVector<int>::const_iterator e1 = v1.m_segments.constEnd(); - QVector<int>::const_iterator i2 = v2.m_segments.constBegin(); - const QVector<int>::const_iterator e2 = v2.m_segments.constEnd(); - - while (i1 != e1 && i2 != e2) { - if (*i1 != *i2) - return (*i1 - *i2); - ++i1; - ++i2; + int commonlen; + + if (Q_LIKELY(!v1.m_segments.isUsingPointer() && !v2.m_segments.isUsingPointer())) { + // we can't use memcmp because it interprets the data as unsigned bytes + const qint8 *ptr1 = v1.m_segments.inline_segments + InlineSegmentStartIdx; + const qint8 *ptr2 = v2.m_segments.inline_segments + InlineSegmentStartIdx; + commonlen = qMin(v1.m_segments.size(), + v2.m_segments.size()); + for (int i = 0; i < commonlen; ++i) + if (int x = ptr1[i] - ptr2[i]) + return x; + } else { + commonlen = qMin(v1.segmentCount(), v2.segmentCount()); + for (int i = 0; i < commonlen; ++i) { + if (v1.segmentAt(i) != v2.segmentAt(i)) + return v1.segmentAt(i) - v2.segmentAt(i); + } } // ran out of segments in v1 and/or v2 and need to check the first trailing // segment to finish the compare - if (i1 != e1) { + if (v1.segmentCount() > commonlen) { // v1 is longer - if (*i1 != 0) - return *i1; + if (v1.segmentAt(commonlen) != 0) + return v1.segmentAt(commonlen); else return 1; - } else if (i2 != e2) { + } else if (v2.segmentCount() > commonlen) { // v2 is longer - if (*i2 != 0) - return -*i2; + if (v2.segmentAt(commonlen) != 0) + return -v2.segmentAt(commonlen); else return -1; } @@ -271,13 +304,20 @@ int QVersionNumber::compare(const QVersionNumber &v1, const QVersionNumber &v2) QVersionNumber QVersionNumber::commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2) { - int min = qMin(v1.m_segments.size(), v2.m_segments.size()); - QVector<int>::const_iterator i1 = v1.m_segments.begin(); - QVector<int>::const_iterator e1; - e1 = std::mismatch(i1, - v1.m_segments.begin() + min, - v2.m_segments.begin()).first; - return QVersionNumber(v1.m_segments.mid(0, e1 - i1)); + int commonlen = qMin(v1.segmentCount(), v2.segmentCount()); + int i; + for (i = 0; i < commonlen; ++i) { + if (v1.segmentAt(i) != v2.segmentAt(i)) + break; + } + + if (i == 0) + return QVersionNumber(); + + // try to use the one with inline segments, if there's one + QVersionNumber result(!v1.m_segments.isUsingPointer() ? v1 : v2); + result.m_segments.resize(i); + return result; } /*! @@ -348,12 +388,12 @@ QVersionNumber QVersionNumber::commonPrefix(const QVersionNumber &v1, QString QVersionNumber::toString() const { QString version; - version.reserve(qMax(m_segments.size() * 2 - 1, 0)); + version.reserve(qMax(segmentCount() * 2 - 1, 0)); bool first = true; - for (QVector<int>::const_iterator it = m_segments.begin(), end = m_segments.end(); it != end; ++it) { + for (int i = 0; i < segmentCount(); ++i) { if (!first) version += QLatin1Char('.'); - version += QString::number(*it); + version += QString::number(segmentAt(i)); first = false; } return version; @@ -401,19 +441,17 @@ QVersionNumber QVersionNumber::fromString(const QString &string, int *suffixInde return QVersionNumber(qMove(seg)); } -/*! - \fn QVersionNumber QVersionNumber::normalizedImpl(QVector<int> &segs) - - Implementation of the normalized() function. Takes the movable list \a segs - and normalizes them. - - \internal - */ -QVersionNumber QVersionNumber::normalizedImpl(QVector<int> &segs) +void QVersionNumber::SegmentStorage::setVector(int len, int maj, int min, int mic) { - while (segs.size() && segs.last() == 0) - segs.pop_back(); - return QVersionNumber(qMove(segs)); + pointer_segments = new QVector<int>; + pointer_segments->resize(len); + pointer_segments->data()[0] = maj; + if (len > 1) { + pointer_segments->data()[1] = min; + if (len > 2) { + pointer_segments->data()[2] = mic; + } + } } #ifndef QT_NO_DATASTREAM @@ -442,7 +480,9 @@ QDataStream& operator<<(QDataStream &out, const QVersionNumber &version) */ QDataStream& operator>>(QDataStream &in, QVersionNumber &version) { - in >> version.m_segments; + if (!version.m_segments.isUsingPointer()) + version.m_segments.pointer_segments = new QVector<int>; + in >> *version.m_segments.pointer_segments; return in; } #endif @@ -459,14 +499,18 @@ QDebug operator<<(QDebug debug, const QVersionNumber &version) /*! \fn uint qHash(const QVersionNumber &key, uint seed) \relates QHash - \since 5.4 + \since 5.6 Returns the hash value for the \a key, using \a seed to seed the calculation. */ uint qHash(const QVersionNumber &key, uint seed) { - return qHashRange(key.m_segments.begin(), key.m_segments.end(), seed); + QtPrivate::QHashCombine hash; + for (int i = 0; i < key.segmentCount(); ++i) + seed = hash(seed, key.segmentAt(i)); + return seed; } QT_END_NAMESPACE + diff --git a/src/corelib/tools/qversionnumber.h b/src/corelib/tools/qversionnumber.h new file mode 100644 index 0000000000000000000000000000000000000000..ebf1844f38937e8acf8205883a5dafea8e213d3f --- /dev/null +++ b/src/corelib/tools/qversionnumber.h @@ -0,0 +1,313 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com> +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QVERSIONNUMBER_H +#define QVERSIONNUMBER_H + +#include <QtCore/qnamespace.h> +#include <QtCore/qstring.h> +#include <QtCore/qvector.h> +#include <QtCore/qmetatype.h> +#include <QtCore/qtypeinfo.h> + +QT_BEGIN_NAMESPACE + +class QVersionNumber; +Q_CORE_EXPORT uint qHash(const QVersionNumber &key, uint seed = 0); + +#ifndef QT_NO_DATASTREAM +Q_CORE_EXPORT QDataStream& operator<<(QDataStream &out, const QVersionNumber &version); +Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QVersionNumber &version); +#endif + +class QVersionNumber +{ + /* + * QVersionNumber stores small values inline, without memory allocation. + * We do that by setting the LSB in the pointer that would otherwise hold + * the longer form of the segments. + * The constants below help us deal with the permutations for 32- and 64-bit, + * little- and big-endian architectures. + */ + enum { + // in little-endian, inline_segments[0] is shared with the pointer's LSB, while + // in big-endian, it's inline_segments[7] + InlineSegmentMarker = Q_BYTE_ORDER == Q_LITTLE_ENDIAN ? 0 : sizeof(void*) - 1, + InlineSegmentStartIdx = !InlineSegmentMarker, // 0 for BE, 1 for LE + InlineSegmentCount = sizeof(void*) - 1 + }; + Q_STATIC_ASSERT(InlineSegmentCount >= 3); // at least major, minor, micro + + struct SegmentStorage { + // Note: we alias the use of dummy and inline_segments in the use of the + // union below. This is undefined behavior in C++98, but most compilers implement + // the C++11 behavior. The one known exception is older versions of Sun Studio. + union { + quintptr dummy; + qint8 inline_segments[sizeof(void*)]; + QVector<int> *pointer_segments; + }; + + // set the InlineSegmentMarker and set length to zero + SegmentStorage() Q_DECL_NOTHROW : dummy(1) {} + + SegmentStorage(const QVector<int> &seg) + { + if (dataFitsInline(seg.begin(), seg.size())) + setInlineData(seg.begin(), seg.size()); + else + pointer_segments = new QVector<int>(seg); + } + + SegmentStorage(const SegmentStorage &other) + { + if (other.isUsingPointer()) + pointer_segments = new QVector<int>(*other.pointer_segments); + else + dummy = other.dummy; + } + + SegmentStorage &operator=(const SegmentStorage &other) + { + if (isUsingPointer() && other.isUsingPointer()) { + *pointer_segments = *other.pointer_segments; + } else if (other.isUsingPointer()) { + pointer_segments = new QVector<int>(*other.pointer_segments); + } else { + if (isUsingPointer()) + delete pointer_segments; + dummy = other.dummy; + } + return *this; + } + +#ifdef Q_COMPILER_RVALUE_REFS + SegmentStorage(SegmentStorage &&other) Q_DECL_NOTHROW + : dummy(other.dummy) + { + other.dummy = 1; + } + + SegmentStorage &operator=(SegmentStorage &&other) Q_DECL_NOTHROW + { + qSwap(dummy, other.dummy); + return *this; + } + + explicit SegmentStorage(QVector<int> &&seg) + { + if (dataFitsInline(seg.begin(), seg.size())) + setInlineData(seg.begin(), seg.size()); + else + pointer_segments = new QVector<int>(std::move(seg)); + } +#endif +#ifdef Q_COMPILER_INITIALIZER_LISTS + SegmentStorage(std::initializer_list<int> args) + { + if (dataFitsInline(args.begin(), int(args.size()))) { + setInlineData(args.begin(), int(args.size())); + } else { + pointer_segments = new QVector<int>(args); + } + } +#endif + + ~SegmentStorage() { if (isUsingPointer()) delete pointer_segments; } + + bool isUsingPointer() const Q_DECL_NOTHROW + { return (inline_segments[InlineSegmentMarker] & 1) == 0; } + + int size() const Q_DECL_NOTHROW + { return isUsingPointer() ? pointer_segments->size() : (inline_segments[InlineSegmentMarker] >> 1); } + + void setInlineSize(int len) + { inline_segments[InlineSegmentMarker] = 1 + 2 * len; } + + void resize(int len) + { + if (isUsingPointer()) + pointer_segments->resize(len); + else + setInlineSize(len); + } + + int at(int index) const + { + return isUsingPointer() ? + pointer_segments->at(index) : + inline_segments[InlineSegmentStartIdx + index]; + } + + void setSegments(int len, int maj, int min = 0, int mic = 0) + { + if (maj == qint8(maj) && min == qint8(min) && mic == qint8(mic)) { + int data[] = { maj, min, mic }; + setInlineData(data, len); + } else { + setVector(len, maj, min, mic); + } + } + + private: + static bool dataFitsInline(const int *data, int len) + { + if (len > InlineSegmentCount) + return false; + for (int i = 0; i < len; ++i) + if (data[i] != qint8(data[i])) + return false; + return true; + } + void setInlineData(const int *data, int len) + { + dummy = 1 + len * 2; +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + for (int i = 0; i < len; ++i) + dummy |= quintptr(data[i] & 0xFF) << (8 * (i + 1)); +#elif Q_BYTE_ORDER == Q_BIG_ENDIAN + for (int i = 0; i < len; ++i) + dummy |= quintptr(data[i] & 0xFF) << (8 * (sizeof(void *) - i - 1)); +#else + // the code above is equivalent to: + setInlineSize(len); + for (int i = 0; i < len; ++i) + inline_segments[InlineSegmentStartIdx + i] = data[i] & 0xFF; +#endif + } + + Q_CORE_EXPORT void setVector(int len, int maj, int min, int mic); + } m_segments; + +public: + inline QVersionNumber() Q_DECL_NOTHROW + : m_segments() + {} + inline explicit QVersionNumber(const QVector<int> &seg) + : m_segments(seg) + {} + + // compiler-generated copy/move ctor/assignment operators and the destructor are ok + +#ifdef Q_COMPILER_RVALUE_REFS + explicit QVersionNumber(QVector<int> &&seg) + : m_segments(std::move(seg)) + {} +#endif + +#ifdef Q_COMPILER_INITIALIZER_LISTS + inline QVersionNumber(std::initializer_list<int> args) + : m_segments(args) + {} +#endif + + inline explicit QVersionNumber(int maj) + { m_segments.setSegments(1, maj); } + + inline explicit QVersionNumber(int maj, int min) + { m_segments.setSegments(2, maj, min); } + + inline explicit QVersionNumber(int maj, int min, int mic) + { m_segments.setSegments(3, maj, min, mic); } + + inline bool isNull() const Q_DECL_NOTHROW Q_REQUIRED_RESULT + { return segmentCount() == 0; } + + inline bool isNormalized() const Q_DECL_NOTHROW Q_REQUIRED_RESULT + { return isNull() || segmentAt(segmentCount() - 1) != 0; } + + inline int majorVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT + { return segmentAt(0); } + + inline int minorVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT + { return segmentAt(1); } + + inline int microVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT + { return segmentAt(2); } + + Q_CORE_EXPORT QVersionNumber normalized() const Q_REQUIRED_RESULT; + + Q_CORE_EXPORT QVector<int> segments() const Q_REQUIRED_RESULT; + + inline int segmentAt(int index) const Q_DECL_NOTHROW Q_REQUIRED_RESULT + { return (m_segments.size() > index) ? m_segments.at(index) : 0; } + + inline int segmentCount() const Q_DECL_NOTHROW Q_REQUIRED_RESULT + { return m_segments.size(); } + + Q_CORE_EXPORT bool isPrefixOf(const QVersionNumber &other) const Q_DECL_NOTHROW Q_REQUIRED_RESULT; + + Q_CORE_EXPORT static int compare(const QVersionNumber &v1, const QVersionNumber &v2) Q_DECL_NOTHROW Q_REQUIRED_RESULT; + + Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2) Q_REQUIRED_RESULT; + + Q_CORE_EXPORT QString toString() const Q_REQUIRED_RESULT; + Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = 0) Q_REQUIRED_RESULT; + +private: +#ifndef QT_NO_DATASTREAM + friend Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QVersionNumber &version); +#endif + friend Q_CORE_EXPORT uint qHash(const QVersionNumber &key, uint seed); +}; + +Q_DECLARE_TYPEINFO(QVersionNumber, Q_MOVABLE_TYPE); + +#ifndef QT_NO_DEBUG_STREAM +Q_CORE_EXPORT QDebug operator<<(QDebug, const QVersionNumber &version); +#endif + +Q_REQUIRED_RESULT inline bool operator> (const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW +{ return QVersionNumber::compare(lhs, rhs) > 0; } + +Q_REQUIRED_RESULT inline bool operator>=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW +{ return QVersionNumber::compare(lhs, rhs) >= 0; } + +Q_REQUIRED_RESULT inline bool operator< (const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW +{ return QVersionNumber::compare(lhs, rhs) < 0; } + +Q_REQUIRED_RESULT inline bool operator<=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW +{ return QVersionNumber::compare(lhs, rhs) <= 0; } + +Q_REQUIRED_RESULT inline bool operator==(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW +{ return QVersionNumber::compare(lhs, rhs) == 0; } + +Q_REQUIRED_RESULT inline bool operator!=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW +{ return QVersionNumber::compare(lhs, rhs) != 0; } + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QVersionNumber) + +#endif //QVERSIONNUMBER_H diff --git a/src/corelib/tools/qversionnumber_p.h b/src/corelib/tools/qversionnumber_p.h deleted file mode 100644 index 2da3103be328994ae3e41e8834086e27415ac623..0000000000000000000000000000000000000000 --- a/src/corelib/tools/qversionnumber_p.h +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QVERSIONNUMBER_H -#define QVERSIONNUMBER_H - -#include <QtCore/qnamespace.h> -#include <QtCore/qstring.h> -#include <QtCore/qvector.h> -#include <QtCore/qmetatype.h> -#include <QtCore/qtypeinfo.h> - -QT_BEGIN_NAMESPACE - -class QVersionNumber; -Q_CORE_EXPORT uint qHash(const QVersionNumber &key, uint seed = 0); - -#ifndef QT_NO_DATASTREAM -Q_CORE_EXPORT QDataStream& operator<<(QDataStream &out, const QVersionNumber &version); -Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QVersionNumber &version); -#endif - -class QVersionNumber -{ -public: - inline QVersionNumber() Q_DECL_NOTHROW - : m_segments() - {} - // compiler-generated copy/move ctor/assignment operators are ok - - inline explicit QVersionNumber(const QVector<int> &seg) Q_DECL_NOTHROW - : m_segments(seg) - {} -#ifdef Q_COMPILER_RVALUE_REFS - inline explicit QVersionNumber(QVector<int> &&seg) Q_DECL_NOTHROW - : m_segments(qMove(seg)) - {} -#endif -#ifdef Q_COMPILER_INITIALIZER_LISTS - inline QVersionNumber(std::initializer_list<int> args) - : m_segments(args) - {} -#endif - - inline explicit QVersionNumber(int maj) - { m_segments.reserve(1); m_segments << maj; } - - inline explicit QVersionNumber(int maj, int min) - { m_segments.reserve(2); m_segments << maj << min; } - - inline explicit QVersionNumber(int maj, int min, int mic) - { m_segments.reserve(3); m_segments << maj << min << mic; } - - inline bool isNull() const Q_DECL_NOTHROW Q_REQUIRED_RESULT - { return m_segments.isEmpty(); } - - inline bool isNormalized() const Q_DECL_NOTHROW Q_REQUIRED_RESULT - { return isNull() || m_segments.last() != 0; } - - inline int majorVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT - { return segmentAt(0); } - - inline int minorVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT - { return segmentAt(1); } - - inline int microVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT - { return segmentAt(2); } - -#if defined(Q_COMPILER_REF_QUALIFIERS) -# if defined(Q_CC_GNU) - // required due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61941 -# pragma push_macro("Q_REQUIRED_RESULT") -# undef Q_REQUIRED_RESULT -# define Q_REQUIRED_RESULT -# define Q_REQUIRED_RESULT_pushed -# endif - inline QVersionNumber normalized() const & Q_REQUIRED_RESULT - { - QVector<int> segs(m_segments); - return normalizedImpl(segs); - } - - inline QVersionNumber normalized() && Q_REQUIRED_RESULT - { - return normalizedImpl(m_segments); - } - - inline QVector<int> segments() const & Q_DECL_NOTHROW Q_REQUIRED_RESULT - { return m_segments; } - - inline QVector<int> segments() && Q_DECL_NOTHROW Q_REQUIRED_RESULT - { return qMove(m_segments); } - -# ifdef Q_REQUIRED_RESULT_pushed -# pragma pop_macro("Q_REQUIRED_RESULT") -# endif -#else - inline QVersionNumber normalized() const Q_REQUIRED_RESULT - { - QVector<int> segs(m_segments); - return normalizedImpl(segs); - } - - inline QVector<int> segments() const Q_DECL_NOTHROW Q_REQUIRED_RESULT - { return m_segments; } -#endif - - inline int segmentAt(int index) const Q_DECL_NOTHROW Q_REQUIRED_RESULT - { return (m_segments.size() > index) ? m_segments.at(index) : 0; } - - inline int segmentCount() const Q_DECL_NOTHROW Q_REQUIRED_RESULT - { return m_segments.size(); } - - Q_CORE_EXPORT bool isPrefixOf(const QVersionNumber &other) const Q_DECL_NOTHROW Q_REQUIRED_RESULT; - - Q_CORE_EXPORT static int compare(const QVersionNumber &v1, const QVersionNumber &v2) Q_DECL_NOTHROW Q_REQUIRED_RESULT; - - Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2) Q_REQUIRED_RESULT; - - Q_CORE_EXPORT QString toString() const Q_REQUIRED_RESULT; - Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = 0) Q_REQUIRED_RESULT; - -private: - Q_CORE_EXPORT static QVersionNumber normalizedImpl(QVector<int> &segs) Q_REQUIRED_RESULT; - -#ifndef QT_NO_DATASTREAM - friend Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QVersionNumber &version); -#endif - friend Q_CORE_EXPORT uint qHash(const QVersionNumber &key, uint seed); - - QVector<int> m_segments; -}; - -Q_DECLARE_TYPEINFO(QVersionNumber, Q_MOVABLE_TYPE); - -#ifndef QT_NO_DEBUG_STREAM -Q_CORE_EXPORT QDebug operator<<(QDebug, const QVersionNumber &version); -#endif - -Q_REQUIRED_RESULT inline bool operator> (const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW -{ return QVersionNumber::compare(lhs, rhs) > 0; } - -Q_REQUIRED_RESULT inline bool operator>=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW -{ return QVersionNumber::compare(lhs, rhs) >= 0; } - -Q_REQUIRED_RESULT inline bool operator< (const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW -{ return QVersionNumber::compare(lhs, rhs) < 0; } - -Q_REQUIRED_RESULT inline bool operator<=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW -{ return QVersionNumber::compare(lhs, rhs) <= 0; } - -Q_REQUIRED_RESULT inline bool operator==(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW -{ return QVersionNumber::compare(lhs, rhs) == 0; } - -Q_REQUIRED_RESULT inline bool operator!=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW -{ return QVersionNumber::compare(lhs, rhs) != 0; } - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(QVersionNumber) - -#endif //QVERSIONNUMBER_H diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index 0d19d54cba9e48cc84c7ffc253b8fa508a8ad3e5..c0c2442e55d2d596c34cd8b4117fb19faca3a102 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -9,6 +9,7 @@ HEADERS += \ tools/qarraydatapointer.h \ tools/qbitarray.h \ tools/qbytearray.h \ + tools/qbytearray_p.h \ tools/qbytearraylist.h \ tools/qbytearraymatcher.h \ tools/qbytedata_p.h \ @@ -74,7 +75,7 @@ HEADERS += \ tools/qunicodetools_p.h \ tools/qvarlengtharray.h \ tools/qvector.h \ - tools/qversionnumber_p.h + tools/qversionnumber.h SOURCES += \ diff --git a/src/corelib/xml/qxmlstream.h b/src/corelib/xml/qxmlstream.h index 21188bc5e0ffac6fc7785bc9d685f74ef28f6361..7b1ea624c5faf7c41e2fdfa5e22019f2048510a4 100644 --- a/src/corelib/xml/qxmlstream.h +++ b/src/corelib/xml/qxmlstream.h @@ -75,6 +75,28 @@ public: QXmlStreamAttribute(const QString &qualifiedName, const QString &value); QXmlStreamAttribute(const QString &namespaceUri, const QString &name, const QString &value); QXmlStreamAttribute(const QXmlStreamAttribute &); +#ifdef Q_COMPILER_RVALUE_REFS + QXmlStreamAttribute(QXmlStreamAttribute &&other) Q_DECL_NOTHROW // = default; + : m_name(std::move(other.m_name)), + m_namespaceUri(std::move(other.m_namespaceUri)), + m_qualifiedName(std::move(other.m_qualifiedName)), + m_value(std::move(other.m_value)), + reserved(other.reserved), + m_isDefault(other.m_isDefault) + { + other.reserved = Q_NULLPTR; + } + QXmlStreamAttribute &operator=(QXmlStreamAttribute &&other) Q_DECL_NOTHROW // = default; + { + m_name = std::move(other.m_name); + m_namespaceUri = std::move(other.m_namespaceUri); + m_qualifiedName = std::move(other.m_qualifiedName); + m_value = std::move(other.m_value); + qSwap(reserved, other.reserved); + m_isDefault = other.m_isDefault; + return *this; + } +#endif QXmlStreamAttribute& operator=(const QXmlStreamAttribute &); ~QXmlStreamAttribute(); inline QStringRef namespaceUri() const { return m_namespaceUri; } diff --git a/src/dbus/dbus.pro b/src/dbus/dbus.pro index 3ef8e6c80c490325ecdeb7f0e65f7b9c6ad4f9cb..ebeab5c1b09260bec1f7804306e8805ea922e881 100644 --- a/src/dbus/dbus.pro +++ b/src/dbus/dbus.pro @@ -16,7 +16,7 @@ contains(QT_CONFIG, dbus-linked) { } win32 { - wince*:LIBS_PRIVATE += -lws2 + wince: LIBS_PRIVATE += -lws2 else:LIBS_PRIVATE += -lws2_32 \ -ladvapi32 \ -lnetapi32 \ diff --git a/src/dbus/qdbus_symbols.cpp b/src/dbus/qdbus_symbols.cpp index b82d92b561389b1dc58df00cdedff83a1587b12f..395a436869ca197943cb3146a883047b8e700474 100644 --- a/src/dbus/qdbus_symbols.cpp +++ b/src/dbus/qdbus_symbols.cpp @@ -48,7 +48,7 @@ void (*qdbus_resolve_me(const char *name))(); #if !defined QT_LINKED_LIBDBUS -#ifndef QT_BOOTSTRAPPED +#ifndef QT_NO_LIBRARY static QLibrary *qdbus_libdbus = 0; void qdbus_unloadLibDBus() @@ -65,7 +65,7 @@ void qdbus_unloadLibDBus() bool qdbus_loadLibDBus() { -#ifndef QT_BOOTSTRAPPED +#ifndef QT_NO_LIBRARY #ifdef QT_BUILD_INTERNAL // this is to simulate a library load failure for our autotest suite. if (!qEnvironmentVariableIsEmpty("QT_SIMULATE_DBUS_LIBFAIL")) @@ -118,7 +118,7 @@ bool qdbus_loadLibDBus() #endif } -#ifndef QT_BOOTSTRAPPED +#ifndef QT_NO_LIBRARY void (*qdbus_resolve_conditionally(const char *name))() { if (qdbus_loadLibDBus()) @@ -129,7 +129,7 @@ void (*qdbus_resolve_conditionally(const char *name))() void (*qdbus_resolve_me(const char *name))() { -#ifndef QT_BOOTSTRAPPED +#ifndef QT_NO_LIBRARY if (!qdbus_loadLibDBus()) qFatal("Cannot find libdbus-1 in your system to resolve symbol '%s'.", name); @@ -144,7 +144,7 @@ void (*qdbus_resolve_me(const char *name))() #endif } -#else // QT_LINKED_LIBDBUS +#else static void qdbus_unloadLibDBus() { if (qEnvironmentVariableIsSet("QDBUS_FORCE_SHUTDOWN")) @@ -153,7 +153,7 @@ static void qdbus_unloadLibDBus() #endif // !QT_LINKED_LIBDBUS -#ifndef QT_BOOTSTRAPPED +#if defined(QT_LINKED_LIBDBUS) || !defined(QT_NO_LIBRARY) Q_DESTRUCTOR_FUNCTION(qdbus_unloadLibDBus) #endif diff --git a/src/dbus/qdbusabstractadaptor.cpp b/src/dbus/qdbusabstractadaptor.cpp index e7529f794ee4f61737f1c6e889a22405c60efc70..2864e076e9948d9ccea5f5fc2fb0ba76aa77b984 100644 --- a/src/dbus/qdbusabstractadaptor.cpp +++ b/src/dbus/qdbusabstractadaptor.cpp @@ -317,7 +317,9 @@ void QDBusAdaptorConnector::relay(QObject *senderObj, int lastSignalIdx, void ** } QVariantList args; - for (int i = 1; i < types.count(); ++i) + const int numTypes = types.count(); + args.reserve(numTypes - 1); + for (int i = 1; i < numTypes; ++i) args << QVariant(types.at(i), argv[i]); // now emit the signal with all the information diff --git a/src/dbus/qdbusabstractadaptor_p.h b/src/dbus/qdbusabstractadaptor_p.h index 8fd158614fb4f7496558e1fd1340a3e3a5ea1acb..5ff33f8bef5b6554de77a8a31f215d01056f0733 100644 --- a/src/dbus/qdbusabstractadaptor_p.h +++ b/src/dbus/qdbusabstractadaptor_p.h @@ -126,6 +126,7 @@ public: // member variables private: static int relaySlotMethodIndex(); }; +Q_DECLARE_TYPEINFO(QDBusAdaptorConnector::AdaptorData, Q_PRIMITIVE_TYPE); extern QDBusAdaptorConnector *qDBusFindAdaptorConnector(QObject *object); extern QDBusAdaptorConnector *qDBusCreateAdaptorConnector(QObject *object); diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index 03640cdd21b3992cfaf6495d6bc6c1e353a366ed..a7c70bce705c9cd46e4ec655d0547daf61b4fec5 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -216,6 +216,7 @@ void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, const QString &newOwner) { Q_UNUSED(oldOwner); + Q_UNUSED(name); //qDebug() << "QDBusAbstractInterfacePrivate serviceOwnerChanged" << name << oldOwner << newOwner; if (name == service) { currentOwner = newOwner; diff --git a/src/dbus/qdbusargument.h b/src/dbus/qdbusargument.h index 42b266792a032f4f260b9278ff709f89daf4b365..a6bc3968619048dc079a2fe4f67fa940fb05e6d7 100644 --- a/src/dbus/qdbusargument.h +++ b/src/dbus/qdbusargument.h @@ -70,9 +70,15 @@ public: QDBusArgument(); QDBusArgument(const QDBusArgument &other); +#ifdef Q_COMPILER_RVALUE_REFS + QDBusArgument(QDBusArgument &&other) Q_DECL_NOTHROW : d(other.d) { other.d = Q_NULLPTR; } + QDBusArgument &operator=(QDBusArgument &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QDBusArgument &operator=(const QDBusArgument &other); ~QDBusArgument(); + void swap(QDBusArgument &other) Q_DECL_NOTHROW { qSwap(d, other.d); } + // used for marshalling (Qt -> D-BUS) QDBusArgument &operator<<(uchar arg); QDBusArgument &operator<<(bool arg); @@ -140,6 +146,7 @@ protected: friend class QDBusArgumentPrivate; mutable QDBusArgumentPrivate *d; }; +Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QDBusArgument) QT_END_NAMESPACE Q_DECLARE_METATYPE(QDBusArgument) @@ -147,7 +154,7 @@ QT_BEGIN_NAMESPACE template<typename T> inline T qdbus_cast(const QDBusArgument &arg #ifndef Q_QDOC -, T * = 0 +, T * = Q_NULLPTR #endif ) { @@ -158,7 +165,7 @@ template<typename T> inline T qdbus_cast(const QDBusArgument &arg template<typename T> inline T qdbus_cast(const QVariant &v #ifndef Q_QDOC -, T * = 0 +, T * = Q_NULLPTR #endif ) { diff --git a/src/dbus/qdbusconnection.h b/src/dbus/qdbusconnection.h index 10598c0b7bf695fd2579ff9ff04d2b611c971772..8b2e9234aa1fda7e58d4f61b187645a84e94634d 100644 --- a/src/dbus/qdbusconnection.h +++ b/src/dbus/qdbusconnection.h @@ -99,11 +99,12 @@ public: ExportChildObjects = 0x1000 // Reserved = 0xff000000 }; + Q_DECLARE_FLAGS(RegisterOptions, RegisterOption) + enum UnregisterMode { UnregisterNode, UnregisterTree }; - Q_DECLARE_FLAGS(RegisterOptions, RegisterOption) enum VirtualObjectRegisterOption { SingleNode = 0x0, @@ -121,9 +122,14 @@ public: explicit QDBusConnection(const QString &name); QDBusConnection(const QDBusConnection &other); +#ifdef Q_COMPILER_RVALUE_REFS + QDBusConnection(QDBusConnection &&other) Q_DECL_NOTHROW : d(other.d) { other.d = Q_NULLPTR; } + QDBusConnection &operator=(QDBusConnection &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif + QDBusConnection &operator=(const QDBusConnection &other); ~QDBusConnection(); - QDBusConnection &operator=(const QDBusConnection &other); + void swap(QDBusConnection &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool isConnected() const; QString baseService() const; @@ -199,9 +205,11 @@ private: friend class QDBusConnectionPrivate; QDBusConnectionPrivate *d; }; +Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QDBusConnection) Q_DECLARE_OPERATORS_FOR_FLAGS(QDBusConnection::RegisterOptions) Q_DECLARE_OPERATORS_FOR_FLAGS(QDBusConnection::VirtualObjectRegisterOptions) +Q_DECLARE_OPERATORS_FOR_FLAGS(QDBusConnection::ConnectionCapabilities) QT_END_NAMESPACE diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 5d8777c6221a051750824c30fca08f02f3cb1d94..752ca9c37aa34e4b27189a5247d7a4c01225d437 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -166,7 +166,7 @@ public: // typedefs typedef QMultiHash<int, Watcher> WatcherHash; typedef QHash<int, DBusTimeout *> TimeoutHash; - typedef QList<QPair<DBusTimeout *, int> > PendingTimeoutList; + typedef QVector<QPair<DBusTimeout *, int> > PendingTimeoutList; typedef QMultiHash<QString, SignalHook> SignalHookHash; typedef QHash<QString, QDBusMetaObject* > MetaObjectHash; diff --git a/src/dbus/qdbuserror.h b/src/dbus/qdbuserror.h index c2c0ff8fc56076e52cfe41e79b5359e994b7a315..ce5275dee9e1a3e57f80f24cab1659d3f3808de2 100644 --- a/src/dbus/qdbuserror.h +++ b/src/dbus/qdbuserror.h @@ -92,11 +92,25 @@ public: #endif QDBusError(ErrorType error, const QString &message); QDBusError(const QDBusError &other); +#ifdef Q_COMPILER_RVALUE_REFS + QDBusError(QDBusError &&other) Q_DECL_NOTHROW + : code(other.code), msg(std::move(other.msg)), nm(std::move(other.nm)), unused(other.unused) + { other.unused = Q_NULLPTR; } + QDBusError &operator=(QDBusError &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QDBusError &operator=(const QDBusError &other); #ifndef QT_BOOTSTRAPPED QDBusError &operator=(const QDBusMessage &msg); #endif + void swap(QDBusError &other) Q_DECL_NOTHROW + { + qSwap(code, other.code); + qSwap(msg, other.msg); + qSwap(nm, other.nm); + qSwap(unused, other.unused); + } + ErrorType type() const; QString name() const; QString message() const; @@ -110,6 +124,7 @@ private: QString nm; void *unused; }; +Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QDBusError) #ifndef QT_NO_DEBUG_STREAM Q_DBUS_EXPORT QDebug operator<<(QDebug, const QDBusError &); diff --git a/src/dbus/qdbusextratypes.h b/src/dbus/qdbusextratypes.h index 5032db08d0e0870efbf5e8df0dc76cc9d45ce985..8495b3a32068db31057152f9ca04e23da3a41551 100644 --- a/src/dbus/qdbusextratypes.h +++ b/src/dbus/qdbusextratypes.h @@ -53,11 +53,18 @@ class Q_DBUS_EXPORT QDBusObjectPath { QString m_path; public: - inline QDBusObjectPath() { } + QDBusObjectPath() Q_DECL_NOTHROW : m_path() {} + // compiler-generated copy/move constructor/assignment operators are ok! + // compiler-generated destructor is ok! inline explicit QDBusObjectPath(const char *path); inline explicit QDBusObjectPath(QLatin1String path); inline explicit QDBusObjectPath(const QString &path); +#ifdef Q_COMPILER_RVALUE_REFS + explicit QDBusObjectPath(QString &&p) : m_path(std::move(p)) { doCheck(); } +#endif + + void swap(QDBusObjectPath &other) Q_DECL_NOTHROW { qSwap(m_path, other.m_path); } inline void setPath(const QString &path); @@ -67,6 +74,7 @@ public: private: void doCheck(); }; +Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QDBusObjectPath) inline QDBusObjectPath::QDBusObjectPath(const char *objectPath) : m_path(QString::fromLatin1(objectPath)) @@ -92,7 +100,7 @@ inline bool operator!=(const QDBusObjectPath &lhs, const QDBusObjectPath &rhs) inline bool operator<(const QDBusObjectPath &lhs, const QDBusObjectPath &rhs) { return lhs.path() < rhs.path(); } -inline uint qHash(const QDBusObjectPath &objectPath, uint seed) +inline uint qHash(const QDBusObjectPath &objectPath, uint seed = 0) { return qHash(objectPath.path(), seed); } @@ -100,11 +108,18 @@ class Q_DBUS_EXPORT QDBusSignature { QString m_signature; public: - inline QDBusSignature() { } + QDBusSignature() Q_DECL_NOTHROW : m_signature() {} + // compiler-generated copy/move constructor/assignment operators are ok! + // compiler-generated destructor is ok! inline explicit QDBusSignature(const char *signature); inline explicit QDBusSignature(QLatin1String signature); inline explicit QDBusSignature(const QString &signature); +#ifdef Q_COMPILER_RVALUE_REFS + explicit QDBusSignature(QString &&sig) : m_signature(std::move(sig)) { doCheck(); } +#endif + + void swap(QDBusSignature &other) Q_DECL_NOTHROW { qSwap(m_signature, other.m_signature); } inline void setSignature(const QString &signature); @@ -114,6 +129,7 @@ public: private: void doCheck(); }; +Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QDBusSignature) inline QDBusSignature::QDBusSignature(const char *dBusSignature) : m_signature(QString::fromLatin1(dBusSignature)) @@ -139,21 +155,30 @@ inline bool operator!=(const QDBusSignature &lhs, const QDBusSignature &rhs) inline bool operator<(const QDBusSignature &lhs, const QDBusSignature &rhs) { return lhs.signature() < rhs.signature(); } -inline uint qHash(const QDBusSignature &signature, uint seed) +inline uint qHash(const QDBusSignature &signature, uint seed = 0) { return qHash(signature.signature(), seed); } class QDBusVariant { QVariant m_variant; public: - inline QDBusVariant() { } + QDBusVariant() Q_DECL_NOTHROW : m_variant() {} + // compiler-generated copy/move constructor/assignment operators are ok! + // compiler-generated destructor is ok! + inline explicit QDBusVariant(const QVariant &variant); +#ifdef Q_COMPILER_RVALUE_REFS + explicit QDBusVariant(QVariant &&v) Q_DECL_NOTHROW : m_variant(std::move(v)) {} +#endif + + void swap(QDBusVariant &other) Q_DECL_NOTHROW { qSwap(m_variant, other.m_variant); } inline void setVariant(const QVariant &variant); inline QVariant variant() const { return m_variant; } }; +Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QDBusVariant) inline QDBusVariant::QDBusVariant(const QVariant &dBusVariant) : m_variant(dBusVariant) { } diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index b310483d1175bca510f9fd6415de6c9e92db4d94..22c1a3e3639cfbf20a5597b4386f9c53758ca91e 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -160,7 +160,7 @@ static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data) static bool qDBusRealAddTimeout(QDBusConnectionPrivate *d, DBusTimeout *timeout, int ms) { - Q_ASSERT(d->timeouts.keys(timeout).isEmpty()); + Q_ASSERT(d->timeouts.key(timeout, 0) == 0); int timerId = d->startTimer(ms); if (!timerId) @@ -952,14 +952,19 @@ void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const Q } // output arguments + const int numMetaTypes = metaTypes.count(); QVariantList outputArgs; void *null = 0; if (metaTypes[0] != QMetaType::Void && metaTypes[0] != QMetaType::UnknownType) { + outputArgs.reserve(numMetaTypes - i + 1); QVariant arg(metaTypes[0], null); outputArgs.append( arg ); params[0] = const_cast<void*>(outputArgs.at( outputArgs.count() - 1 ).constData()); + } else { + outputArgs.reserve(numMetaTypes - i); } - for ( ; i < metaTypes.count(); ++i) { + + for ( ; i < numMetaTypes; ++i) { QVariant arg(metaTypes[i], null); outputArgs.append( arg ); params.append(const_cast<void*>(outputArgs.at( outputArgs.count() - 1 ).constData())); @@ -1730,7 +1735,7 @@ static QDBusConnection::ConnectionCapabilities connectionCapabilies(DBusConnecti # if DBUS_VERSION-0 >= 0x010400 can_send_type = dbus_connection_can_send_type; # endif -#else +#elif !defined(QT_NO_LIBRARY) // run-time check if the next functions are available can_send_type = (can_send_type_t)qdbus_resolve_conditionally("dbus_connection_can_send_type"); #endif diff --git a/src/dbus/qdbusintegrator_p.h b/src/dbus/qdbusintegrator_p.h index cd358569df0e7d0f67a091980287b76cbc84afe6..95eeed3fffebe9c209e9b71dd9063b6bfbe579b8 100644 --- a/src/dbus/qdbusintegrator_p.h +++ b/src/dbus/qdbusintegrator_p.h @@ -76,10 +76,21 @@ struct QDBusSlotCache int flags; int slotIdx; QVector<int> metaTypes; + + void swap(Data &other) Q_DECL_NOTHROW + { + qSwap(flags, other.flags); + qSwap(slotIdx, other.slotIdx); + qSwap(metaTypes, other.metaTypes); + } }; typedef QMultiHash<QString, Data> Hash; Hash hash; + + void swap(QDBusSlotCache &other) Q_DECL_NOTHROW { qSwap(hash, other.hash); } }; +Q_DECLARE_SHARED(QDBusSlotCache::Data) +Q_DECLARE_SHARED(QDBusSlotCache) class QDBusCallDeliveryEvent: public QMetaCallEvent { diff --git a/src/dbus/qdbusinterface.cpp b/src/dbus/qdbusinterface.cpp index 1fc313d8ccd6a4bdb5e54c27c4066c0528ec71c2..421fc0bdb626c3e3034dc8994cce7c5fb6a2770a 100644 --- a/src/dbus/qdbusinterface.cpp +++ b/src/dbus/qdbusinterface.cpp @@ -278,6 +278,7 @@ int QDBusInterfacePrivate::metacall(QMetaObject::Call c, int id, void **argv) // we will assume that the input arguments were passed correctly QVariantList args; + args.reserve(inputTypesCount); int i = 1; for ( ; i <= inputTypesCount; ++i) args << QVariant(inputTypes[i], argv[i]); diff --git a/src/dbus/qdbusinterface.h b/src/dbus/qdbusinterface.h index b63df107637c84bd3814fb3bb991d1177152065d..b48a2066441f38e23709356e2c0743c92a6e229a 100644 --- a/src/dbus/qdbusinterface.h +++ b/src/dbus/qdbusinterface.h @@ -52,7 +52,7 @@ private: public: QDBusInterface(const QString &service, const QString &path, const QString &interface = QString(), const QDBusConnection &connection = QDBusConnection::sessionBus(), - QObject *parent = 0); + QObject *parent = Q_NULLPTR); ~QDBusInterface(); virtual const QMetaObject *metaObject() const Q_DECL_OVERRIDE; diff --git a/src/dbus/qdbusintrospection_p.h b/src/dbus/qdbusintrospection_p.h index ce3be00733cf6a1f473d8579683074edf1b9d20e..572a39b1408f86e3bce9d5115af46f7f25d7195a 100644 --- a/src/dbus/qdbusintrospection_p.h +++ b/src/dbus/qdbusintrospection_p.h @@ -46,7 +46,7 @@ // #include <QtCore/qstring.h> -#include <QtCore/qlist.h> +#include <QtCore/qvector.h> #include <QtCore/qstringlist.h> #include <QtCore/qmap.h> #include <QtCore/qpair.h> @@ -71,7 +71,7 @@ public: // typedefs typedef QMap<QString, QString> Annotations; - typedef QList<Argument> Arguments; + typedef QVector<Argument> Arguments; typedef QMultiMap<QString, Method> Methods; typedef QMultiMap<QString, Signal> Signals; typedef QMap<QString, Property> Properties; @@ -158,6 +158,7 @@ public: private: QDBusIntrospection(); }; +Q_DECLARE_TYPEINFO(QDBusIntrospection::Argument, Q_MOVABLE_TYPE); QT_END_NAMESPACE diff --git a/src/dbus/qdbusmessage.h b/src/dbus/qdbusmessage.h index 640226e77aad255e3b8ef45943d80b36d7945444..e85d60008070b655eba07404cad97003e7881480 100644 --- a/src/dbus/qdbusmessage.h +++ b/src/dbus/qdbusmessage.h @@ -62,9 +62,14 @@ public: QDBusMessage(); QDBusMessage(const QDBusMessage &other); +#ifdef Q_COMPILER_RVALUE_REFS + QDBusMessage &operator=(QDBusMessage &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QDBusMessage &operator=(const QDBusMessage &other); ~QDBusMessage(); + void swap(QDBusMessage &other) Q_DECL_NOTHROW { qSwap(d_ptr, other.d_ptr); } + static QDBusMessage createSignal(const QString &path, const QString &interface, const QString &name); static QDBusMessage createTargetedSignal(const QString &service, const QString &path, @@ -117,6 +122,7 @@ private: friend class QDBusMessagePrivate; QDBusMessagePrivate *d_ptr; }; +Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QDBusMessage) #ifndef QT_NO_DEBUG_STREAM Q_DBUS_EXPORT QDebug operator<<(QDebug, const QDBusMessage &); diff --git a/src/dbus/qdbuspendingcall.h b/src/dbus/qdbuspendingcall.h index 99d261d05b3a7142bbbf9c6cc84230e60a57fc5e..3bcacffd224808ab52305622552e8b373c47a662 100644 --- a/src/dbus/qdbuspendingcall.h +++ b/src/dbus/qdbuspendingcall.h @@ -56,9 +56,12 @@ class Q_DBUS_EXPORT QDBusPendingCall public: QDBusPendingCall(const QDBusPendingCall &other); ~QDBusPendingCall(); +#ifdef Q_COMPILER_RVALUE_REFS + QDBusPendingCall &operator=(QDBusPendingCall &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QDBusPendingCall &operator=(const QDBusPendingCall &other); - void swap(QDBusPendingCall &other) { qSwap(d, other.d); } + void swap(QDBusPendingCall &other) Q_DECL_NOTHROW { qSwap(d, other.d); } #ifndef Q_QDOC // pretend that they aren't here @@ -93,7 +96,7 @@ class Q_DBUS_EXPORT QDBusPendingCallWatcher: public QObject, public QDBusPending { Q_OBJECT public: - explicit QDBusPendingCallWatcher(const QDBusPendingCall &call, QObject *parent = 0); + explicit QDBusPendingCallWatcher(const QDBusPendingCall &call, QObject *parent = Q_NULLPTR); ~QDBusPendingCallWatcher(); #ifdef Q_QDOC diff --git a/src/dbus/qdbusreply.h b/src/dbus/qdbusreply.h index 56830f698a53b6210bbfa777a56ec22c6df6d892..4cfe8db161b0d082c1d1b75f3356e58d78c06af6 100644 --- a/src/dbus/qdbusreply.h +++ b/src/dbus/qdbusreply.h @@ -125,7 +125,7 @@ private: template<> inline QDBusReply<QVariant>& QDBusReply<QVariant>::operator=(const QDBusMessage &reply) { - void *null = 0; + void *null = Q_NULLPTR; QVariant data(qMetaTypeId<QDBusVariant>(), null); qDBusReplyFill(reply, m_error, data); m_data = qvariant_cast<QDBusVariant>(data).variant(); diff --git a/src/dbus/qdbusserver.h b/src/dbus/qdbusserver.h index cdd531802af44b89500fe26859ad3d40ba5e14ff..db21f268b02c0056e4534525374e72311a9cb4f5 100644 --- a/src/dbus/qdbusserver.h +++ b/src/dbus/qdbusserver.h @@ -50,8 +50,8 @@ class Q_DBUS_EXPORT QDBusServer: public QObject { Q_OBJECT public: - explicit QDBusServer(const QString &address, QObject *parent = 0); - explicit QDBusServer(QObject *parent = 0); + explicit QDBusServer(const QString &address, QObject *parent = Q_NULLPTR); + explicit QDBusServer(QObject *parent = Q_NULLPTR); virtual ~QDBusServer(); bool isConnected() const; diff --git a/src/dbus/qdbusservicewatcher.h b/src/dbus/qdbusservicewatcher.h index 020ce13c30a037076147906bbc7bd7ce92e29288..6f6ce917af469c345372a4c9ca5c8659922ce4c0 100644 --- a/src/dbus/qdbusservicewatcher.h +++ b/src/dbus/qdbusservicewatcher.h @@ -58,9 +58,9 @@ public: }; Q_DECLARE_FLAGS(WatchMode, WatchModeFlag) - explicit QDBusServiceWatcher(QObject *parent = 0); + explicit QDBusServiceWatcher(QObject *parent = Q_NULLPTR); QDBusServiceWatcher(const QString &service, const QDBusConnection &connection, - WatchMode watchMode = WatchForOwnerChange, QObject *parent = 0); + WatchMode watchMode = WatchForOwnerChange, QObject *parent = Q_NULLPTR); ~QDBusServiceWatcher(); QStringList watchedServices() const; diff --git a/src/dbus/qdbusunixfiledescriptor.h b/src/dbus/qdbusunixfiledescriptor.h index 35e9d87cf3fa7b9c8270ff9fcb943e026eedc136..9fb6eb44c703a800d018855c3d190c621760ea92 100644 --- a/src/dbus/qdbusunixfiledescriptor.h +++ b/src/dbus/qdbusunixfiledescriptor.h @@ -55,10 +55,13 @@ public: QDBusUnixFileDescriptor(); explicit QDBusUnixFileDescriptor(int fileDescriptor); QDBusUnixFileDescriptor(const QDBusUnixFileDescriptor &other); +#if defined(Q_COMPILER_RVALUE_REFS) + QDBusUnixFileDescriptor &operator=(QDBusUnixFileDescriptor &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QDBusUnixFileDescriptor &operator=(const QDBusUnixFileDescriptor &other); ~QDBusUnixFileDescriptor(); - void swap(QDBusUnixFileDescriptor &other) + void swap(QDBusUnixFileDescriptor &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool isValid() const; @@ -71,11 +74,6 @@ public: static bool isSupported(); -#if defined(Q_COMPILER_RVALUE_REFS) - inline QDBusUnixFileDescriptor &operator=(QDBusUnixFileDescriptor &&other) - { d.swap(other.d); return *this; } -#endif - protected: typedef QExplicitlySharedDataPointer<QDBusUnixFileDescriptorPrivate> Data; Data d; diff --git a/src/dbus/qdbusvirtualobject.h b/src/dbus/qdbusvirtualobject.h index 469c41f363b97577fcd6bffed4337d4c2f790473..740c5f712e7dc953a9576a14af8060d3a197a711 100644 --- a/src/dbus/qdbusvirtualobject.h +++ b/src/dbus/qdbusvirtualobject.h @@ -51,7 +51,7 @@ class Q_DBUS_EXPORT QDBusVirtualObject : public QObject { Q_OBJECT public: - explicit QDBusVirtualObject(QObject *parent = 0); + explicit QDBusVirtualObject(QObject *parent = Q_NULLPTR); virtual ~QDBusVirtualObject(); virtual QString introspect(const QString &path) const = 0; diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index c1b586f87950b9dd5abbcd842aaa2256a7058593..dc6933f9ff5e2b44159918c1c3f5cd24cb470200 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -85,7 +85,7 @@ QT_BEGIN_NAMESPACE to replace or extend the default behavior of the static functions in QAccessible. - Qt supports Microsoft Active Accessibility (MSAA), Mac OS X + Qt supports Microsoft Active Accessibility (MSAA), OS X Accessibility, and the Unix/X11 AT-SPI standard. Other backends can be supported using QAccessibleBridge. @@ -462,12 +462,12 @@ QAccessibleInterface::~QAccessibleInterface() #ifndef QT_NO_LIBRARY Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QAccessibleFactoryInterface_iid, QLatin1String("/accessible"))) +typedef QHash<QString, QAccessiblePlugin*> QAccessiblePluginsHash; +Q_GLOBAL_STATIC(QAccessiblePluginsHash, qAccessiblePlugins) #endif // FIXME turn this into one global static struct Q_GLOBAL_STATIC(QList<QAccessible::InterfaceFactory>, qAccessibleFactories) -typedef QHash<QString, QAccessiblePlugin*> QAccessiblePluginsHash; -Q_GLOBAL_STATIC(QAccessiblePluginsHash, qAccessiblePlugins) Q_GLOBAL_STATIC(QList<QAccessible::ActivationObserver *>, qAccessibleActivationObservers) QAccessible::UpdateHandler QAccessible::updateHandler = 0; @@ -2833,7 +2833,7 @@ const QString &QAccessibleActionInterface::toggleAction() Returns the name of the scroll left default action. \sa actionNames(), localizedActionName() */ -const QString &QAccessibleActionInterface::scrollLeftAction() +QString QAccessibleActionInterface::scrollLeftAction() { return accessibleActionStrings()->scrollLeftAction; } @@ -2842,7 +2842,7 @@ const QString &QAccessibleActionInterface::scrollLeftAction() Returns the name of the scroll right default action. \sa actionNames(), localizedActionName() */ -const QString &QAccessibleActionInterface::scrollRightAction() +QString QAccessibleActionInterface::scrollRightAction() { return accessibleActionStrings()->scrollRightAction; } @@ -2851,7 +2851,7 @@ const QString &QAccessibleActionInterface::scrollRightAction() Returns the name of the scroll up default action. \sa actionNames(), localizedActionName() */ -const QString &QAccessibleActionInterface::scrollUpAction() +QString QAccessibleActionInterface::scrollUpAction() { return accessibleActionStrings()->scrollUpAction; } @@ -2860,7 +2860,7 @@ const QString &QAccessibleActionInterface::scrollUpAction() Returns the name of the scroll down default action. \sa actionNames(), localizedActionName() */ -const QString &QAccessibleActionInterface::scrollDownAction() +QString QAccessibleActionInterface::scrollDownAction() { return accessibleActionStrings()->scrollDownAction; } @@ -2869,7 +2869,7 @@ const QString &QAccessibleActionInterface::scrollDownAction() Returns the name of the previous page default action. \sa actionNames(), localizedActionName() */ -const QString &QAccessibleActionInterface::previousPageAction() +QString QAccessibleActionInterface::previousPageAction() { return accessibleActionStrings()->previousPageAction; } @@ -2878,7 +2878,7 @@ const QString &QAccessibleActionInterface::previousPageAction() Returns the name of the next page default action. \sa actionNames(), localizedActionName() */ -const QString &QAccessibleActionInterface::nextPageAction() +QString QAccessibleActionInterface::nextPageAction() { return accessibleActionStrings()->nextPageAction; } diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index a0281d1c110a6dd2084c8148cad331d6f1fece68..63658260fcab55eb14eb0e798eb5b722518cc3aa 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -505,7 +505,7 @@ public: virtual void virtual_hook(int id, void *data); virtual void *interface_cast(QAccessible::InterfaceType) - { return 0; } + { return Q_NULLPTR; } protected: friend class QAccessibleCache; @@ -635,12 +635,12 @@ public: static const QString &showMenuAction(); static const QString &setFocusAction(); static const QString &toggleAction(); - static const QString &scrollLeftAction(); - static const QString &scrollRightAction(); - static const QString &scrollUpAction(); - static const QString &scrollDownAction(); - static const QString &nextPageAction(); - static const QString &previousPageAction(); + static QString scrollLeftAction(); + static QString scrollRightAction(); + static QString scrollUpAction(); + static QString scrollDownAction(); + static QString nextPageAction(); + static QString previousPageAction(); }; class Q_GUI_EXPORT QAccessibleImageInterface @@ -676,7 +676,7 @@ public: } inline QAccessibleEvent(QAccessibleInterface *iface, QAccessible::Event typ) - : m_type(typ), m_object(0) + : m_type(typ), m_object(Q_NULLPTR) { Q_ASSERT(iface); Q_ASSERT(m_type != QAccessible::ValueChanged); diff --git a/src/gui/accessible/qaccessiblebridge.cpp b/src/gui/accessible/qaccessiblebridge.cpp index b4f28a6968bc314806058528d5ebcd50c50ce192..ddee4b06761765f25f149af41199658b20428196 100644 --- a/src/gui/accessible/qaccessiblebridge.cpp +++ b/src/gui/accessible/qaccessiblebridge.cpp @@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE \ingroup accessibility \inmodule QtWidgets - Qt supports Microsoft Active Accessibility (MSAA), Mac OS X + Qt supports Microsoft Active Accessibility (MSAA), OS X Accessibility, and the Unix/X11 AT-SPI standard. By subclassing QAccessibleBridge, you can support other backends than the predefined ones. diff --git a/src/gui/accessible/qaccessiblebridge.h b/src/gui/accessible/qaccessiblebridge.h index f0df5e1f3958fa0854acaf1ce54188f376259c74..277a8d201b5cf4bf29f7ce960cce625ea8b8a5c2 100644 --- a/src/gui/accessible/qaccessiblebridge.h +++ b/src/gui/accessible/qaccessiblebridge.h @@ -59,7 +59,7 @@ class Q_GUI_EXPORT QAccessibleBridgePlugin : public QObject { Q_OBJECT public: - explicit QAccessibleBridgePlugin(QObject *parent = 0); + explicit QAccessibleBridgePlugin(QObject *parent = Q_NULLPTR); ~QAccessibleBridgePlugin(); virtual QAccessibleBridge *create(const QString &key) = 0; diff --git a/src/gui/accessible/qaccessibleplugin.h b/src/gui/accessible/qaccessibleplugin.h index a4b782af111371949d02db6948256fcbaa500bcd..44261788c78a6d0923246c206399c076c9575e03 100644 --- a/src/gui/accessible/qaccessibleplugin.h +++ b/src/gui/accessible/qaccessibleplugin.h @@ -53,7 +53,7 @@ class Q_GUI_EXPORT QAccessiblePlugin : public QObject { Q_OBJECT public: - explicit QAccessiblePlugin(QObject *parent = 0); + explicit QAccessiblePlugin(QObject *parent = Q_NULLPTR); ~QAccessiblePlugin(); virtual QAccessibleInterface *create(const QString &key, QObject *object) = 0; diff --git a/src/gui/doc/images/qpainter-text-bounds.png b/src/gui/doc/images/qpainter-text-bounds.png new file mode 100644 index 0000000000000000000000000000000000000000..f92b8502f4e3282107e86d4ed4d4ca3ee00998dc Binary files /dev/null and b/src/gui/doc/images/qpainter-text-bounds.png differ diff --git a/src/gui/doc/snippets/code/src_gui_painting_qpainter.cpp b/src/gui/doc/snippets/code/src_gui_painting_qpainter.cpp index 1367ab2f8c5eb2fa4355cc7617bfe0f45b27389a..6d0308b1e9d5a7f0e18b8700b71168a61548bf74 100644 --- a/src/gui/doc/snippets/code/src_gui_painting_qpainter.cpp +++ b/src/gui/doc/snippets/code/src_gui_painting_qpainter.cpp @@ -257,3 +257,23 @@ glDisable(GL_SCISSOR_TEST); painter.endNativePainting(); //! [21] + +//! [drawText] +QPainter painter(this); +QFont font = painter.font(); +font.setPixelSize(48); +painter.setFont(font); + +const QRect rectangle = QRect(0, 0, 100, 50); +QRect boundingRect; +painter.drawText(rectangle, 0, tr("Hello"), &boundingRect); + +QPen pen = painter.pen(); +pen.setStyle(Qt::DotLine); +painter.setPen(pen); +painter.drawRect(boundingRect.adjusted(0, 0, -pen.width(), -pen.width())); + +pen.setStyle(Qt::DashLine); +painter.setPen(pen); +painter.drawRect(rectangle.adjusted(0, 0, -pen.width(), -pen.width())); +//! [drawText] diff --git a/src/gui/doc/snippets/code/src_gui_qopenglshaderprogram.cpp b/src/gui/doc/snippets/code/src_gui_qopenglshaderprogram.cpp index ab8ee67929a5ff769dade9f6524a03dcf5e83354..368a5085d4136041f0eeb901da3e9ab5c09a82c9 100644 --- a/src/gui/doc/snippets/code/src_gui_qopenglshaderprogram.cpp +++ b/src/gui/doc/snippets/code/src_gui_qopenglshaderprogram.cpp @@ -43,7 +43,7 @@ QOpenGLShader shader(QOpenGLShader::Vertex); shader.compileSourceCode(code); QOpenGLShaderProgram program(context); -program.addShader(shader); +program.addShader(&shader); program.link(); program.bind(); diff --git a/src/gui/doc/src/richtext.qdoc b/src/gui/doc/src/richtext.qdoc index 770ff985af2aedf48fa919f77a8b6dcaa570eaa5..58f7890f8b2d09da2087a4ec9e45d65e53a8e24e 100644 --- a/src/gui/doc/src/richtext.qdoc +++ b/src/gui/doc/src/richtext.qdoc @@ -874,7 +874,7 @@ The following table lists the HTML tags supported by Qt's \l{Rich Text Processing}{rich text} engine: - \table + \table 70% \header \li Tag \li Description \li Comment diff --git a/src/gui/image/qbitmap.h b/src/gui/image/qbitmap.h index f3ad90be209581126a5f1e1361359f51d4373187..be693af1cf23b9f249f62f37ddc185e1346c1816 100644 --- a/src/gui/image/qbitmap.h +++ b/src/gui/image/qbitmap.h @@ -48,7 +48,7 @@ public: QBitmap(const QPixmap &); QBitmap(int w, int h); explicit QBitmap(const QSize &); - explicit QBitmap(const QString &fileName, const char *format=0); + explicit QBitmap(const QString &fileName, const char *format = Q_NULLPTR); ~QBitmap(); QBitmap &operator=(const QPixmap &); diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 40ba84bb140831814a78c306e285f161d759b0c7..6b506580ea468f92ef4b1a12399c870d8cd642f4 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -46,11 +46,6 @@ #include "qdebug.h" #include "qpalette.h" -#ifdef Q_DEAD_CODE_FROM_QT4_MAC -#include <private/qt_mac_p.h> -#include <private/qt_cocoa_helpers_mac_p.h> -#endif - #include "private/qhexstring_p.h" #include "private/qguiapplication_p.h" #include "qpa/qplatformtheme.h" @@ -134,7 +129,8 @@ static qreal qt_effective_device_pixel_ratio(QWindow *window = 0) QIconPrivate::QIconPrivate() : engine(0), ref(1), serialNum(serialNumCounter.fetchAndAddRelaxed(1)), - detach_no(0) + detach_no(0), + is_mask(false) { } @@ -362,7 +358,7 @@ static inline int origIcoDepth(const QImage &image) return s.isEmpty() ? 32 : s.toInt(); } -static inline int findBySize(const QList<QImage> &images, const QSize &size) +static inline int findBySize(const QVector<QImage> &images, const QSize &size) { for (int i = 0; i < images.size(); ++i) { if (images.at(i).size() == size) @@ -426,7 +422,7 @@ void QPixmapIconEngine::addFile(const QString &fileName, const QSize &size, QIco // these files may contain low-resolution images. As this information is lost, // ICOReader sets the original format as an image text key value. Read all matching // images into a list trying to find the highest quality per size. - QList<QImage> icoImages; + QVector<QImage> icoImages; while (imageReader.read(&image)) { if (ignoreSize || image.size() == size) { const int position = findBySize(icoImages, image.size()); @@ -599,6 +595,8 @@ QFactoryLoader *qt_iconEngineFactoryLoader() \image icon.png QIcon + \note QIcon needs a QGuiApplication instance before the icon is created. + \sa {fowler}{GUI Design Handbook: Iconic Label}, {Icons Example} */ @@ -1170,15 +1168,14 @@ QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback) icon = *qtIconCache()->object(name); } else { QPlatformTheme * const platformTheme = QGuiApplicationPrivate::platformTheme(); - QIconEngine * const engine = platformTheme ? platformTheme->createIconEngine(name) + bool hasUserTheme = QIconLoader::instance()->hasUserTheme(); + QIconEngine * const engine = (platformTheme && !hasUserTheme) ? platformTheme->createIconEngine(name) : new QIconLoaderEngine(name); QIcon *cachedIcon = new QIcon(engine); icon = *cachedIcon; qtIconCache()->insert(name, cachedIcon); } - // Note the qapp check is to allow lazy loading of static icons - // Supporting fallbacks will not work for this case. if (qApp && icon.availableSizes().isEmpty()) return fallback; @@ -1200,6 +1197,31 @@ bool QIcon::hasThemeIcon(const QString &name) return icon.name() == name; } +/*! + \since 5.6 + + Indicate that this icon is a mask image, and hence can potentially + be modified based on where it's displayed. + \sa isMask() +*/ +void QIcon::setIsMask(bool isMask) +{ + d->is_mask = isMask; +} + +/*! + \since 5.6 + + Returns \c true if this icon has been marked as a mask image. + Certain platforms render mask icons differently (for example, + menu icons on OS X). + + \sa setIsMask() +*/ +bool QIcon::isMask() const +{ + return d->is_mask; +} /***************************************************************************** QIcon stream functions diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h index 63e77eef9940d9afb787c0a9813b8a3e5b3d978a..ccddf691019e235e2d6d191b51c4c308a4ea7d08 100644 --- a/src/gui/image/qicon.h +++ b/src/gui/image/qicon.h @@ -56,8 +56,8 @@ public: QIcon(const QIcon &other); #ifdef Q_COMPILER_RVALUE_REFS QIcon(QIcon &&other) Q_DECL_NOEXCEPT - : d(0) - { qSwap(d, other.d); } + : d(other.d) + { other.d = Q_NULLPTR; } #endif explicit QIcon(const QString &fileName); // file or resource name explicit QIcon(QIconEngine *engine); @@ -65,7 +65,7 @@ public: QIcon &operator=(const QIcon &other); #ifdef Q_COMPILER_RVALUE_REFS inline QIcon &operator=(QIcon &&other) Q_DECL_NOEXCEPT - { qSwap(d, other.d); return *this; } + { swap(other); return *this; } #endif inline void swap(QIcon &other) Q_DECL_NOEXCEPT { qSwap(d, other.d); } @@ -102,6 +102,9 @@ public: QList<QSize> availableSizes(Mode mode = Normal, State state = Off) const; + void setIsMask(bool isMask); + bool isMask() const; + static QIcon fromTheme(const QString &name, const QIcon &fallback = QIcon()); static bool hasThemeIcon(const QString &name); diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h index 8b42e770fac9b205094554830fc6b2f20e9c5f6b..2a4f584a0dd8fdc60291ece1092ddc3dd4799a9a 100644 --- a/src/gui/image/qicon_p.h +++ b/src/gui/image/qicon_p.h @@ -71,6 +71,7 @@ public: QAtomicInt ref; int serialNum; int detach_no; + bool is_mask; }; diff --git a/src/gui/image/qiconengineplugin.h b/src/gui/image/qiconengineplugin.h index 66684c871d8ae964e0bd101d55aefc8165087388..b05969f283fccff54f77a0fa8c42602b31c6e61f 100644 --- a/src/gui/image/qiconengineplugin.h +++ b/src/gui/image/qiconengineplugin.h @@ -48,7 +48,7 @@ class Q_GUI_EXPORT QIconEnginePlugin : public QObject { Q_OBJECT public: - QIconEnginePlugin(QObject *parent = 0); + QIconEnginePlugin(QObject *parent = Q_NULLPTR); ~QIconEnginePlugin(); virtual QIconEngine *create(const QString &filename = QString()) = 0; diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index d3553f28be0faf7389941931415d8dd7cee33738..3ead72dfbbdd5110204fc4723c8d2291e4e5c5e2 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -46,10 +46,6 @@ #include <QtCore/QSettings> #include <QtGui/QPainter> -#ifdef Q_DEAD_CODE_FROM_QT4_MAC -#include <private/qt_cocoa_helpers_mac_p.h> -#endif - #include <private/qhexstring_p.h> QT_BEGIN_NAMESPACE @@ -72,9 +68,6 @@ QIconLoader::QIconLoader() : { } -// We lazily initialize the loader to make static icons -// work. Though we do not officially support this. - static inline QString systemThemeName() { if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { @@ -397,9 +390,6 @@ void QIconLoaderEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) { QSize pixmapSize = rect.size(); -#if defined(Q_DEAD_CODE_FROM_QT4_MAC) - pixmapSize *= qt_mac_get_scalefactor(); -#endif painter->drawPixmap(rect, pixmap(pixmapSize, mode, state)); } diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h index 38cf9c173660fe7b2111a0468b5b29e6894efe0f..ccf0a9d4382c7c83fad77dd26a46be16cc68796c 100644 --- a/src/gui/image/qiconloader_p.h +++ b/src/gui/image/qiconloader_p.h @@ -76,7 +76,7 @@ struct QIconDirInfo short maxSize; short minSize; short threshold; - Type type : 4; + Type type; }; Q_DECLARE_TYPEINFO(QIconDirInfo, Q_MOVABLE_TYPE); @@ -173,6 +173,7 @@ public: void updateSystemTheme(); void invalidateKey() { m_themeKey++; } void ensureInitialized(); + bool hasUserTheme() const { return !m_userTheme.isEmpty(); } private: QThemeIconInfo findIconHelper(const QString &themeName, diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 3c192a237e65efee0b7cd0ab936d68a63343fcb7..b8606a92b4052d2c4a5c4df41c0c0a887fecc98f 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3891,6 +3891,10 @@ int QImage::metric(PaintDeviceMetric metric) const return d->devicePixelRatio; break; + case PdmDevicePixelRatioScaled: + return d->devicePixelRatio * QPaintDevice::devicePixelRatioFScale(); + break; + default: qWarning("QImage::metric(): Unhandled metric type %d", metric); break; diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index 26707021ea43d71df95ae2204f3333a7427daa14..888c7beb3254d9e3b72072ad13c9ae31408a4b6a 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -125,15 +125,15 @@ public: QImage() Q_DECL_NOEXCEPT; QImage(const QSize &size, Format format); QImage(int width, int height, Format format); - QImage(uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = 0, void *cleanupInfo = 0); - QImage(const uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = 0, void *cleanupInfo = 0); - QImage(uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = 0, void *cleanupInfo = 0); - QImage(const uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = 0, void *cleanupInfo = 0); + QImage(uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR); + QImage(const uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR); + QImage(uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR); + QImage(const uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR); #ifndef QT_NO_IMAGEFORMAT_XPM explicit QImage(const char * const xpm[]); #endif - explicit QImage(const QString &fileName, const char *format = 0); + explicit QImage(const QString &fileName, const char *format = Q_NULLPTR); QImage(const QImage &); #ifdef Q_COMPILER_RVALUE_REFS @@ -279,16 +279,16 @@ public: bool load(QIODevice *device, const char* format); - bool load(const QString &fileName, const char* format=0); - bool loadFromData(const uchar *buf, int len, const char *format = 0); - inline bool loadFromData(const QByteArray &data, const char* aformat=0) + bool load(const QString &fileName, const char *format = Q_NULLPTR); + bool loadFromData(const uchar *buf, int len, const char *format = Q_NULLPTR); + inline bool loadFromData(const QByteArray &data, const char *aformat = Q_NULLPTR) { return loadFromData(reinterpret_cast<const uchar *>(data.constData()), data.size(), aformat); } - bool save(const QString &fileName, const char* format=0, int quality=-1) const; - bool save(QIODevice *device, const char* format=0, int quality=-1) const; + bool save(const QString &fileName, const char *format = Q_NULLPTR, int quality = -1) const; + bool save(QIODevice *device, const char *format = Q_NULLPTR, int quality = -1) const; - static QImage fromData(const uchar *data, int size, const char *format = 0); - inline static QImage fromData(const QByteArray &data, const char *format = 0) + static QImage fromData(const uchar *data, int size, const char *format = Q_NULLPTR); + inline static QImage fromData(const QByteArray &data, const char *format = Q_NULLPTR) { return fromData(reinterpret_cast<const uchar *>(data.constData()), data.size(), format); } #if QT_DEPRECATED_SINCE(5, 0) diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index e0ca2c53313ba183cee2a167a7a6885c94ec737c..02f32aa34b2934f1b1302c4b61477a5e35e60402 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -1103,7 +1103,7 @@ static bool mask_alpha_converter_rgbx_inplace(QImageData *data, Qt::ImageConvers } rgb_data += pad; } - data->format = DestFormat; + data->format = QImage::Format_RGBX8888; return true; #endif } diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index 7eb571900a193d9ee65d9463e3af26bec3001fdd..feeab60abd45b61740f18b688a7a017b4800453a 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -116,7 +116,7 @@ void qInitImageConversions(); const uchar *qt_get_bitflip_array(); Q_GUI_EXPORT void qGamma_correct_back_to_linear_cs(QImage *image); -#if defined(Q_OS_WINRT) && defined(_M_ARM) // QTBUG-42038 +#if defined(_M_ARM) // QTBUG-42038 #pragma optimize("", off) #endif inline int qt_depthForFormat(QImage::Format format) @@ -163,7 +163,7 @@ inline int qt_depthForFormat(QImage::Format format) } return depth; } -#if defined(Q_OS_WINRT) && defined(_M_ARM) +#if defined(_M_ARM) #pragma optimize("", on) #endif diff --git a/src/gui/image/qimageiohandler.h b/src/gui/image/qimageiohandler.h index 80cd87c4c3751aeaa154a3ba32d7ead1df746cca..47a8a2b7c6f5889c3883a0dca02d8bc1947d2e42 100644 --- a/src/gui/image/qimageiohandler.h +++ b/src/gui/image/qimageiohandler.h @@ -133,7 +133,7 @@ class Q_GUI_EXPORT QImageIOPlugin : public QObject { Q_OBJECT public: - explicit QImageIOPlugin(QObject *parent = 0); + explicit QImageIOPlugin(QObject *parent = Q_NULLPTR); virtual ~QImageIOPlugin(); enum Capability { diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index ba79bf40e52936bb6734146ee5c2cad50b640894..618352d363a423483b99c08a5bccf2dd6548e252 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -252,7 +252,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, #ifdef QIMAGEREADER_DEBUG qDebug() << "QImageReader::createReadHandler( device =" << (void *)device << ", format =" << format << ")," - << keyMap.values().size() << "plugins available: " << keyMap.values(); + << keyMap.size() << "plugins available: " << keyMap.values(); #endif int suffixPluginIndex = -1; @@ -312,7 +312,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, const qint64 pos = device ? device->pos() : 0; if (autoDetectImageFormat) { - const int keyCount = keyMap.keys().size(); + const int keyCount = keyMap.size(); for (int i = 0; i < keyCount; ++i) { if (i != suffixPluginIndex) { QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(i)); @@ -392,7 +392,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) { // check if any of our plugins recognize the file from its contents. const qint64 pos = device ? device->pos() : 0; - const int keyCount = keyMap.keys().size(); + const int keyCount = keyMap.size(); for (int i = 0; i < keyCount; ++i) { if (i != suffixPluginIndex) { QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(i)); @@ -1168,9 +1168,10 @@ QImageIOHandler::Transformations QImageReader::transformation() const /*! \since 5.5 - Sets if images returned by read() should have transformation metadata automatically applied. + Determines that images returned by read() should have transformation metadata automatically + applied if \a enabled is \c true. - \sa autoTransform(), transform(), read() + \sa autoTransform(), read() */ void QImageReader::setAutoTransform(bool enabled) { @@ -1202,6 +1203,39 @@ bool QImageReader::autoTransform() const return false; } +/*! + \since 5.6 + + This is an image format specific function that forces images with + gamma information to be gamma corrected to \a gamma. For image formats + that do not support gamma correction, this value is ignored. + + To gamma correct to a standard PC color-space, set gamma to \c 1/2.2. + + \sa gamma() +*/ +void QImageReader::setGamma(float gamma) +{ + if (d->initHandler() && d->handler->supportsOption(QImageIOHandler::Gamma)) + d->handler->setOption(QImageIOHandler::Gamma, gamma); +} + +/*! + \since 5.6 + + Returns the gamma level of the decoded image. If setGamma() has been + called and gamma correction is supported it will return the gamma set. + If gamma level is not supported by the image format, \c 0.0 is returned. + + \sa setGamma() +*/ +float QImageReader::gamma() const +{ + if (d->initHandler() && d->handler->supportsOption(QImageIOHandler::Gamma)) + return d->handler->option(QImageIOHandler::Gamma).toFloat(); + return 0.0; +} + /*! Returns \c true if an image can be read for the device (i.e., the image format is supported, and the device seems to contain valid diff --git a/src/gui/image/qimagereader.h b/src/gui/image/qimagereader.h index 27a29bed49fff6188b1cccf04bdcf5cab709463a..6745c55b978ae9a6288d18dcd23f3dad8869dca0 100644 --- a/src/gui/image/qimagereader.h +++ b/src/gui/image/qimagereader.h @@ -110,6 +110,9 @@ public: void setAutoTransform(bool enabled); bool autoTransform() const; + void setGamma(float gamma); + float gamma() const; + QByteArray subType() const; QList<QByteArray> supportedSubTypes() const; diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index e9de1db4b2d26d268c52a3d7dff07034d3fff912..1cf75d8688ebcd6c453ede37d37c531ee53a9138 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -212,7 +212,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device, #ifndef QT_NO_IMAGEFORMATPLUGIN if (!testFormat.isEmpty()) { - const int keyCount = keyMap.keys().size(); + const int keyCount = keyMap.size(); for (int i = 0; i < keyCount; ++i) { QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(i)); if (plugin && (plugin->capabilities(device, testFormat) & QImageIOPlugin::CanWrite)) { @@ -621,7 +621,7 @@ bool QImageWriter::progressiveScanWrite() const /*! \since 5.5 - Sets the image transformations metadata including orientation. + Sets the image transformations metadata including orientation to \a transform. If transformation metadata is not supported by the image format, the transform is applied before writing. diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index 4ff3917fe6242579e2604542888d71a264a64e48..e29f9783a61500e5a88d12d5d365592bf6f9bf3e 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -710,6 +710,7 @@ public: enum State { Ready, ReadHeader, + ReadingEnd, Error }; @@ -929,8 +930,6 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) if (!exifData.isEmpty()) { // Exif data present int exifOrientation = getExifOrientation(exifData); - if (exifOrientation == -1) - return false; if (exifOrientation > 0) transformation = exif2Qt(exifOrientation); } @@ -960,7 +959,7 @@ bool QJpegHandlerPrivate::read(QImage *image) for (int i = 0; i < readTexts.size()-1; i+=2) image->setText(readTexts.at(i), readTexts.at(i+1)); - state = Ready; + state = ReadingEnd; return true; } @@ -1008,7 +1007,7 @@ bool QJpegHandler::canRead() const if(d->state == QJpegHandlerPrivate::Ready && !canRead(device())) return false; - if (d->state != QJpegHandlerPrivate::Error) { + if (d->state != QJpegHandlerPrivate::Error && d->state != QJpegHandlerPrivate::ReadingEnd) { setFormat("jpeg"); return true; } diff --git a/src/gui/image/qmovie.h b/src/gui/image/qmovie.h index 13bc381f8e38e9a577e55f0edf858d39cf23ca04..a750e4a9fc2e3f881d5911f33503c915dd84a0ab 100644 --- a/src/gui/image/qmovie.h +++ b/src/gui/image/qmovie.h @@ -73,9 +73,9 @@ public: }; Q_ENUM(CacheMode) - explicit QMovie(QObject *parent = 0); - explicit QMovie(QIODevice *device, const QByteArray &format = QByteArray(), QObject *parent = 0); - explicit QMovie(const QString &fileName, const QByteArray &format = QByteArray(), QObject *parent = 0); + explicit QMovie(QObject *parent = Q_NULLPTR); + explicit QMovie(QIODevice *device, const QByteArray &format = QByteArray(), QObject *parent = Q_NULLPTR); + explicit QMovie(const QString &fileName, const QByteArray &format = QByteArray(), QObject *parent = Q_NULLPTR); ~QMovie(); static QList<QByteArray> supportedFormats(); diff --git a/src/gui/image/qpaintengine_pic.cpp b/src/gui/image/qpaintengine_pic.cpp index b17fb731330d0ff50aae563f2125e17627080942..47480ebbae5c05d8121ee483192f5b010d9912b8 100644 --- a/src/gui/image/qpaintengine_pic.cpp +++ b/src/gui/image/qpaintengine_pic.cpp @@ -342,7 +342,7 @@ void QPicturePaintEngine::writeCmdLength(int pos, const QRectF &r, bool corr) } br = painter()->transform().mapRect(br); if (painter()->hasClipping()) { - QRect cr = painter()->clipRegion().boundingRect(); + QRectF cr = painter()->clipBoundingRect(); br &= cr; } @@ -398,6 +398,7 @@ void QPicturePaintEngine::drawPolygon(const QPointF *points, int numPoints, Poly int pos; QPolygonF polygon; + polygon.reserve(numPoints); for (int i=0; i<numPoints; ++i) polygon << points[i]; diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index b63be19153a913f7128ec766e585a7c0bc78b17c..2b184466f42dd6ae698da918d41c2bf94450f0d8 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -961,6 +961,9 @@ int QPicture::metric(PaintDeviceMetric m) const case PdmDevicePixelRatio: val = 1; break; + case PdmDevicePixelRatioScaled: + val = 1 * QPaintDevice::devicePixelRatioFScale(); + break; default: val = 0; qWarning("QPicture::metric: Invalid metric command"); @@ -1216,7 +1219,9 @@ QList<QByteArray> QPicture::inputFormats() static QStringList qToStringList(const QList<QByteArray> &arr) { QStringList list; - for (int i = 0; i < arr.count(); ++i) + const int count = arr.count(); + list.reserve(count); + for (int i = 0; i < count; ++i) list.append(QString::fromLatin1(arr.at(i))); return list; } diff --git a/src/gui/image/qpicture.h b/src/gui/image/qpicture.h index c3897a1935d9e0b9fec95fbed13094f4c43a770f..a71d1deb0241872e0ec69313b1b2c50146d68973 100644 --- a/src/gui/image/qpicture.h +++ b/src/gui/image/qpicture.h @@ -62,10 +62,10 @@ public: bool play(QPainter *p); - bool load(QIODevice *dev, const char *format = 0); - bool load(const QString &fileName, const char *format = 0); - bool save(QIODevice *dev, const char *format = 0); - bool save(const QString &fileName, const char *format = 0); + bool load(QIODevice *dev, const char *format = Q_NULLPTR); + bool load(const QString &fileName, const char *format = Q_NULLPTR); + bool save(QIODevice *dev, const char *format = Q_NULLPTR); + bool save(const QString &fileName, const char *format = Q_NULLPTR); QRect boundingRect() const; void setBoundingRect(const QRect &r); diff --git a/src/gui/image/qpicture_p.h b/src/gui/image/qpicture_p.h index 56e6e1249c4e0479f5e76d627a5fb334280b0f5e..a414a122f124a5ed0f2cb8f83580669dc68d30a7 100644 --- a/src/gui/image/qpicture_p.h +++ b/src/gui/image/qpicture_p.h @@ -48,6 +48,7 @@ #include "QtCore/qatomic.h" #include "QtCore/qbuffer.h" #include "QtCore/qobjectdefs.h" +#include "QtCore/qvector.h" #include "QtGui/qpicture.h" #include "QtGui/qpixmap.h" #include "QtGui/qpen.h" @@ -150,8 +151,8 @@ public: QRect override_rect; QScopedPointer<QPaintEngine> paintEngine; bool in_memory_only; - QList<QImage> image_list; - QList<QPixmap> pixmap_list; + QVector<QImage> image_list; + QVector<QPixmap> pixmap_list; QList<QBrush> brush_list; QList<QPen> pen_list; }; diff --git a/src/gui/image/qpictureformatplugin.h b/src/gui/image/qpictureformatplugin.h index 773c0180d3537d31c8a6544a3743f22155c28f36..9ad938fa79e1feccf3d4d142ebf2318381abd729 100644 --- a/src/gui/image/qpictureformatplugin.h +++ b/src/gui/image/qpictureformatplugin.h @@ -53,7 +53,7 @@ class Q_GUI_EXPORT QPictureFormatPlugin : public QObject { Q_OBJECT public: - explicit QPictureFormatPlugin(QObject *parent = 0); + explicit QPictureFormatPlugin(QObject *parent = Q_NULLPTR); ~QPictureFormatPlugin(); virtual bool loadPicture(const QString &format, const QString &filename, QPicture *pic); diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h index 51b02acfcf31b4ec99df4a566e47fa573774796d..48db7a3840bee94cbbaafd9a0b7cc36db5765ae5 100644 --- a/src/gui/image/qpixmap.h +++ b/src/gui/image/qpixmap.h @@ -58,7 +58,7 @@ public: explicit QPixmap(QPlatformPixmap *data); QPixmap(int w, int h); explicit QPixmap(const QSize &); - QPixmap(const QString& fileName, const char *format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor); + QPixmap(const QString& fileName, const char *format = Q_NULLPTR, Qt::ImageConversionFlags flags = Qt::AutoColor); #ifndef QT_NO_IMAGEFORMAT_XPM explicit QPixmap(const char * const xpm[]); #endif @@ -131,19 +131,19 @@ public: } #endif - bool load(const QString& fileName, const char *format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor); - bool loadFromData(const uchar *buf, uint len, const char* format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor); - inline bool loadFromData(const QByteArray &data, const char* format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor); - bool save(const QString& fileName, const char* format = 0, int quality = -1) const; - bool save(QIODevice* device, const char* format = 0, int quality = -1) const; + bool load(const QString& fileName, const char *format = Q_NULLPTR, Qt::ImageConversionFlags flags = Qt::AutoColor); + bool loadFromData(const uchar *buf, uint len, const char* format = Q_NULLPTR, Qt::ImageConversionFlags flags = Qt::AutoColor); + inline bool loadFromData(const QByteArray &data, const char* format = Q_NULLPTR, Qt::ImageConversionFlags flags = Qt::AutoColor); + bool save(const QString& fileName, const char* format = Q_NULLPTR, int quality = -1) const; + bool save(QIODevice* device, const char* format = Q_NULLPTR, int quality = -1) const; bool convertFromImage(const QImage &img, Qt::ImageConversionFlags flags = Qt::AutoColor); inline QPixmap copy(int x, int y, int width, int height) const; QPixmap copy(const QRect &rect = QRect()) const; - inline void scroll(int dx, int dy, int x, int y, int width, int height, QRegion *exposed = 0); - void scroll(int dx, int dy, const QRect &rect, QRegion *exposed = 0); + inline void scroll(int dx, int dy, int x, int y, int width, int height, QRegion *exposed = Q_NULLPTR); + void scroll(int dx, int dy, const QRect &rect, QRegion *exposed = Q_NULLPTR); #if QT_DEPRECATED_SINCE(5, 0) QT_DEPRECATED inline int serialNumber() const { return cacheKey() >> 32; } diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp index f24cbc3db98f355a5e7583564c4a3dd97c81c482..b254c5a2af2b737be92924fb1270d00ead1238e4 100644 --- a/src/gui/image/qpixmap_blitter.cpp +++ b/src/gui/image/qpixmap_blitter.cpp @@ -115,6 +115,8 @@ int QBlittablePlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) con return qt_defaultDpiY(); case QPaintDevice::PdmDevicePixelRatio: return devicePixelRatio(); + case QPaintDevice::PdmDevicePixelRatioScaled: + return devicePixelRatio() * QPaintDevice::devicePixelRatioFScale(); default: qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric); break; diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index 9c8835a7a060482aabc4be6858778c627846d71a..a2b84b358e2d21ba4de99141e8bd027386b4c74f 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -288,6 +288,9 @@ int QRasterPlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const return qt_defaultDpiY(); case QPaintDevice::PdmDevicePixelRatio: return image.devicePixelRatio(); + case QPaintDevice::PdmDevicePixelRatioScaled: + return image.devicePixelRatio() * QPaintDevice::devicePixelRatioFScale(); + default: qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric); break; diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index f9c362e194067180ee375dc944d1b8fe9b02532f..0fefa1f7eaa7e43a2988f4b0e2d5095b0a42fc58 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -137,6 +137,24 @@ bool QPixmapCache::Key::operator ==(const Key &key) const \internal */ +/*! + \fn QPixmapCache::Key::Key(Key &&) + \internal + \since 5.6 +*/ + +/*! + \fn QPixmapCache::Key &QPixmapCache::Key::operator=(Key &&) + \internal + \since 5.6 +*/ + +/*! + \fn void QPixmapCache::Key::swap(Key &) + \internal + \since 5.6 +*/ + /*! \internal */ @@ -179,7 +197,6 @@ public: static QPixmapCache::KeyData* getKeyData(QPixmapCache::Key *key); - QList< QPair<QString,QPixmap> > allPixmaps() const; bool flushDetachedPixmaps(bool nt); private: @@ -423,20 +440,6 @@ QPixmapCache::KeyData* QPMCache::getKeyData(QPixmapCache::Key *key) return key->d; } -QList< QPair<QString,QPixmap> > QPMCache::allPixmaps() const -{ - QList< QPair<QString,QPixmap> > r; - QHash<QString, QPixmapCache::Key>::const_iterator it = cacheKeys.begin(); - while (it != cacheKeys.end()) { - QPixmap *ptr = QCache<QPixmapCache::Key, QPixmapCacheEntry>::object(it.value()); - if (ptr) - r.append(QPair<QString,QPixmap>(it.key(),*ptr)); - ++it; - } - return r; -} - - Q_GLOBAL_STATIC(QPMCache, pm_cache) int Q_AUTOTEST_EXPORT q_QPixmapCache_keyHashSize() @@ -656,9 +659,4 @@ int QPixmapCache::totalUsed() return (pm_cache()->totalCost()+1023) / 1024; } -QList< QPair<QString,QPixmap> > QPixmapCache::allPixmaps() -{ - return pm_cache()->allPixmaps(); -} - QT_END_NAMESPACE diff --git a/src/gui/image/qpixmapcache.h b/src/gui/image/qpixmapcache.h index 345389e9873afac5ac677ff5040818c12d35915f..37a0588e0644b7cc39dc1b8f00c3f0c28771722a 100644 --- a/src/gui/image/qpixmapcache.h +++ b/src/gui/image/qpixmapcache.h @@ -36,10 +36,6 @@ #include <QtGui/qpixmap.h> -#ifdef Q_TEST_QPIXMAPCACHE -#include <QtCore/qpair.h> -#endif - QT_BEGIN_NAMESPACE @@ -52,12 +48,18 @@ public: public: Key(); Key(const Key &other); +#ifdef Q_COMPILER_RVALUE_REFS + Key(Key &&other) Q_DECL_NOTHROW : d(other.d) { other.d = Q_NULLPTR; } + Key &operator =(Key &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif ~Key(); bool operator ==(const Key &key) const; inline bool operator !=(const Key &key) const { return !operator==(key); } Key &operator =(const Key &other); + void swap(Key &other) Q_DECL_NOTHROW { qSwap(d, other.d); } + private: KeyData *d; friend class QPMCache; @@ -80,9 +82,9 @@ public: #ifdef Q_TEST_QPIXMAPCACHE static void flushDetachedPixmaps(); static int totalUsed(); - static QList< QPair<QString,QPixmap> > allPixmaps(); #endif }; +Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QPixmapCache::Key) QT_END_NAMESPACE diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 7fbd24787e2b88504cb1e4250034a8feed1ff869..776a61d8fe190bbd488e3626738ed476d82e2c43 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -108,10 +108,11 @@ public: }; QPngHandlerPrivate(QPngHandler *qq) - : gamma(0.0), quality(2), png_ptr(0), info_ptr(0), end_info(0), state(Ready), q(qq) + : gamma(0.0), fileGamma(0.0), quality(2), png_ptr(0), info_ptr(0), end_info(0), state(Ready), q(qq) { } float gamma; + float fileGamma; int quality; QString description; QSize scaledSize; @@ -234,13 +235,10 @@ void CALLBACK_CALL_TYPE qpiw_flush_fn(png_structp /* png_ptr */) } static -void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead, float screen_gamma=0.0) +void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead, float screen_gamma=0.0, float file_gamma=0.0) { - if (screen_gamma != 0.0 && png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) { - double file_gamma; - png_get_gAMA(png_ptr, info_ptr, &file_gamma); - png_set_gamma(png_ptr, screen_gamma, file_gamma); - } + if (screen_gamma != 0.0 && file_gamma != 0.0) + png_set_gamma(png_ptr, 1.0f / screen_gamma, file_gamma); png_uint_32 width; png_uint_32 height; @@ -557,6 +555,12 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngHeader() readPngTexts(info_ptr); + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) { + double file_gamma = 0.0; + png_get_gAMA(png_ptr, info_ptr, &file_gamma); + fileGamma = file_gamma; + } + state = ReadHeader; return true; } @@ -580,7 +584,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngImage(QImage *outImage) } bool doScaledRead = false; - setup_qt(*outImage, png_ptr, info_ptr, scaledSize, &doScaledRead, gamma); + setup_qt(*outImage, png_ptr, info_ptr, scaledSize, &doScaledRead, gamma, fileGamma); if (outImage->isNull()) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); @@ -1063,7 +1067,7 @@ QVariant QPngHandler::option(ImageOption option) const return QVariant(); if (option == Gamma) - return d->gamma; + return d->gamma == 0.0 ? d->fileGamma : d->gamma; else if (option == Quality) return d->quality; else if (option == Description) diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp index 7dc42544eba4621d67e2ff6a9c0e972dc2fa119a..25b82b94b593cc5f2c586efb7fc5faa4c077a112 100644 --- a/src/gui/itemmodels/qstandarditemmodel.cpp +++ b/src/gui/itemmodels/qstandarditemmodel.cpp @@ -1266,7 +1266,8 @@ void QStandardItem::setCheckable(bool checkable) */ /*! - Sets whether the item is tristate and controlled by QTreeWidget. + Determines that the item is tristate and controlled by QTreeWidget if \a tristate + is \c true. This enables automatic management of the state of parent items in QTreeWidget (checked if all children are checked, unchecked if all children are unchecked, or partially checked if only some children are checked). @@ -1803,6 +1804,7 @@ QList<QStandardItem*> QStandardItem::takeRow(int row) int index = d->childIndex(row, 0); // Will return -1 if there are no columns if (index != -1) { int col_count = d->columnCount(); + items.reserve(col_count); for (int column = 0; column < col_count; ++column) { QStandardItem *ch = d->children.at(index + column); if (ch) @@ -1864,9 +1866,11 @@ bool QStandardItem::operator<(const QStandardItem &other) const const int role = model() ? model()->sortRole() : Qt::DisplayRole; const QVariant l = data(role), r = other.data(role); // this code is copied from QSortFilterProxyModel::lessThan() + if (l.userType() == QVariant::Invalid) + return false; + if (r.userType() == QVariant::Invalid) + return true; switch (l.userType()) { - case QVariant::Invalid: - return (r.type() == QVariant::Invalid); case QVariant::Int: return l.toInt() < r.toInt(); case QVariant::UInt: @@ -2518,7 +2522,9 @@ QList<QStandardItem*> QStandardItemModel::findItems(const QString &text, QModelIndexList indexes = match(index(0, column, QModelIndex()), Qt::DisplayRole, text, -1, flags); QList<QStandardItem*> items; - for (int i = 0; i < indexes.size(); ++i) + const int numIndexes = indexes.size(); + items.reserve(numIndexes); + for (int i = 0; i < numIndexes; ++i) items.append(itemFromIndex(indexes.at(i))); return items; } diff --git a/src/gui/itemmodels/qstandarditemmodel.h b/src/gui/itemmodels/qstandarditemmodel.h index 44156d1907abf8655487910e9310532e59d9728f..8740f7940b10b617896bca17f74f54acd38789e3 100644 --- a/src/gui/itemmodels/qstandarditemmodel.h +++ b/src/gui/itemmodels/qstandarditemmodel.h @@ -320,8 +320,8 @@ class Q_GUI_EXPORT QStandardItemModel : public QAbstractItemModel Q_PROPERTY(int sortRole READ sortRole WRITE setSortRole) public: - explicit QStandardItemModel(QObject *parent = 0); - QStandardItemModel(int rows, int columns, QObject *parent = 0); + explicit QStandardItemModel(QObject *parent = Q_NULLPTR); + QStandardItemModel(int rows, int columns, QObject *parent = Q_NULLPTR); ~QStandardItemModel(); void setItemRoleNames(const QHash<int,QByteArray> &roleNames); @@ -415,7 +415,7 @@ Q_SIGNALS: void itemChanged(QStandardItem *item); protected: - QStandardItemModel(QStandardItemModelPrivate &dd, QObject *parent = 0); + QStandardItemModel(QStandardItemModelPrivate &dd, QObject *parent = Q_NULLPTR); private: friend class QStandardItemPrivate; diff --git a/src/gui/itemmodels/qstandarditemmodel_p.h b/src/gui/itemmodels/qstandarditemmodel_p.h index 491a49f9c2d981bbe7e7cd9c794364f12ac3b679..b49045d2832850699f456ff9c4ec90fe05e7c39e 100644 --- a/src/gui/itemmodels/qstandarditemmodel_p.h +++ b/src/gui/itemmodels/qstandarditemmodel_p.h @@ -61,7 +61,7 @@ class QStandardItemData { public: inline QStandardItemData() : role(-1) {} - inline QStandardItemData(int r, QVariant v) : role(r), value(v) {} + inline QStandardItemData(int r, const QVariant &v) : role(r), value(v) {} int role; QVariant value; inline bool operator==(const QStandardItemData &other) const { return role == other.role && value == other.value; } diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 953398376316e50e1e27ccf4027d48bff19ff358..7686a2a5048b136b8e1ba4c52daaa30d0721feda 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -76,7 +76,9 @@ HEADERS += \ kernel/qplatformgraphicsbuffer.h \ kernel/qplatformgraphicsbufferhelper.h \ kernel/qinputdevicemanager_p.h \ - kernel/qinputdevicemanager_p_p.h + kernel/qinputdevicemanager_p_p.h \ + kernel/qhighdpiscaling_p.h + SOURCES += \ kernel/qgenericpluginfactory.cpp \ @@ -133,7 +135,9 @@ SOURCES += \ kernel/qrasterwindow.cpp \ kernel/qplatformgraphicsbuffer.cpp \ kernel/qplatformgraphicsbufferhelper.cpp \ - kernel/qinputdevicemanager.cpp + kernel/qinputdevicemanager.cpp \ + kernel/qhighdpiscaling.cpp + contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) { HEADERS += \ diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp index 402f5005fdec0300ec0b499f188ae36380847526..922c7fb8d9bc23f992607ac40f6ec0a669674f9d 100644 --- a/src/gui/kernel/qclipboard.cpp +++ b/src/gui/kernel/qclipboard.cpp @@ -110,22 +110,22 @@ QT_BEGIN_NAMESPACE \endlist - \section1 Notes for Mac OS X Users + \section1 Notes for OS X Users - Mac OS X supports a separate find buffer that holds the current + OS X supports a separate find buffer that holds the current search string in Find operations. This find clipboard can be accessed by specifying the FindBuffer mode. - \section1 Notes for Windows and Mac OS X Users + \section1 Notes for Windows and OS X Users \list - \li Windows and Mac OS X do not support the global mouse + \li Windows and OS X do not support the global mouse selection; they only supports the global clipboard, i.e. they only add text to the clipboard when an explicit copy or cut is made. - \li Windows and Mac OS X does not have the concept of ownership; + \li Windows and OS X does not have the concept of ownership; the clipboard is a fully global resource so all applications are notified of changes. @@ -181,7 +181,7 @@ QClipboard::~QClipboard() This signal is emitted when the clipboard data is changed. - On Mac OS X and with Qt version 4.3 or higher, clipboard + On OS X and with Qt version 4.3 or higher, clipboard changes made by other applications will only be detected when the application is activated. @@ -193,7 +193,7 @@ QClipboard::~QClipboard() This signal is emitted when the selection is changed. This only applies to windowing systems that support selections, e.g. X11. - Windows and Mac OS X don't support selections. + Windows and OS X don't support selections. \sa dataChanged(), findBufferChanged(), changed() */ @@ -203,7 +203,7 @@ QClipboard::~QClipboard() \since 4.2 This signal is emitted when the find buffer is changed. This only - applies to Mac OS X. + applies to OS X. With Qt version 4.3 or higher, clipboard changes made by other applications will only be detected when the application is activated. @@ -226,7 +226,7 @@ QClipboard::~QClipboard() systems with a global mouse selection (e.g. X11). \value FindBuffer indicates that data should be stored and retrieved from - the Find buffer. This mode is used for holding search strings on Mac OS X. + the Find buffer. This mode is used for holding search strings on OS X. \omitvalue LastMode diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp index 6ed750eda12215b2150f9d586ba0d5d5ad9c22b4..dbf2b3c21ff5348c34975d1edf5df92a72d5b82b 100644 --- a/src/gui/kernel/qcursor.cpp +++ b/src/gui/kernel/qcursor.cpp @@ -43,6 +43,7 @@ #include <qpa/qplatformcursor.h> #include <private/qguiapplication_p.h> +#include <private/qhighdpiscaling_p.h> QT_BEGIN_NAMESPACE @@ -177,9 +178,14 @@ QT_BEGIN_NAMESPACE */ QPoint QCursor::pos(const QScreen *screen) { - if (screen) - if (const QPlatformCursor *cursor = screen->handle()->cursor()) - return cursor->pos(); + if (screen) { + if (const QPlatformCursor *cursor = screen->handle()->cursor()) { + const QPlatformScreen *ps = screen->handle(); + QPoint nativePos = cursor->pos(); + ps = ps->screenForPosition(nativePos); + return QHighDpi::fromNativePixels(nativePos, ps->screen()); + } + } return QGuiApplicationPrivate::lastCursorPosition.toPoint(); } @@ -231,12 +237,12 @@ void QCursor::setPos(QScreen *screen, int x, int y) { if (screen) { if (QPlatformCursor *cursor = screen->handle()->cursor()) { - const QPoint pos = QPoint(x, y); + const QPoint devicePos = QHighDpi::toNativePixels(QPoint(x, y), screen); // Need to check, since some X servers generate null mouse move // events, causing looping in applications which call setPos() on // every mouse move event. - if (pos != cursor->pos()) - cursor->setPos(pos); + if (devicePos != cursor->pos()) + cursor->setPos(devicePos); } } } diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp index 3ce8ab95ec61fba6fe15486cd9fcfb29d9a88c4b..b05da1bfd01e4ae7b97fe90021e561598260bb45 100644 --- a/src/gui/kernel/qdnd.cpp +++ b/src/gui/kernel/qdnd.cpp @@ -147,7 +147,9 @@ static QStringList imageReadMimeFormats() { QStringList formats; QList<QByteArray> imageFormats = QImageReader::supportedImageFormats(); - for (int i = 0; i < imageFormats.size(); ++i) { + const int numImageFormats = imageFormats.size(); + formats.reserve(numImageFormats); + for (int i = 0; i < numImageFormats; ++i) { QString format = QLatin1String("image/"); format += QString::fromLatin1(imageFormats.at(i).toLower()); formats.append(format); @@ -166,7 +168,9 @@ static QStringList imageWriteMimeFormats() { QStringList formats; QList<QByteArray> imageFormats = QImageWriter::supportedImageFormats(); - for (int i = 0; i < imageFormats.size(); ++i) { + const int numImageFormats = imageFormats.size(); + formats.reserve(numImageFormats); + for (int i = 0; i < numImageFormats; ++i) { QString format = QLatin1String("image/"); format += QString::fromLatin1(imageFormats.at(i).toLower()); formats.append(format); diff --git a/src/gui/kernel/qdrag.cpp b/src/gui/kernel/qdrag.cpp index 723b83d338b9f7f27eb1657b5d69f60b928fefb5..2736fac8e0beb714eea0bcd966eb4840540982a6 100644 --- a/src/gui/kernel/qdrag.cpp +++ b/src/gui/kernel/qdrag.cpp @@ -218,7 +218,7 @@ QObject *QDrag::target() const from are specified in \a supportedActions. The default proposed action will be selected among the allowed actions in the following order: Move, Copy and Link. - \b{Note:} On Linux and Mac OS X, the drag and drop operation + \b{Note:} On Linux and OS X, the drag and drop operation can take some time, but this function does not block the event loop. Other events are still delivered to the application while the operation is performed. On Windows, the Qt event loop is @@ -240,7 +240,7 @@ Qt::DropAction QDrag::exec(Qt::DropActions supportedActions) The \a defaultDropAction determines which action will be proposed when the user performs a drag without using modifier keys. - \b{Note:} On Linux and Mac OS X, the drag and drop operation + \b{Note:} On Linux and OS X, the drag and drop operation can take some time, but this function does not block the event loop. Other events are still delivered to the application while the operation is performed. On Windows, the Qt event loop is diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 1dc3e69470b50cc21596d10779aaedfab4e7f8c1..adbaa5ff86b62c3efd77856fd1e111bd94912269 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -605,7 +605,7 @@ QHoverEvent::~QHoverEvent() wheel event delta: angleDelta() returns the delta in wheel degrees. This value is always provided. pixelDelta() returns the delta in screen pixels and is available on platforms that - have high-resolution trackpads, such as Mac OS X. If that is the + have high-resolution trackpads, such as OS X. If that is the case, source() will return Qt::MouseEventSynthesizedBySystem. The functions pos() and globalPos() return the mouse cursor's @@ -825,7 +825,7 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, Returns the scrolling distance in pixels on screen. This value is provided on platforms that support high-resolution pixel-based - delta values, such as Mac OS X. The value should be used directly + delta values, such as OS X. The value should be used directly to scroll content on screen. Example: @@ -966,7 +966,7 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, Returns the scrolling phase of this wheel event. \note The Qt::ScrollBegin and Qt::ScrollEnd phases are currently - supported only on Mac OS X. + supported only on OS X. */ @@ -1578,7 +1578,7 @@ QCloseEvent::~QCloseEvent() \ingroup events Icon drag events are sent to widgets when the main icon of a window - has been dragged away. On Mac OS X, this happens when the proxy + has been dragged away. On OS X, this happens when the proxy icon of a window is dragged off the title bar. It is normal to begin using drag and drop in response to this @@ -3357,12 +3357,12 @@ QShowEvent::~QShowEvent() when the operating system requests that a file or URL should be opened. This is a high-level event that can be caused by different user actions depending on the user's desktop environment; for example, double - clicking on an file icon in the Finder on Mac OS X. + clicking on an file icon in the Finder on OS X. This event is only used to notify the application of a request. It may be safely ignored. - \note This class is currently supported for Mac OS X only. + \note This class is currently supported for OS X only. */ /*! @@ -3428,7 +3428,7 @@ bool QFileOpenEvent::openFile(QFile &file, QIODevice::OpenMode flags) const \internal \class QToolBarChangeEvent \brief The QToolBarChangeEvent class provides an event that is - sent whenever a the toolbar button is clicked on Mac OS X. + sent whenever a the toolbar button is clicked on OS X. \ingroup events \inmodule QtGui diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index dd7b35e2bbc64ab7c9fc557fe205495d2fcccf42..b90fce97e0d119635371deb538960cb5987b6287 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -522,7 +522,7 @@ public: }; class Attribute { public: - Attribute(AttributeType t, int s, int l, QVariant val) : type(t), start(s), length(l), value(val) {} + Attribute(AttributeType t, int s, int l, QVariant val) : type(t), start(s), length(l), value(qMove(val)) {} AttributeType type; int start; @@ -699,7 +699,7 @@ class Q_GUI_EXPORT QActionEvent : public QEvent { QAction *act, *bef; public: - QActionEvent(int type, QAction *action, QAction *before = 0); + QActionEvent(int type, QAction *action, QAction *before = Q_NULLPTR); ~QActionEvent(); inline QAction *action() const { return act; } @@ -876,9 +876,9 @@ public: #endif explicit QTouchEvent(QEvent::Type eventType, - QTouchDevice *device = 0, + QTouchDevice *device = Q_NULLPTR, Qt::KeyboardModifiers modifiers = Qt::NoModifier, - Qt::TouchPointStates touchPointStates = 0, + Qt::TouchPointStates touchPointStates = Qt::TouchPointStates(), const QList<QTouchEvent::TouchPoint> &touchPoints = QList<QTouchEvent::TouchPoint>()); ~QTouchEvent(); diff --git a/src/gui/kernel/qgenericplugin.h b/src/gui/kernel/qgenericplugin.h index cfab34d08139f31d851a2c2d83a05b7c041ab078..03c1df7fba5ff83a5bca0f4c9e426f07fd3aba0c 100644 --- a/src/gui/kernel/qgenericplugin.h +++ b/src/gui/kernel/qgenericplugin.h @@ -48,7 +48,7 @@ class Q_GUI_EXPORT QGenericPlugin : public QObject { Q_OBJECT public: - explicit QGenericPlugin(QObject *parent = 0); + explicit QGenericPlugin(QObject *parent = Q_NULLPTR); ~QGenericPlugin(); virtual QObject* create(const QString& name, const QString &spec) = 0; diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 01a4a2d85b29669e56b5bcf326019303212c2c5c..9bff1429c3cded9c1021a8b83c9f7ac0bd3ea4d2 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -959,8 +959,10 @@ QWindow *QGuiApplication::topLevelAt(const QPoint &pos) QList<QScreen *>::const_iterator end = screens.constEnd(); while (screen != end) { - if ((*screen)->geometry().contains(pos)) - return (*screen)->handle()->topLevelAt(pos); + if ((*screen)->geometry().contains(pos)) { + const QPoint devicePosition = QHighDpi::toNativePixels(pos, *screen); + return (*screen)->handle()->topLevelAt(devicePosition); + } ++screen; } return 0; @@ -975,7 +977,7 @@ QWindow *QGuiApplication::topLevelAt(const QPoint &pos) \list \li \c android - \li \c cocoa is a platform plugin for Mac OS X. + \li \c cocoa is a platform plugin for OS X. \li \c directfb \li \c eglfs is a platform plugin for running Qt5 applications on top of EGL and OpenGL ES 2.0 without an actual windowing system (like X11 @@ -1123,6 +1125,9 @@ void QGuiApplicationPrivate::createPlatformIntegration() // this flag. QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true); + + QHighDpiScaling::initHighDpiScaling(); + // Load the platform integration QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH")); @@ -1212,6 +1217,10 @@ void QGuiApplicationPrivate::eventDispatcherReady() createPlatformIntegration(); platform_integration->initialize(); + + // Do this here in order to play nice with platforms that add screens only + // in initialize(). + QHighDpiScaling::updateHighDpiScaling(); } void QGuiApplicationPrivate::init() @@ -1353,6 +1362,8 @@ void QGuiApplicationPrivate::init() qCritical() << "Library qttestability load failed:" << testLib.errorString(); } } +#else + Q_UNUSED(loadTestability); #endif // QT_NO_LIBRARY } @@ -1827,7 +1838,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo points << point; QEvent::Type type; - QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type); + QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, window, &type); QWindowSystemInterfacePrivate::TouchEvent fake(window, e->timestamp, type, m_fakeTouchDevice, touchPoints, e->modifiers); fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic; @@ -1894,7 +1905,7 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE #if !defined(Q_OS_OSX) // On OS X the shortcut override is checked earlier, see: QWindowSystemInterface::handleKeyEvent() const bool checkShortcut = e->keyType == QEvent::KeyPress && window != 0; - if (checkShortcut && QWindowSystemInterface::tryHandleShortcutEvent(window, e->timestamp, e->key, e->modifiers, e->unicode)) + if (checkShortcut && QWindowSystemInterface::tryHandleShortcutEvent(window, e->timestamp, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount)) return; #endif // Q_OS_OSX @@ -2038,6 +2049,11 @@ void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterf window->d_func()->setTopLevelScreen(screen, false /* recreate */); else // Fall back to default behavior, and try to find some appropriate screen window->setScreen(0); + // we may have changed scaling, so trigger resize event if needed + if (window->handle()) { + QWindowSystemInterfacePrivate::GeometryChangeEvent gce(window, QHighDpi::fromNativePixels(window->handle()->geometry(), window), QRect()); + processGeometryChangeEvent(&gce); + } } } diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp new file mode 100644 index 0000000000000000000000000000000000000000..19e3045fc95b3e64630f1bc1073736fed25c8284 --- /dev/null +++ b/src/gui/kernel/qhighdpiscaling.cpp @@ -0,0 +1,320 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qhighdpiscaling_p.h" +#include "qguiapplication.h" +#include "qscreen.h" +#include "qplatformintegration.h" +#include "private/qscreen_p.h" + +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcScaling, "qt.scaling"); + +static const char legacyDevicePixelEnvVar[] = "QT_DEVICE_PIXEL_RATIO"; +static const char scaleFactorEnvVar[] = "QT_SCALE_FACTOR"; +static const char autoScreenEnvVar[] = "QT_AUTO_SCREEN_SCALE_FACTOR"; +static const char screenFactorsEnvVar[] = "QT_SCREEN_SCALE_FACTORS"; + +static inline qreal initialScaleFactor() +{ + + qreal result = 1; + if (qEnvironmentVariableIsSet(scaleFactorEnvVar)) { + bool ok; + const qreal f = qgetenv(scaleFactorEnvVar).toDouble(&ok); + if (ok && f > 0) { + qCDebug(lcScaling) << "Apply " << scaleFactorEnvVar << f; + result = f; + } + } else { + if (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar)) { + qWarning() << "Warning:" << legacyDevicePixelEnvVar << "is deprecated. Instead use:"; + qWarning() << " " << autoScreenEnvVar << "to enable platform plugin controlled per-screen factors."; + qWarning() << " " << screenFactorsEnvVar << "to set per-screen factors."; + qWarning() << " " << scaleFactorEnvVar << "to set the application global scale factor."; + + int dpr = qEnvironmentVariableIntValue(legacyDevicePixelEnvVar); + if (dpr > 0) + result = dpr; + } + } + return result; +} + +/*! + \class QHighDpiScaling + \since 5.6 + \internal + \preliminary + \ingroup qpa + + \brief Collection of utility functions for UI scaling. + + QHighDpiScaling implements utility functions for high-dpi scaling for use + on operating systems that provide limited support for native scaling. In + addition this functionality can be used for simulation and testing purposes. + + The functions support scaling between the device independent coordinate + system used by Qt applications and the native coordinate system used by + the platform plugins. Intended usage locations are the low level / platform + plugin interfacing parts of QtGui, for example the QWindow, QScreen and + QWindowSystemInterface implementation. + + The coordinate system scaling is enabled by setting one or more scale + factors. These will then be factored into the value returned by the + devicePixelRatio() accessors (any native scale factor will also be + included in this value). Several setters are available: + + - A process-global scale factor + - QT_SCALE_FACTOR (environment variable) + - QHighDpiScaling::setGlobalFactor() + + - A per-screen scale factor + - QT_AUTO_SCALE_FACTOR (environment variable) + Setting this to a true-ish value will make QHighDpiScaling + call QPlatformScreen::pixelDensity() + - QHighDpiScaling::setScreenFactor(screen, factor); + - QT_SCREEN_SCALE_FACTORS (environment variable) + Set this to a semicolon-separated list of scale factors + (matching the order of QGuiApplications::screens()), + or to a list of name=value pairs (where name matches + QScreen::name()). + + All scale factors are of type qreal. + + The main scaling functions for use in QtGui are: + T toNativePixels(T, QWindow *) + T fromNativePixels(T, QWindow*) + Where T is QPoint, QSize, QRect etc. +*/ + +qreal QHighDpiScaling::m_factor = 1.0; +bool QHighDpiScaling::m_active = false; //"overall active" - is there any scale factor set. +bool QHighDpiScaling::m_usePixelDensity = false; // use scale factor from platform plugin +bool QHighDpiScaling::m_pixelDensityScalingActive = false; // pixel density scale factor > 1 +bool QHighDpiScaling::m_globalScalingActive = false; // global scale factor is active +bool QHighDpiScaling::m_screenFactorSet = false; // QHighDpiScaling::setScreenFactor has been used +QDpi QHighDpiScaling::m_logicalDpi = QDpi(-1,-1); // The scaled logical DPI of the primary screen + +/* + Initializes the QHighDpiScaling global variables. Called before the + platform plugin is created. +*/ +void QHighDpiScaling::initHighDpiScaling() +{ + if (QCoreApplication::testAttribute(Qt::AA_NoHighDpiScaling)) { + m_factor = 1; + m_active = false; + return; + } + m_factor = initialScaleFactor(); + bool usePlatformPluginPixelDensity = qEnvironmentVariableIsSet(autoScreenEnvVar) + || qgetenv(legacyDevicePixelEnvVar).toLower() == "auto"; + + m_globalScalingActive = !qFuzzyCompare(m_factor, qreal(1)); + m_usePixelDensity = usePlatformPluginPixelDensity; + m_pixelDensityScalingActive = false; //set in updateHighDpiScaling below + + // we update m_active in updateHighDpiScaling, but while we create the + // screens, we have to assume that m_usePixelDensity implies scaling + m_active = m_globalScalingActive || m_usePixelDensity; +} + +void QHighDpiScaling::updateHighDpiScaling() +{ + if (QCoreApplication::testAttribute(Qt::AA_NoHighDpiScaling)) + return; + + if (m_usePixelDensity && !m_pixelDensityScalingActive) { + Q_FOREACH (QScreen *screen, QGuiApplication::screens()) { + if (!qFuzzyCompare(screenSubfactor(screen->handle()), qreal(1))) { + m_pixelDensityScalingActive = true; + break; + } + } + } + if (qEnvironmentVariableIsSet(screenFactorsEnvVar)) { + int i = 0; + Q_FOREACH (const QByteArray &spec, qgetenv(screenFactorsEnvVar).split(';')) { + QScreen *screen = 0; + int equalsPos = spec.lastIndexOf('='); + double factor = 0; + if (equalsPos > 0) { + // support "name=factor" + QByteArray name = spec.mid(0, equalsPos); + QByteArray f = spec.mid(equalsPos + 1); + bool ok; + factor = f.toDouble(&ok); + if (ok) { + Q_FOREACH (QScreen *s, QGuiApplication::screens()) { + if (s->name() == QString::fromLocal8Bit(name)) { + screen = s; + break; + } + } + } + } else { + // listing screens in order + bool ok; + factor = spec.toDouble(&ok); + if (ok && i < QGuiApplication::screens().count()) + screen = QGuiApplication::screens().at(i); + } + if (screen) + setScreenFactor(screen, factor); + ++i; + } + } + m_active = m_globalScalingActive || m_screenFactorSet || m_pixelDensityScalingActive; + + QPlatformScreen *primaryScreen = QGuiApplication::primaryScreen()->handle(); + qreal sf = screenSubfactor(primaryScreen); + QDpi primaryDpi = primaryScreen->logicalDpi(); + m_logicalDpi = QDpi(primaryDpi.first / sf, primaryDpi.second / sf); +} + +/* + Sets the global scale factor which is applied to all windows. +*/ +void QHighDpiScaling::setGlobalFactor(qreal factor) +{ + if (qFuzzyCompare(factor, m_factor)) + return; + if (!QGuiApplication::allWindows().isEmpty()) + qWarning() << Q_FUNC_INFO << "QHighDpiScaling::setFactor: Should only be called when no windows exist."; + + m_globalScalingActive = !qFuzzyCompare(factor, qreal(1)); + m_factor = m_globalScalingActive ? factor : qreal(1); + m_active = m_globalScalingActive || m_screenFactorSet || m_pixelDensityScalingActive; + Q_FOREACH (QScreen *screen, QGuiApplication::screens()) + screen->d_func()->updateHighDpi(); +} + +static const char scaleFactorProperty[] = "_q_scaleFactor"; + +/* + Sets a per-screen scale factor. +*/ +void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor) +{ + m_screenFactorSet = true; + m_active = true; + screen->setProperty(scaleFactorProperty, QVariant(factor)); + + // hack to force re-evaluation of screen geometry + if (screen->handle()) + screen->d_func()->setPlatformScreen(screen->handle()); // updates geometries based on scale factor +} + +QPoint QHighDpiScaling::mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen) +{ + if (!platformScreen) + return pos; + const qreal scaleFactor = factor(platformScreen); + const QPoint topLeft = platformScreen->geometry().topLeft(); + return (pos - topLeft) * scaleFactor + topLeft; +} + +QPoint QHighDpiScaling::mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen) +{ + if (!platformScreen) + return pos; + const qreal scaleFactor = factor(platformScreen); + const QPoint topLeft = platformScreen->geometry().topLeft(); + return (pos - topLeft) / scaleFactor + topLeft; +} + +qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen) +{ + qreal factor = qreal(1.0); + if (screen) { + if (m_usePixelDensity) + factor *= screen->pixelDensity(); + if (m_screenFactorSet) { + QVariant screenFactor = screen->screen()->property(scaleFactorProperty); + if (screenFactor.isValid()) + factor *= screenFactor.toReal(); + } + } + return factor; +} + +QDpi QHighDpiScaling::logicalDpi() +{ + return m_logicalDpi; +} + +qreal QHighDpiScaling::factor(const QScreen *screen) +{ + // Fast path for when scaling in Qt is not used at all. + if (!m_active) + return qreal(1.0); + + // The effective factor for a given screen is the product of the + // screen and global sub-factors + qreal factor = m_factor; + if (screen) + factor *= screenSubfactor(screen->handle()); + return factor; +} + +qreal QHighDpiScaling::factor(const QPlatformScreen *platformScreen) +{ + if (!m_active) + return qreal(1.0); + + return m_factor * screenSubfactor(platformScreen); +} + +qreal QHighDpiScaling::factor(const QWindow *window) +{ + if (!m_active) + return qreal(1.0); + + return factor(window ? window->screen() : QGuiApplication::primaryScreen()); +} + +QPoint QHighDpiScaling::origin(const QScreen *screen) +{ + return screen->geometry().topLeft(); +} + +QPoint QHighDpiScaling::origin(const QPlatformScreen *platformScreen) +{ + return platformScreen->geometry().topLeft(); +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h new file mode 100644 index 0000000000000000000000000000000000000000..c79540d9e477c4753ae713b6e4ecc5b7ce02779d --- /dev/null +++ b/src/gui/kernel/qhighdpiscaling_p.h @@ -0,0 +1,470 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QHIGHDPISCALING_P_H +#define QHIGHDPISCALING_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> +#include <QtCore/qmargins.h> +#include <QtCore/qrect.h> +#include <QtCore/qvector.h> +#include <QtCore/qloggingcategory.h> +#include <QtGui/qregion.h> +#include <QtGui/qscreen.h> +#include <QtGui/qwindow.h> + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(lcScaling); + +class QScreen; +class QPlatformScreen; +typedef QPair<qreal, qreal> QDpi; + +class Q_GUI_EXPORT QHighDpiScaling { +public: + static void initHighDpiScaling(); + static void updateHighDpiScaling(); + static void setGlobalFactor(qreal factor); + static void setScreenFactor(QScreen *window, qreal factor); + + static bool isActive() { return m_active; } + static qreal factor(const QWindow *window); + static qreal factor(const QScreen *screen); + static qreal factor(const QPlatformScreen *platformScreen); + static QPoint origin(const QScreen *screen); + static QPoint origin(const QPlatformScreen *platformScreen); + static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen); + static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen); + static QDpi logicalDpi(); + +private: + static qreal screenSubfactor(const QPlatformScreen *screen); + + static qreal m_factor; + static bool m_active; + static bool m_usePixelDensity; + static bool m_globalScalingActive; + static bool m_pixelDensityScalingActive; + static bool m_screenFactorSet; + static QDpi m_logicalDpi; +}; + +// Coordinate system conversion functions: +// QHighDpi::fromNativePixels : from physical(screen/backing) to logical pixels +// QHighDpi::toNativePixels : from logical to physical pixels + +namespace QHighDpi { + +inline QPointF fromNative(const QPointF &pos, qreal scaleFactor, const QPointF &origin) +{ + return (pos - origin) / scaleFactor + origin; +} + +inline QPointF toNative(const QPointF &pos, qreal scaleFactor, const QPointF &origin) +{ + return (pos - origin) * scaleFactor + origin; +} + +inline QPoint fromNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin) +{ + return (pos - origin) / scaleFactor + origin; +} + +inline QPoint toNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin) +{ + return (pos - origin) * scaleFactor + origin; +} + +inline QPoint fromNative(const QPoint &pos, qreal scaleFactor) +{ + return pos / scaleFactor; +} + +inline QPoint toNative(const QPoint &pos, qreal scaleFactor) +{ + return pos * scaleFactor; +} + +inline QSize fromNative(const QSize &size, qreal scaleFactor) +{ + return size / scaleFactor; // TODO: should we round up? +} + +inline QSize toNative(const QSize &size, qreal scaleFactor) +{ + return size * scaleFactor; +} + +inline QSizeF fromNative(const QSizeF &size, qreal scaleFactor) +{ + return size / scaleFactor; +} + +inline QSizeF toNative(const QSizeF &size, qreal scaleFactor) +{ + return size * scaleFactor; +} + +inline QRect fromNative(const QRect &rect, qreal scaleFactor, const QPoint &origin) +{ + return QRect(fromNative(rect.topLeft(), scaleFactor, origin), fromNative(rect.size(), scaleFactor)); +} + +inline QRect toNative(const QRect &rect, qreal scaleFactor, const QPoint &origin) +{ + return QRect(toNative(rect.topLeft(), scaleFactor, origin), toNative(rect.size(), scaleFactor)); + +} + +inline QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin) +{ + return toNative(rect, QHighDpiScaling::factor(screen), screenOrigin); +} + +inline QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen) +{ + return QRect(nativeScreenGeometry.topLeft(), + fromNative(nativeScreenGeometry.size(), QHighDpiScaling::factor(screen))); +} + +inline QPoint fromNativeLocalPosition(const QPoint &pos, const QWindow *window) +{ + const qreal scaleFactor = QHighDpiScaling::factor(window); + return pos / scaleFactor; +} + +inline QPoint toNativeLocalPosition(const QPoint &pos, const QWindow *window) +{ + const qreal scaleFactor = QHighDpiScaling::factor(window); + return pos * scaleFactor; +} + +inline QPointF fromNativeLocalPosition(const QPointF &pos, const QWindow *window) +{ + const qreal scaleFactor = QHighDpiScaling::factor(window); + return pos / scaleFactor; +} + +inline QPointF toNativeLocalPosition(const QPointF &pos, const QWindow *window) +{ + const qreal scaleFactor = QHighDpiScaling::factor(window); + return pos * scaleFactor; +} + +inline QRect fromNativePixels(const QRect &pixelRect, const QPlatformScreen *platformScreen) +{ + const qreal scaleFactor = QHighDpiScaling::factor(platformScreen); + const QPoint origin = QHighDpiScaling::origin(platformScreen); + return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin), + fromNative(pixelRect.size(), scaleFactor)); +} + +inline QRect toNativePixels(const QRect &pointRect, const QPlatformScreen *platformScreen) +{ + const qreal scaleFactor = QHighDpiScaling::factor(platformScreen); + const QPoint origin = QHighDpiScaling::origin(platformScreen); + return QRect(toNative(pointRect.topLeft(), scaleFactor, origin), + toNative(pointRect.size(), scaleFactor)); +} + +inline QRect fromNativePixels(const QRect &pixelRect, const QScreen *screen) +{ + const qreal scaleFactor = QHighDpiScaling::factor(screen); + const QPoint origin = QHighDpiScaling::origin(screen); + return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin), + fromNative(pixelRect.size(), scaleFactor)); +} + +inline QRect toNativePixels(const QRect &pointRect, const QScreen *screen) +{ + const qreal scaleFactor = QHighDpiScaling::factor(screen); + const QPoint origin = QHighDpiScaling::origin(screen); + return QRect(toNative(pointRect.topLeft(), scaleFactor, origin), + toNative(pointRect.size(), scaleFactor)); +} + +inline QRect fromNativePixels(const QRect &pixelRect, const QWindow *window) +{ + if (window && window->isTopLevel() && window->screen()) { + return fromNativePixels(pixelRect, window->screen()); + } else { + const qreal scaleFactor = QHighDpiScaling::factor(window); + return QRect(pixelRect.topLeft() / scaleFactor, fromNative(pixelRect.size(), scaleFactor)); + } +} + +inline QRectF toNativePixels(const QRectF &pointRect, const QScreen *screen) +{ + const qreal scaleFactor = QHighDpiScaling::factor(screen); + const QPoint origin = QHighDpiScaling::origin(screen); + return QRectF(toNative(pointRect.topLeft(), scaleFactor, origin), + toNative(pointRect.size(), scaleFactor)); +} + +inline QRect toNativePixels(const QRect &pointRect, const QWindow *window) +{ + if (window && window->isTopLevel() && window->screen()) { + return toNativePixels(pointRect, window->screen()); + } else { + const qreal scaleFactor = QHighDpiScaling::factor(window); + return QRect(pointRect.topLeft() * scaleFactor, toNative(pointRect.size(), scaleFactor)); + } +} + +inline QRectF fromNativePixels(const QRectF &pixelRect, const QScreen *screen) +{ + const qreal scaleFactor = QHighDpiScaling::factor(screen); + const QPoint origin = QHighDpiScaling::origin(screen); + return QRectF(fromNative(pixelRect.topLeft(), scaleFactor, origin), + fromNative(pixelRect.size(), scaleFactor)); +} + +inline QRectF fromNativePixels(const QRectF &pixelRect, const QWindow *window) +{ + if (window && window->isTopLevel() && window->screen()) { + return fromNativePixels(pixelRect, window->screen()); + } else { + const qreal scaleFactor = QHighDpiScaling::factor(window); + return QRectF(pixelRect.topLeft() / scaleFactor, pixelRect.size() / scaleFactor); + } +} + +inline QRectF toNativePixels(const QRectF &pointRect, const QWindow *window) +{ + if (window && window->isTopLevel() && window->screen()) { + return toNativePixels(pointRect, window->screen()); + } else { + const qreal scaleFactor = QHighDpiScaling::factor(window); + return QRectF(pointRect.topLeft() * scaleFactor, pointRect.size() * scaleFactor); + } +} + +inline QSize fromNativePixels(const QSize &pixelSize, const QWindow *window) +{ + return pixelSize / QHighDpiScaling::factor(window); +} + +inline QSize toNativePixels(const QSize &pointSize, const QWindow *window) +{ + return pointSize * QHighDpiScaling::factor(window); +} + +inline QSizeF fromNativePixels(const QSizeF &pixelSize, const QWindow *window) +{ + return pixelSize / QHighDpiScaling::factor(window); +} + +inline QSizeF toNativePixels(const QSizeF &pointSize, const QWindow *window) +{ + return pointSize * QHighDpiScaling::factor(window); +} + +inline QPoint fromNativePixels(const QPoint &pixelPoint, const QScreen *screen) +{ + return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen)); +} + +inline QPoint fromNativePixels(const QPoint &pixelPoint, const QWindow *window) +{ + if (window && window->isTopLevel() && window->screen()) + return fromNativePixels(pixelPoint, window->screen()); + else + return pixelPoint / QHighDpiScaling::factor(window); +} + +inline QPoint toNativePixels(const QPoint &pointPoint, const QScreen *screen) +{ + return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen)); +} + +inline QPoint toNativePixels(const QPoint &pointPoint, const QWindow *window) +{ + if (window && window->isTopLevel() && window->screen()) + return toNativePixels(pointPoint, window->screen()); + else + return pointPoint * QHighDpiScaling::factor(window); +} + +inline QPointF fromNativePixels(const QPointF &pixelPoint, const QScreen *screen) +{ + return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen)); +} + +inline QPointF fromNativePixels(const QPointF &pixelPoint, const QWindow *window) +{ + if (window && window->isTopLevel() && window->screen()) + return fromNativePixels(pixelPoint, window->screen()); + else + return pixelPoint / QHighDpiScaling::factor(window); +} + +inline QPointF toNativePixels(const QPointF &pointPoint, const QScreen *screen) +{ + return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen)); +} + +inline QPointF toNativePixels(const QPointF &pointPoint, const QWindow *window) +{ + if (window && window->isTopLevel() && window->screen()) + return toNativePixels(pointPoint, window->screen()); + else + return pointPoint * QHighDpiScaling::factor(window); +} + +inline QMargins fromNativePixels(const QMargins &pixelMargins, const QWindow *window) +{ + const qreal scaleFactor = QHighDpiScaling::factor(window); + return QMargins(pixelMargins.left() / scaleFactor, pixelMargins.top() / scaleFactor, + pixelMargins.right() / scaleFactor, pixelMargins.bottom() / scaleFactor); +} + +inline QMargins toNativePixels(const QMargins &pointMargins, const QWindow *window) +{ + const qreal scaleFactor = QHighDpiScaling::factor(window); + return QMargins(pointMargins.left() * scaleFactor, pointMargins.top() * scaleFactor, + pointMargins.right() * scaleFactor, pointMargins.bottom() * scaleFactor); +} + +inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow *window) +{ + if (!QHighDpiScaling::isActive()) + return pixelRegion; + + qreal scaleFactor = QHighDpiScaling::factor(window); + QRegion pointRegion; + foreach (const QRect &rect, pixelRegion.rects()) { + pointRegion += QRect(fromNative(rect.topLeft(), scaleFactor), + fromNative(rect.size(), scaleFactor)); + } + return pointRegion; +} + +inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window) +{ + if (!QHighDpiScaling::isActive()) + return pointRegion; + + qreal scaleFactor = QHighDpiScaling::factor(window); + QRegion pixelRegon; + foreach (const QRect &rect, pointRegion.rects()) { + pixelRegon += QRect(toNative(rect.topLeft(), scaleFactor), + toNative(rect.size(), scaleFactor)); + } + return pixelRegon; +} + +// Any T that has operator/() +template <typename T> +T fromNativePixels(const T &pixelValue, const QWindow *window) +{ + if (!QHighDpiScaling::isActive()) + return pixelValue; + + return pixelValue / QHighDpiScaling::factor(window); + +} + + //##### ????? +template <typename T> +T fromNativePixels(const T &pixelValue, const QScreen *screen) +{ + if (!QHighDpiScaling::isActive()) + return pixelValue; + + return pixelValue / QHighDpiScaling::factor(screen); + +} + +// Any T that has operator*() +template <typename T> +T toNativePixels(const T &pointValue, const QWindow *window) +{ + if (!QHighDpiScaling::isActive()) + return pointValue; + + return pointValue * QHighDpiScaling::factor(window); +} + +template <typename T> +T toNativePixels(const T &pointValue, const QScreen *screen) +{ + if (!QHighDpiScaling::isActive()) + return pointValue; + + return pointValue * QHighDpiScaling::factor(screen); +} + + +// Any QVector<T> where T has operator/() +template <typename T> +QVector<T> fromNativePixels(const QVector<T> &pixelValues, const QWindow *window) +{ + if (!QHighDpiScaling::isActive()) + return pixelValues; + + QVector<T> pointValues; + foreach (const T& pixelValue, pixelValues) + pointValues.append(pixelValue / QHighDpiScaling::factor(window)); + return pointValues; +} + +// Any QVector<T> where T has operator*() +template <typename T> +QVector<T> toNativePixels(const QVector<T> &pointValues, const QWindow *window) +{ + if (!QHighDpiScaling::isActive()) + return pointValues; + + QVector<T> pixelValues; + foreach (const T& pointValue, pointValues) + pixelValues.append(pointValue * QHighDpiScaling::factor(window)); + return pixelValues; +} + +} // namespace QHighDpi + +QT_END_NAMESPACE + +#endif // QHIGHDPISCALING_P_H diff --git a/src/gui/kernel/qinputmethod.h b/src/gui/kernel/qinputmethod.h index 3e801bff3cddc2252321e9c5bd8838e60a15d68c..d7a7b1db8a1cec4f81dfdd4e94844f29de22dda0 100644 --- a/src/gui/kernel/qinputmethod.h +++ b/src/gui/kernel/qinputmethod.h @@ -82,7 +82,7 @@ public: QLocale locale() const; Qt::LayoutDirection inputDirection() const; - static QVariant queryFocusObject(Qt::InputMethodQuery query, QVariant argument); + static QVariant queryFocusObject(Qt::InputMethodQuery query, QVariant argument); // ### Qt 6: QVariant by const-ref public Q_SLOTS: void show(); diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index ab846b63cbabfeecd41b5c95c16753fabca5e0cc..ffa9b87147f476b399b0ea8766c60acd7758296d 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -194,7 +194,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni QKeySequence objects can be cast to a QString to obtain a human-readable translated version of the sequence. Similarly, the toString() function - produces human-readable strings for use in menus. On Mac OS X, the + produces human-readable strings for use in menus. On OS X, the appropriate symbols are used to describe keyboard shortcuts using special keys on the Macintosh keyboard. @@ -202,12 +202,12 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni code point of the character; for example, 'A' gives the same key sequence as Qt::Key_A. - \b{Note:} On Mac OS X, references to "Ctrl", Qt::CTRL, Qt::Control + \b{Note:} On OS X, references to "Ctrl", Qt::CTRL, Qt::Control and Qt::ControlModifier correspond to the \uicontrol Command keys on the Macintosh keyboard, and references to "Meta", Qt::META, Qt::Meta and Qt::MetaModifier correspond to the \uicontrol Control keys. Developers on - Mac OS X can use the same shortcut descriptions across all platforms, - and their applications will automatically work as expected on Mac OS X. + OS X can use the same shortcut descriptions across all platforms, + and their applications will automatically work as expected on OS X. \section1 Standard Shortcuts @@ -216,12 +216,12 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni setting up actions in a typical application. The table below shows some common key sequences that are often used for these standard shortcuts by applications on four widely-used platforms. Note - that on Mac OS X, the \uicontrol Ctrl value corresponds to the \uicontrol + that on OS X, the \uicontrol Ctrl value corresponds to the \uicontrol Command keys on the Macintosh keyboard, and the \uicontrol Meta value corresponds to the \uicontrol Control keys. \table - \header \li StandardKey \li Windows \li Mac OS X \li KDE \li GNOME + \header \li StandardKey \li Windows \li OS X \li KDE \li GNOME \row \li HelpContents \li F1 \li Ctrl+? \li F1 \li F1 \row \li WhatsThis \li Shift+F1 \li Shift+F1 \li Shift+F1 \li Shift+F1 \row \li Open \li Ctrl+O \li Ctrl+O \li Ctrl+O \li Ctrl+O @@ -819,6 +819,7 @@ QKeySequence::QKeySequence(const QString &key, QKeySequence::SequenceFormat form assign(key, format); } +Q_STATIC_ASSERT_X(QKeySequencePrivate::MaxKeyCount == 4, "Change docs and ctor impl below"); /*! Constructs a key sequence with up to 4 keys \a k1, \a k2, \a k3 and \a k4. @@ -877,26 +878,19 @@ QKeySequence::~QKeySequence() void QKeySequence::setKey(int key, int index) { - Q_ASSERT_X(index >= 0 && index < 4, "QKeySequence::setKey", "index out of range"); + Q_ASSERT_X(index >= 0 && index < QKeySequencePrivate::MaxKeyCount, "QKeySequence::setKey", "index out of range"); qAtomicDetach(d); d->key[index] = key; } +Q_STATIC_ASSERT_X(QKeySequencePrivate::MaxKeyCount == 4, "Change docs below"); /*! Returns the number of keys in the key sequence. The maximum is 4. */ int QKeySequence::count() const { - if (!d->key[0]) - return 0; - if (!d->key[1]) - return 1; - if (!d->key[2]) - return 2; - if (!d->key[3]) - return 3; - return 4; + return int(std::distance(d->key, std::find(d->key, d->key + QKeySequencePrivate::MaxKeyCount, 0))); } @@ -988,8 +982,8 @@ int QKeySequence::assign(const QString &ks, QKeySequence::SequenceFormat format) int p = 0, diff = 0; // Run through the whole string, but stop - // if we have 4 keys before the end. - while (keyseq.length() && n < 4) { + // if we have MaxKeyCount keys before the end. + while (keyseq.length() && n < QKeySequencePrivate::MaxKeyCount) { // We MUST use something to separate each sequence, and space // does not cut it, since some of the key names have space // in them.. (Let's hope no one translate with a comma in it:) @@ -1023,9 +1017,10 @@ struct QModifKeyName { int qt_key; QString name; }; +Q_DECLARE_TYPEINFO(QModifKeyName, Q_MOVABLE_TYPE); -Q_GLOBAL_STATIC(QList<QModifKeyName>, globalModifs) -Q_GLOBAL_STATIC(QList<QModifKeyName>, globalPortableModifs) +Q_GLOBAL_STATIC(QVector<QModifKeyName>, globalModifs) +Q_GLOBAL_STATIC(QVector<QModifKeyName>, globalPortableModifs) /*! Constructs a single key from the string \a str. @@ -1041,7 +1036,7 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence QString accel = str.toLower(); bool nativeText = (format == QKeySequence::NativeText); - QList<QModifKeyName> *gmodifs; + QVector<QModifKeyName> *gmodifs; if (nativeText) { gmodifs = globalModifs(); if (gmodifs->isEmpty()) { @@ -1077,7 +1072,7 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence if (!gmodifs) return ret; - QList<QModifKeyName> modifs; + QVector<QModifKeyName> modifs; if (nativeText) { modifs << QModifKeyName(Qt::CTRL, QCoreApplication::translate("QShortcut", "Ctrl").toLower().append(QLatin1Char('+'))) << QModifKeyName(Qt::SHIFT, QCoreApplication::translate("QShortcut", "Shift").toLower().append(QLatin1Char('+'))) @@ -1101,7 +1096,7 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence int i = 0; int lastI = 0; while ((i = sl.indexOf(QLatin1Char('+'), i + 1)) != -1) { - const QString sub = sl.mid(lastI, i - lastI + 1); + const QStringRef sub = sl.midRef(lastI, i - lastI + 1); // If we get here the shortcuts contains at least one '+'. We break up // along the following strategy: // Meta+Ctrl++ ( "Meta+", "Ctrl+", "+" ) @@ -1207,7 +1202,7 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat #if defined(Q_OS_MACX) if (nativeText) { - // On Mac OS X the order (by default) is Meta, Alt, Shift, Control. + // On OS X the order (by default) is Meta, Alt, Shift, Control. // If the AA_MacDontSwapCtrlAndMeta is enabled, then the order // is Ctrl, Alt, Shift, Meta. The macSymbolForQtKey does this swap // for us, which means that we have to adjust our order here. @@ -1367,7 +1362,7 @@ QKeySequence::operator QVariant() const */ int QKeySequence::operator[](uint index) const { - Q_ASSERT_X(index < 4, "QKeySequence::operator[]", "index out of range"); + Q_ASSERT_X(index < QKeySequencePrivate::MaxKeyCount, "QKeySequence::operator[]", "index out of range"); return d->key[index]; } @@ -1435,10 +1430,8 @@ uint qHash(const QKeySequence &key, uint seed) Q_DECL_NOTHROW */ bool QKeySequence::operator< (const QKeySequence &other) const { - for (int i = 0; i < 4; ++i) - if (d->key[i] != other.d->key[i]) - return d->key[i] < other.d->key[i]; - return false; + return std::lexicographical_compare(d->key, d->key + QKeySequencePrivate::MaxKeyCount, + other.d->key, other.d->key + QKeySequencePrivate::MaxKeyCount); } /*! @@ -1490,7 +1483,7 @@ bool QKeySequence::isDetached() const If the key sequence has no keys, an empty string is returned. - On Mac OS X, the string returned resembles the sequence that is + On OS X, the string returned resembles the sequence that is shown in the menu bar. \sa fromString() @@ -1534,6 +1527,7 @@ QList<QKeySequence> QKeySequence::listFromString(const QString &str, SequenceFor QList<QKeySequence> result; QStringList strings = str.split(QLatin1String("; ")); + result.reserve(strings.count()); foreach (const QString &string, strings) { result << fromString(string, format); } @@ -1576,15 +1570,14 @@ QString QKeySequence::listToString(const QList<QKeySequence> &list, SequenceForm */ QDataStream &operator<<(QDataStream &s, const QKeySequence &keysequence) { - QList<quint32> list; - list << keysequence.d->key[0]; - - if (s.version() >= 5 && keysequence.count() > 1) { - list << keysequence.d->key[1]; - list << keysequence.d->key[2]; - list << keysequence.d->key[3]; + Q_STATIC_ASSERT_X(QKeySequencePrivate::MaxKeyCount == 4, "Forgot to adapt QDataStream &operator<<(QDataStream &s, const QKeySequence &keysequence) to new QKeySequence::MaxKeyCount"); + const bool extended = s.version() >= 5 && keysequence.count() > 1; + s << quint32(extended ? 4 : 1) << quint32(keysequence.d->key[0]); + if (extended) { + s << quint32(keysequence.d->key[1]) + << quint32(keysequence.d->key[2]) + << quint32(keysequence.d->key[3]); } - s << list; return s; } @@ -1599,11 +1592,19 @@ QDataStream &operator<<(QDataStream &s, const QKeySequence &keysequence) */ QDataStream &operator>>(QDataStream &s, QKeySequence &keysequence) { + const quint32 MaxKeys = QKeySequencePrivate::MaxKeyCount; + quint32 c; + s >> c; + quint32 keys[MaxKeys] = {0}; + for (uint i = 0; i < qMin(c, MaxKeys); ++i) { + if (s.atEnd()) { + qWarning("Premature EOF while reading QKeySequence"); + return s; + } + s >> keys[i]; + } qAtomicDetach(keysequence.d); - QList<quint32> list; - s >> list; - for (int i = 0; i < 4; ++i) - keysequence.d->key[i] = list.value(i); + std::copy(keys, keys + MaxKeys, keysequence.d->key); return s; } diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h index e6616dae11b5afe68ce8dfc31d94f1628e752e3c..d6171c86f24a78a94d17983ab15649e0b8a74a34 100644 --- a/src/gui/kernel/qkeysequence.h +++ b/src/gui/kernel/qkeysequence.h @@ -180,10 +180,10 @@ public: int operator[](uint i) const; QKeySequence &operator=(const QKeySequence &other); #ifdef Q_COMPILER_RVALUE_REFS - inline QKeySequence &operator=(QKeySequence &&other) - { qSwap(d, other.d); return *this; } + QKeySequence &operator=(QKeySequence &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif - inline void swap(QKeySequence &other) { qSwap(d, other.d); } + void swap(QKeySequence &other) Q_DECL_NOTHROW { qSwap(d, other.d); } + bool operator==(const QKeySequence &other) const; inline bool operator!= (const QKeySequence &other) const { return !(*this == other); } diff --git a/src/gui/kernel/qkeysequence_p.h b/src/gui/kernel/qkeysequence_p.h index 97416943d08a0f0c834ac15d662cc020f05b0e58..3e4c5bae88a281b1555ce9e9db07a3cf7524976d 100644 --- a/src/gui/kernel/qkeysequence_p.h +++ b/src/gui/kernel/qkeysequence_p.h @@ -47,6 +47,8 @@ #include "qkeysequence.h" +#include <algorithm> + QT_BEGIN_NAMESPACE #ifndef QT_NO_SHORTCUT @@ -61,20 +63,17 @@ struct Q_AUTOTEST_EXPORT QKeyBinding class Q_AUTOTEST_EXPORT QKeySequencePrivate { public: - enum { MaxKeyCount = 4 }; // used in QKeySequenceEdit + enum { MaxKeyCount = 4 }; // also used in QKeySequenceEdit inline QKeySequencePrivate() : ref(1) { - key[0] = key[1] = key[2] = key[3] = 0; + std::fill_n(key, uint(MaxKeyCount), 0); } inline QKeySequencePrivate(const QKeySequencePrivate ©) : ref(1) { - key[0] = copy.key[0]; - key[1] = copy.key[1]; - key[2] = copy.key[2]; - key[3] = copy.key[3]; + std::copy(copy.key, copy.key + MaxKeyCount, key); } QAtomicInt ref; - int key[4]; + int key[MaxKeyCount]; static QString encodeString(int key, QKeySequence::SequenceFormat format); static int decodeString(const QString &keyStr, QKeySequence::SequenceFormat format); }; diff --git a/src/gui/kernel/qoffscreensurface.h b/src/gui/kernel/qoffscreensurface.h index 909a1ef256ebfbe33d44a56d026b52f1e399a56c..17bc8a7d1732137fa2c3751056144a99264ad8f0 100644 --- a/src/gui/kernel/qoffscreensurface.h +++ b/src/gui/kernel/qoffscreensurface.h @@ -51,7 +51,7 @@ class Q_GUI_EXPORT QOffscreenSurface : public QObject, public QSurface public: - explicit QOffscreenSurface(QScreen *screen = 0); + explicit QOffscreenSurface(QScreen *screen = Q_NULLPTR); virtual ~QOffscreenSurface(); SurfaceType surfaceType() const Q_DECL_OVERRIDE; diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 56a3729a4a53b732eb53314a5c5ee5b49b6467ab..9e5767658fb84d94f17369b3e6dc389986c501c5 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -226,7 +226,7 @@ public: QOpenGLContext *context; }; -static QThreadStorage<QGuiGLThreadContext *> qwindow_context_storage; +Q_GLOBAL_STATIC(QThreadStorage<QGuiGLThreadContext *>, qwindow_context_storage); static QOpenGLContext *global_share_context = 0; #ifndef QT_NO_DEBUG @@ -336,14 +336,14 @@ QOpenGLContext *qt_gl_global_share_context() */ QOpenGLContext *QOpenGLContextPrivate::setCurrentContext(QOpenGLContext *context) { - QGuiGLThreadContext *threadContext = qwindow_context_storage.localData(); + QGuiGLThreadContext *threadContext = qwindow_context_storage()->localData(); if (!threadContext) { if (!QThread::currentThread()) { qWarning("No QTLS available. currentContext won't work"); return 0; } threadContext = new QGuiGLThreadContext; - qwindow_context_storage.setLocalData(threadContext); + qwindow_context_storage()->setLocalData(threadContext); } QOpenGLContext *previous = threadContext->context; threadContext->context = context; @@ -412,8 +412,8 @@ int QOpenGLContextPrivate::maxTextureSize() */ QOpenGLContext* QOpenGLContext::currentContext() { - QGuiGLThreadContext *threadContext = qwindow_context_storage.localData(); - if(threadContext) { + QGuiGLThreadContext *threadContext = qwindow_context_storage()->localData(); + if (threadContext) { return threadContext->context; } return 0; @@ -718,6 +718,28 @@ QOpenGLFunctions *QOpenGLContext::functions() const return d->functions; } +/*! + Get the QOpenGLExtraFunctions instance for this context. + + QOpenGLContext offers this as a convenient way to access QOpenGLExtraFunctions + without having to manage it manually. + + The context or a sharing context must be current. + + The returned QOpenGLExtraFunctions instance is ready to be used and it + does not need initializeOpenGLFunctions() to be called. + + \note QOpenGLExtraFunctions contains functionality that is not guaranteed to + be available at runtime. Runtime availability depends on the platform, + graphics driver, and the OpenGL version requested by the application. + + \sa QOpenGLFunctions, QOpenGLExtraFunctions +*/ +QOpenGLExtraFunctions *QOpenGLContext::extraFunctions() const +{ + return static_cast<QOpenGLExtraFunctions *>(functions()); +} + /*! \fn T *QOpenGLContext::versionFunctions() const diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h index 89c24b66bf7874612b4224a00104ffe6d4bfd2aa..85e7abfa267390bcc76143a9317197f5605aa45b 100644 --- a/src/gui/kernel/qopenglcontext.h +++ b/src/gui/kernel/qopenglcontext.h @@ -66,6 +66,7 @@ QT_BEGIN_NAMESPACE class QOpenGLContextPrivate; class QOpenGLContextGroupPrivate; class QOpenGLFunctions; +class QOpenGLExtraFunctions; class QPlatformOpenGLContext; class QScreen; @@ -143,7 +144,7 @@ class Q_GUI_EXPORT QOpenGLContext : public QObject Q_OBJECT Q_DECLARE_PRIVATE(QOpenGLContext) public: - explicit QOpenGLContext(QObject *parent = 0); + explicit QOpenGLContext(QObject *parent = Q_NULLPTR); ~QOpenGLContext(); void setFormat(const QSurfaceFormat &format); @@ -177,6 +178,7 @@ public: QPlatformOpenGLContext *shareHandle() const; QOpenGLFunctions *functions() const; + QOpenGLExtraFunctions *extraFunctions() const; QAbstractOpenGLFunctions *versionFunctions(const QOpenGLVersionProfile &versionProfile = QOpenGLVersionProfile()) const; diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp index b2025faaf1cec0bc95c467abde50bdb56dc413d6..3a1126d318dea0571c032afb3ddc19986c29d9cc 100644 --- a/src/gui/kernel/qopenglwindow.cpp +++ b/src/gui/kernel/qopenglwindow.cpp @@ -664,15 +664,10 @@ int QOpenGLWindow::metric(PaintDeviceMetric metric) const if (d->paintDevice) return d->paintDevice->depth(); break; - case PdmDevicePixelRatio: - if (d->paintDevice) - return devicePixelRatio(); - break; default: break; } return QPaintDeviceWindow::metric(metric); - } /*! diff --git a/src/gui/kernel/qopenglwindow.h b/src/gui/kernel/qopenglwindow.h index f274275c3fa7f5a05027ddd3bd1cb774a32accd6..0c2b44c1c7094625ef259afff8faf12914fa2a02 100644 --- a/src/gui/kernel/qopenglwindow.h +++ b/src/gui/kernel/qopenglwindow.h @@ -58,8 +58,8 @@ public: PartialUpdateBlend }; - explicit QOpenGLWindow(UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = 0); - explicit QOpenGLWindow(QOpenGLContext *shareContext, UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = 0); + explicit QOpenGLWindow(UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = Q_NULLPTR); + explicit QOpenGLWindow(QOpenGLContext *shareContext, UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = Q_NULLPTR); ~QOpenGLWindow(); UpdateBehavior updateBehavior() const; diff --git a/src/gui/kernel/qpaintdevicewindow.cpp b/src/gui/kernel/qpaintdevicewindow.cpp index ff661d017d8bdc31eca9711ec52d4daaddad85c7..cd894866c37f199794d0a5cd3cea6fd0fc907bd0 100644 --- a/src/gui/kernel/qpaintdevicewindow.cpp +++ b/src/gui/kernel/qpaintdevicewindow.cpp @@ -155,8 +155,10 @@ int QPaintDeviceWindow::metric(PaintDeviceMetric metric) const return qRound(screen->physicalDotsPerInchY()); break; case PdmDevicePixelRatio: - if (screen) - return screen->devicePixelRatio(); + return int(QWindow::devicePixelRatio()); + break; + case PdmDevicePixelRatioScaled: + return int(QWindow::devicePixelRatio() * devicePixelRatioFScale()); break; default: break; diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp index cf17e1b5aa15ae9d43172c013c0a7a6d2fedf526..ae05245e2fa8f878809a57f564b8c8e307303ad3 100644 --- a/src/gui/kernel/qpalette.cpp +++ b/src/gui/kernel/qpalette.cpp @@ -382,7 +382,7 @@ static void qt_palette_from_color(QPalette &pal, const QColor &button) \warning Some styles do not use the palette for all drawing, for instance, if they make use of native theme engines. This is the - case for both the Windows XP, Windows Vista, and the Mac OS X + case for both the Windows XP, Windows Vista, and the OS X styles. \sa QApplication::setPalette(), QWidget::setPalette(), QColor diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp index 3d35c4dcba4a7700a1b4ac285e081bae96304050..25894fd504a9c7e41125eb38a1bcc7247da1a264 100644 --- a/src/gui/kernel/qplatformdialoghelper.cpp +++ b/src/gui/kernel/qplatformdialoghelper.cpp @@ -136,12 +136,6 @@ QVariant QPlatformDialogHelper::defaultStyleHint(QPlatformDialogHelper::StyleHi return QVariant(); } -void QPlatformDialogHelper::execModalForWindow(QWindow *parent) -{ - Q_UNUSED(parent); - exec(); -} - // Font dialog class QFontDialogOptionsPrivate : public QSharedData @@ -428,6 +422,7 @@ public: QUrl initialDirectory; QString initiallySelectedNameFilter; QList<QUrl> initiallySelectedFiles; + QStringList supportedSchemes; }; QFileDialogOptions::QFileDialogOptions() : d(new QFileDialogOptionsPrivate) @@ -619,6 +614,18 @@ void QFileDialogOptions::setInitiallySelectedFiles(const QList<QUrl> &files) d->initiallySelectedFiles = files; } +// Schemes supported by the application +void QFileDialogOptions::setSupportedSchemes(const QStringList &schemes) +{ + d->supportedSchemes = schemes; +} + +QStringList QFileDialogOptions::supportedSchemes() const +{ + return d->supportedSchemes; +} + +// Return true if the URL is supported by the filedialog implementation *and* by the application. bool QPlatformFileDialogHelper::isSupportedUrl(const QUrl &url) const { return url.isLocalFile(); diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h index 6d3a367e60316dbffc45a77f93ca719ae38cd5b7..ec88770862a964c270e331290dcda34221be5054 100644 --- a/src/gui/kernel/qplatformdialoghelper.h +++ b/src/gui/kernel/qplatformdialoghelper.h @@ -145,7 +145,6 @@ public: virtual QVariant styleHint(StyleHint hint) const; virtual void exec() = 0; - virtual void execModalForWindow(QWindow *parent); virtual bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) = 0; @@ -349,6 +348,9 @@ public: QList<QUrl> initiallySelectedFiles() const; void setInitiallySelectedFiles(const QList<QUrl> &); + void setSupportedSchemes(const QStringList &schemes); + QStringList supportedSchemes() const; + private: QSharedDataPointer<QFileDialogOptionsPrivate> d; }; diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index 4d973d47a5bd2f47d9928211977eda7f4a0c9463..e935907a62c5cef79262c1952ea7ad451f6113a7 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -39,7 +39,6 @@ #include <qpa/qplatformtheme.h> #include <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qpixmap_raster_p.h> -#include <qpa/qplatformscreen_p.h> #include <private/qdnd_p.h> #include <private/qsimpledrag_p.h> @@ -450,7 +449,7 @@ QList<int> QPlatformIntegration::possibleKeys(const QKeyEvent *) const void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary) { QScreen *screen = new QScreen(ps); - ps->d_func()->screen = screen; + if (isPrimary) { QGuiApplicationPrivate::screen_list.prepend(screen); } else { @@ -469,8 +468,9 @@ void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary) */ void QPlatformIntegration::destroyScreen(QPlatformScreen *screen) { - QGuiApplicationPrivate::screen_list.removeOne(screen->d_func()->screen); - delete screen->d_func()->screen; + QScreen *qScreen = screen->screen(); + QGuiApplicationPrivate::screen_list.removeOne(qScreen); + delete qScreen; delete screen; } diff --git a/src/gui/kernel/qplatformintegrationfactory.cpp b/src/gui/kernel/qplatformintegrationfactory.cpp index d58ac3a33f7716f362d46f154688e929fb714b8c..5a1fb3ca8391f54db731d583de7db7a328d535e7 100644 --- a/src/gui/kernel/qplatformintegrationfactory.cpp +++ b/src/gui/kernel/qplatformintegrationfactory.cpp @@ -72,6 +72,12 @@ QPlatformIntegration *QPlatformIntegrationFactory::create(const QString &platfor } if (QPlatformIntegration *ret = loadIntegration(loader(), platform, paramList, argc, argv)) return ret; +#else + Q_UNUSED(platform); + Q_UNUSED(paramList); + Q_UNUSED(argc); + Q_UNUSED(argv); + Q_UNUSED(platformPluginPath); #endif return 0; } @@ -102,6 +108,7 @@ QStringList QPlatformIntegrationFactory::keys(const QString &platformPluginPath) list.append(loader()->keyMap().values()); return list; #else + Q_UNUSED(platformPluginPath); return QStringList(); #endif } diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp index edf546799f4bc0007098eb9f7ad3583ce3b361a9..2fb53fe16bcbdc14362b983506b62d57c3fc14c6 100644 --- a/src/gui/kernel/qplatformscreen.cpp +++ b/src/gui/kernel/qplatformscreen.cpp @@ -40,6 +40,7 @@ #include <qpa/qplatformintegration.h> #include <QtGui/qscreen.h> #include <QtGui/qwindow.h> +#include <private/qhighdpiscaling_p.h> QT_BEGIN_NAMESPACE @@ -96,6 +97,23 @@ QWindow *QPlatformScreen::topLevelAt(const QPoint & pos) const return 0; } +/*! + Find the sibling screen corresponding to \a globalPos. + + Returns this screen if no suitable screen is found at the position. + */ +const QPlatformScreen *QPlatformScreen::screenForPosition(const QPoint &point) const +{ + if (!geometry().contains(point)) { + Q_FOREACH (const QPlatformScreen* screen, virtualSiblings()) { + if (screen->geometry().contains(point)) + return screen; + } + } + return this; +} + + /*! Returns a list of all the platform screens that are part of the same virtual desktop. @@ -156,17 +174,37 @@ QDpi QPlatformScreen::logicalDpi() const } /*! - Reimplement this function in subclass to return the device pixel - ratio for the screen. This is the ratio between physical pixels - and device-independent pixels. + Reimplement this function in subclass to return the device pixel ratio + for the screen. This is the ratio between physical pixels and the + device-independent pixels of the windowing system. The default + implementation returns 1.0. - \sa QPlatformWindow::devicePixelRatio(); + \sa QPlatformWindow::devicePixelRatio() + \sa QPlatformScreen::pixelDensity() */ qreal QPlatformScreen::devicePixelRatio() const { return 1.0; } +/*! + Reimplement this function in subclass to return the pixel density of the + screen. This is the scale factor needed to make a low-dpi application + usable on this screen. The default implementation returns 1.0. + + Returning something else than 1.0 from this function causes Qt to + apply the scale factor to the application's coordinate system. + This is different from devicePixelRatio, which reports a scale + factor already applied by the windowing system. A platform plugin + typically implements one (or none) of these two functions. + + \sa QPlatformWindow::devicePixelRatio() +*/ +qreal QPlatformScreen::pixelDensity() const +{ + return 1.0; +} + /*! Reimplement this function in subclass to return the vertical refresh rate of the screen, in Hz. @@ -290,8 +328,8 @@ void QPlatformScreen::resizeMaximizedWindows() // 'screen()' still has the old geometry info while 'this' has the new geometry info const QRect oldGeometry = screen()->geometry(); const QRect oldAvailableGeometry = screen()->availableGeometry(); - const QRect newGeometry = geometry(); - const QRect newAvailableGeometry = availableGeometry(); + const QRect newGeometry = deviceIndependentGeometry(); + const QRect newAvailableGeometry = QHighDpi::fromNative(availableGeometry(), QHighDpiScaling::factor(this), newGeometry.topLeft()); // make sure maximized and fullscreen windows are updated for (int i = 0; i < windows.size(); ++i) { @@ -393,6 +431,13 @@ QRect QPlatformScreen::mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation return rect; } +QRect QPlatformScreen::deviceIndependentGeometry() const +{ + qreal scaleFactor = QHighDpiScaling::factor(this); + QRect nativeGeometry = geometry(); + return QRect(nativeGeometry.topLeft(), QHighDpi::fromNative(nativeGeometry.size(), scaleFactor)); +} + /*! Returns a hint about this screen's subpixel layout structure. @@ -420,4 +465,22 @@ QPlatformScreen::SubpixelAntialiasingType QPlatformScreen::subpixelAntialiasingT return static_cast<QPlatformScreen::SubpixelAntialiasingType>(type); } +/*! + Returns the current power state. + + The default implementation always returns PowerStateOn. +*/ +QPlatformScreen::PowerState QPlatformScreen::powerState() const +{ + return PowerStateOn; +} + +/*! + Sets the power state for this screen. +*/ +void QPlatformScreen::setPowerState(PowerState state) +{ + Q_UNUSED(state); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformscreen.h b/src/gui/kernel/qplatformscreen.h index 551cb788c969d9c5b90fe661e3a66b5b7bbfe9ed..b32f9cf97c5f6cf02d886becc33ff220459f0526 100644 --- a/src/gui/kernel/qplatformscreen.h +++ b/src/gui/kernel/qplatformscreen.h @@ -82,6 +82,13 @@ public: Subpixel_VBGR }; + enum PowerState { + PowerStateOn, + PowerStateStandby, + PowerStateSuspend, + PowerStateOff + }; + QPlatformScreen(); virtual ~QPlatformScreen(); @@ -96,6 +103,7 @@ public: virtual QSizeF physicalSize() const; virtual QDpi logicalDpi() const; virtual qreal devicePixelRatio() const; + virtual qreal pixelDensity() const; virtual qreal refreshRate() const; @@ -105,6 +113,7 @@ public: virtual QWindow *topLevelAt(const QPoint &point) const; virtual QList<QPlatformScreen *> virtualSiblings() const; + const QPlatformScreen *screenForPosition(const QPoint &point) const; QScreen *screen() const; @@ -117,10 +126,16 @@ public: virtual QPlatformCursor *cursor() const; virtual SubpixelAntialiasingType subpixelAntialiasingTypeHint() const; + virtual PowerState powerState() const; + virtual void setPowerState(PowerState state); + static int angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b); static QTransform transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target); static QRect mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect); + // The platform screen's geometry in device independent coordinates + QRect deviceIndependentGeometry() const; + protected: void resizeMaximizedWindows(); @@ -129,7 +144,7 @@ protected: private: Q_DISABLE_COPY(QPlatformScreen) - friend class QPlatformIntegration; + friend class QScreenPrivate; }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformthemefactory.cpp b/src/gui/kernel/qplatformthemefactory.cpp index d4902ac163230dfb64e229efbeb09fad5e82e012..bcc37dad06982e5e882ed955bbc0c9b2443bca9b 100644 --- a/src/gui/kernel/qplatformthemefactory.cpp +++ b/src/gui/kernel/qplatformthemefactory.cpp @@ -63,6 +63,9 @@ QPlatformTheme *QPlatformThemeFactory::create(const QString& key, const QString } if (QPlatformTheme *ret = qLoadPlugin1<QPlatformTheme, QPlatformThemePlugin>(loader(), platform, paramList)) return ret; +#else + Q_UNUSED(key); + Q_UNUSED(platformPluginPath); #endif return 0; } @@ -93,6 +96,7 @@ QStringList QPlatformThemeFactory::keys(const QString &platformPluginPath) list += loader()->keyMap().values(); return list; #else + Q_UNUSED(platformPluginPath); return QStringList(); #endif } diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index 114fcf8062c6295b51169b5be98cb3071e42efc8..d10bd1e9ebe8e04feb596699b2b8f28e06f20137 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -39,8 +39,10 @@ #include <qpa/qwindowsysteminterface.h> #include <QtGui/qwindow.h> #include <QtGui/qscreen.h> +#include <private/qhighdpiscaling_p.h> #include <private/qwindow_p.h> + QT_BEGIN_NAMESPACE /*! @@ -481,13 +483,25 @@ QString QPlatformWindow::formatWindowTitle(const QString &title, const QString & QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) const { QPlatformScreen *currentScreen = screen(); - if (!parent() && currentScreen && !currentScreen->geometry().intersects(newGeometry)) { + QPlatformScreen *fallback = currentScreen; + QPoint center = newGeometry.center(); + if (!parent() && currentScreen && !currentScreen->geometry().contains(center)) { Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) { - if (screen->geometry().intersects(newGeometry)) + if (screen->geometry().contains(center)) return screen; + if (screen->geometry().intersects(newGeometry)) + fallback = screen; } } - return currentScreen; + return fallback; +} + +/*! + Returns a size with both dimensions bounded to [0, QWINDOWSIZE_MAX] +*/ +QSize QPlatformWindow::constrainWindowSize(const QSize &size) +{ + return size.expandedTo(QSize(0, 0)).boundedTo(QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX)); } /*! @@ -565,7 +579,7 @@ void QPlatformWindow::invalidateSurface() QRect QPlatformWindow::initialGeometry(const QWindow *w, const QRect &initialGeometry, int defaultWidth, int defaultHeight) { - QRect rect(initialGeometry); + QRect rect(QHighDpi::fromNativePixels(initialGeometry, w)); if (rect.width() == 0) { const int minWidth = w->minimumWidth(); rect.setWidth(minWidth > 0 ? minWidth : defaultWidth); @@ -593,7 +607,7 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w, } } } - return rect; + return QHighDpi::toNativePixels(rect, w); } /*! @@ -626,6 +640,69 @@ void QPlatformWindow::requestUpdate() wp->updateTimer = w->startTimer(timeout, Qt::PreciseTimer); } +/*! + Returns the QWindow minimum size. +*/ +QSize QPlatformWindow::windowMinimumSize() const +{ + return constrainWindowSize(QHighDpi::toNativePixels(window()->minimumSize(), window())); +} + +/*! + Returns the QWindow maximum size. +*/ +QSize QPlatformWindow::windowMaximumSize() const +{ + return constrainWindowSize(QHighDpi::toNativePixels(window()->maximumSize(), window())); +} + +/*! + Returns the QWindow base size. +*/ +QSize QPlatformWindow::windowBaseSize() const +{ + return QHighDpi::toNativePixels(window()->baseSize(), window()); +} + +/*! + Returns the QWindow size increment. +*/ +QSize QPlatformWindow::windowSizeIncrement() const +{ + QSize increment = window()->sizeIncrement(); + if (!QHighDpiScaling::isActive()) + return increment; + + // Normalize the increment. If not set the increment can be + // (-1, -1) or (0, 0). Make that (1, 1) which is scalable. + if (increment.isEmpty()) + increment = QSize(1, 1); + + return QHighDpi::toNativePixels(increment, window()); +} + +/*! + Returns the QWindow geometry. +*/ +QRect QPlatformWindow::windowGeometry() const +{ + return QHighDpi::toNativePixels(window()->geometry(), window()); +} + +/*! + Returns the closest acceptable geometry for a given geometry before + a resize/move event for platforms that support it, for example to + implement heightForWidth(). +*/ +QRectF QPlatformWindow::windowClosestAcceptableGeometry(const QRectF &nativeRect) const +{ + QWindow *qWindow = window(); + const QRectF rectF = QHighDpi::fromNativePixels(nativeRect, qWindow); + const QRectF correctedGeometryF = qt_window_private(qWindow)->closestAcceptableGeometry(rectF); + return !correctedGeometryF.isEmpty() && rectF != correctedGeometryF + ? QHighDpi::toNativePixels(correctedGeometryF, qWindow) : nativeRect; +} + /*! \class QPlatformWindow \since 4.8 diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index c7c1efdc58e5a4f0013e34cd93166608993441c5..692ae862db55b91d982d850c175db422eb06c124 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -130,9 +130,20 @@ public: const QRect &initialGeometry, int defaultWidth, int defaultHeight); virtual void requestUpdate(); + + // Window property accessors. Platform plugins should use these + // instead of accessing QWindow directly. + QSize windowMinimumSize() const; + QSize windowMaximumSize() const; + QSize windowBaseSize() const; + QSize windowSizeIncrement() const; + QRect windowGeometry() const; + QRectF windowClosestAcceptableGeometry(const QRectF &nativeRect) const; + protected: static QString formatWindowTitle(const QString &title, const QString &separator); QPlatformScreen *screenForGeometry(const QRect &newGeometry) const; + static QSize constrainWindowSize(const QSize &size); QScopedPointer<QPlatformWindowPrivate> d_ptr; private: diff --git a/src/gui/kernel/qrasterwindow.cpp b/src/gui/kernel/qrasterwindow.cpp index c04eb714202915d8fab6ad5dc42671c0bd7c1cd3..fc1739ca0e010e3912efd9497cc93014b3dcafd0 100644 --- a/src/gui/kernel/qrasterwindow.cpp +++ b/src/gui/kernel/qrasterwindow.cpp @@ -108,8 +108,6 @@ int QRasterWindow::metric(PaintDeviceMetric metric) const switch (metric) { case PdmDepth: return d->backingstore->paintDevice()->depth(); - case PdmDevicePixelRatio: - return d->backingstore->paintDevice()->devicePixelRatio(); default: break; } diff --git a/src/gui/kernel/qrasterwindow.h b/src/gui/kernel/qrasterwindow.h index 4912efad37916b33c6770e83a1b1c7ef2dbcd205..6db6baa8f59224981932377a83a8c8e61f54adc5 100644 --- a/src/gui/kernel/qrasterwindow.h +++ b/src/gui/kernel/qrasterwindow.h @@ -46,7 +46,7 @@ class Q_GUI_EXPORT QRasterWindow : public QPaintDeviceWindow Q_DECLARE_PRIVATE(QRasterWindow) public: - explicit QRasterWindow(QWindow *parent = 0); + explicit QRasterWindow(QWindow *parent = Q_NULLPTR); protected: int metric(PaintDeviceMetric metric) const Q_DECL_OVERRIDE; diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index 5785722918e206035b780417b79f5ddff14aaa0c..407b4ee9b638a6ced5755c1eb39433e6f2e52456 100644 --- a/src/gui/kernel/qscreen.cpp +++ b/src/gui/kernel/qscreen.cpp @@ -36,6 +36,7 @@ #include "qpixmap.h" #include "qguiapplication_p.h" #include <qpa/qplatformscreen.h> +#include <qpa/qplatformscreen_p.h> #include <QtCore/QDebug> #include <QtCore/private/qobject_p.h> @@ -63,8 +64,33 @@ QT_BEGIN_NAMESPACE */ QScreen::QScreen(QPlatformScreen *screen) - : QObject(*new QScreenPrivate(screen), 0) + : QObject(*new QScreenPrivate(), 0) { + Q_D(QScreen); + d->setPlatformScreen(screen); +} + +void QScreenPrivate::setPlatformScreen(QPlatformScreen *screen) +{ + Q_Q(QScreen); + platformScreen = screen; + platformScreen->d_func()->screen = q; + orientation = platformScreen->orientation(); + geometry = platformScreen->deviceIndependentGeometry(); + availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft()); + logicalDpi = platformScreen->logicalDpi(); + refreshRate = platformScreen->refreshRate(); + // safeguard ourselves against buggy platform behavior... + if (refreshRate < 1.0) + refreshRate = 60.0; + + updatePrimaryOrientation(); + + filteredOrientation = orientation; + if (filteredOrientation == Qt::PrimaryOrientation) + filteredOrientation = primaryOrientation; + + updateHighDpi(); } @@ -208,6 +234,8 @@ qreal QScreen::physicalDotsPerInch() const qreal QScreen::logicalDotsPerInchX() const { Q_D(const QScreen); + if (QHighDpiScaling::isActive()) + return QHighDpiScaling::logicalDpi().first; return d->logicalDpi.first; } @@ -222,6 +250,8 @@ qreal QScreen::logicalDotsPerInchX() const qreal QScreen::logicalDotsPerInchY() const { Q_D(const QScreen); + if (QHighDpiScaling::isActive()) + return QHighDpiScaling::logicalDpi().second; return d->logicalDpi.second; } @@ -240,7 +270,7 @@ qreal QScreen::logicalDotsPerInchY() const qreal QScreen::logicalDotsPerInch() const { Q_D(const QScreen); - QDpi dpi = d->logicalDpi; + QDpi dpi = QHighDpiScaling::isActive() ? QHighDpiScaling::logicalDpi() : d->logicalDpi; return (dpi.first + dpi.second) * qreal(0.5); } @@ -259,7 +289,7 @@ qreal QScreen::logicalDotsPerInch() const qreal QScreen::devicePixelRatio() const { Q_D(const QScreen); - return d->platformScreen->devicePixelRatio(); + return d->platformScreen->devicePixelRatio() * QHighDpiScaling::factor(this); } /*! @@ -329,6 +359,7 @@ QList<QScreen *> QScreen::virtualSiblings() const Q_D(const QScreen); QList<QPlatformScreen *> platformScreens = d->platformScreen->virtualSiblings(); QList<QScreen *> screens; + screens.reserve(platformScreens.count()); foreach (QPlatformScreen *platformScreen, platformScreens) screens << platformScreen->screen(); return screens; @@ -590,7 +621,7 @@ bool QScreen::isLandscape(Qt::ScreenOrientation o) const \fn void QScreen::orientationChanged(Qt::ScreenOrientation orientation) This signal is emitted when the orientation of the screen - changes. + changes with \a orientation as an argument. \sa orientation() */ @@ -599,7 +630,7 @@ bool QScreen::isLandscape(Qt::ScreenOrientation o) const \fn void QScreen::primaryOrientationChanged(Qt::ScreenOrientation orientation) This signal is emitted when the primary orientation of the screen - changes. + changes with \a orientation as an argument. \sa primaryOrientation() */ diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h index f60fafcf63b226885530904ede3945c1f1a6a038..a6018128e2171293b54b55fb3126547567900a11 100644 --- a/src/gui/kernel/qscreen.h +++ b/src/gui/kernel/qscreen.h @@ -154,6 +154,7 @@ private: friend class QGuiApplicationPrivate; friend class QPlatformIntegration; friend class QPlatformScreen; + friend class QHighDpiScaling; }; #ifndef QT_NO_DEBUG_STREAM diff --git a/src/gui/kernel/qscreen_p.h b/src/gui/kernel/qscreen_p.h index d341b71932e3ee8eb329c4e9b62a6cf24609bf36..4492eddd45cda4094d9d4b3ff614493d1cbccbb4 100644 --- a/src/gui/kernel/qscreen_p.h +++ b/src/gui/kernel/qscreen_p.h @@ -47,6 +47,7 @@ #include <QtGui/qscreen.h> #include <qpa/qplatformscreen.h> +#include "qhighdpiscaling_p.h" #include <QtCore/private/qobject_p.h> @@ -54,25 +55,19 @@ QT_BEGIN_NAMESPACE class QScreenPrivate : public QObjectPrivate { + Q_DECLARE_PUBLIC(QScreen) public: - QScreenPrivate(QPlatformScreen *screen) - : platformScreen(screen) + QScreenPrivate() + : platformScreen(0) , orientationUpdateMask(0) { - orientation = platformScreen->orientation(); - geometry = platformScreen->geometry(); - availableGeometry = platformScreen->availableGeometry(); - logicalDpi = platformScreen->logicalDpi(); - refreshRate = platformScreen->refreshRate(); - // safeguard ourselves against buggy platform behavior... - if (refreshRate < 1.0) - refreshRate = 60.0; - - updatePrimaryOrientation(); + } - filteredOrientation = orientation; - if (filteredOrientation == Qt::PrimaryOrientation) - filteredOrientation = primaryOrientation; + void setPlatformScreen(QPlatformScreen *screen); + void updateHighDpi() + { + geometry = platformScreen->deviceIndependentGeometry(); + availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft()); } void updatePrimaryOrientation(); diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp index b850f53014acecdbda7580067bc3eb7ea909171d..6e574d82e473472a13a7580210641ba57c1ce8ba 100644 --- a/src/gui/kernel/qsimpledrag.cpp +++ b/src/gui/kernel/qsimpledrag.cpp @@ -55,6 +55,7 @@ #include <private/qdnd_p.h> #include <private/qshapedpixmapdndwindow_p.h> +#include <private/qhighdpiscaling_p.h> QT_BEGIN_NAMESPACE @@ -106,6 +107,12 @@ void QBasicDrag::disableEventFilter() qApp->removeEventFilter(this); } + +static inline QPoint getNativeMousePos(QEvent *e, QObject *o) +{ + return QHighDpi::toNativePixels(static_cast<QMouseEvent *>(e)->globalPos(), qobject_cast<QWindow*>(o)); +} + bool QBasicDrag::eventFilter(QObject *o, QEvent *e) { Q_UNUSED(o); @@ -139,19 +146,21 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e) } case QEvent::MouseMove: - move(static_cast<QMouseEvent *>(e)); + { + QPoint nativePosition = getNativeMousePos(e, o); + move(nativePosition); return true; // Eat all mouse events - + } case QEvent::MouseButtonRelease: disableEventFilter(); if (canDrop()) { - drop(static_cast<QMouseEvent *>(e)); + QPoint nativePosition = getNativeMousePos(e, o); + drop(nativePosition); } else { cancel(); } exitDndEventLoop(); return true; // Eat all mouse events - case QEvent::MouseButtonPress: case QEvent::MouseButtonDblClick: case QEvent::Wheel: @@ -227,13 +236,18 @@ void QBasicDrag::cancel() m_drag_icon_window->setVisible(false); } -void QBasicDrag::move(const QMouseEvent *e) +/*! + Move the drag label to \a globalPos, which is + interpreted in device independent coordinates. Typically called from reimplementations of move(). + */ + +void QBasicDrag::moveShapedPixmapWindow(const QPoint &globalPos) { if (m_drag) - m_drag_icon_window->updateGeometry(e->globalPos()); + m_drag_icon_window->updateGeometry(globalPos); } -void QBasicDrag::drop(const QMouseEvent *) +void QBasicDrag::drop(const QPoint &) { disableEventFilter(); restoreCursor(); @@ -330,14 +344,15 @@ void QSimpleDrag::cancel() } } -void QSimpleDrag::move(const QMouseEvent *me) +void QSimpleDrag::move(const QPoint &globalPos) { - QBasicDrag::move(me); - QWindow *window = topLevelAt(me->globalPos()); + //### not high-DPI aware + moveShapedPixmapWindow(globalPos); + QWindow *window = topLevelAt(globalPos); if (!window) return; - const QPoint pos = me->globalPos() - window->geometry().topLeft(); + const QPoint pos = globalPos - window->geometry().topLeft(); const QPlatformDragQtResponse qt_response = QWindowSystemInterface::handleDrag(window, drag()->mimeData(), pos, drag()->supportedActions()); @@ -345,14 +360,16 @@ void QSimpleDrag::move(const QMouseEvent *me) setCanDrop(qt_response.isAccepted()); } -void QSimpleDrag::drop(const QMouseEvent *me) +void QSimpleDrag::drop(const QPoint &globalPos) { - QBasicDrag::drop(me); - QWindow *window = topLevelAt(me->globalPos()); + //### not high-DPI aware + + QBasicDrag::drop(globalPos); + QWindow *window = topLevelAt(globalPos); if (!window) return; - const QPoint pos = me->globalPos() - window->geometry().topLeft(); + const QPoint pos = globalPos - window->geometry().topLeft(); const QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(window, drag()->mimeData(),pos, drag()->supportedActions()); if (response.isAccepted()) { diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h index 7812f8b863870e9228873d2a0d0aa887ef35bbc6..a0114753811a8234d0dfb01f977f7e454e95dc6d 100644 --- a/src/gui/kernel/qsimpledrag_p.h +++ b/src/gui/kernel/qsimpledrag_p.h @@ -73,10 +73,12 @@ protected: virtual void startDrag(); virtual void cancel(); - virtual void move(const QMouseEvent *me); - virtual void drop(const QMouseEvent *me); + virtual void move(const QPoint &globalPos) = 0; + virtual void drop(const QPoint &globalPos) = 0; virtual void endDrag(); + + void moveShapedPixmapWindow(const QPoint &deviceIndependentPosition); QShapedPixmapWindow *shapedPixmapWindow() const { return m_drag_icon_window; } void updateCursor(Qt::DropAction action); @@ -111,8 +113,8 @@ public: protected: virtual void startDrag() Q_DECL_OVERRIDE; virtual void cancel() Q_DECL_OVERRIDE; - virtual void move(const QMouseEvent *me) Q_DECL_OVERRIDE; - virtual void drop(const QMouseEvent *me) Q_DECL_OVERRIDE; + virtual void move(const QPoint &globalPos) Q_DECL_OVERRIDE; + virtual void drop(const QPoint &globalPos) Q_DECL_OVERRIDE; private: QWindow *m_current_window; diff --git a/src/gui/kernel/qtouchdevice.cpp b/src/gui/kernel/qtouchdevice.cpp index 1a6e9deba8ef689db4afecba1768b7a3a7c836a2..9d19fa4b9273003f0c5789e7a32820c12d23f439 100644 --- a/src/gui/kernel/qtouchdevice.cpp +++ b/src/gui/kernel/qtouchdevice.cpp @@ -195,7 +195,7 @@ void QTouchDevice::setName(const QString &name) d->name = name; } -typedef QList<QTouchDevice *> TouchDevices; +typedef QList<const QTouchDevice *> TouchDevices; Q_GLOBAL_STATIC(TouchDevices, deviceList) static QBasicMutex devicesMutex; @@ -214,26 +214,22 @@ static void cleanupDevicesList() QList<const QTouchDevice *> QTouchDevice::devices() { QMutexLocker lock(&devicesMutex); - QList<QTouchDevice *> *devList = deviceList(); - QList<const QTouchDevice *> constDevList; - for (int i = 0, count = devList->count(); i != count; ++i) - constDevList.append(devList->at(i)); - return constDevList; + return *deviceList(); } /*! \internal */ -bool QTouchDevicePrivate::isRegistered(QTouchDevice *dev) +bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev) { - QMutexLocker lock(&devicesMutex); + QMutexLocker locker(&devicesMutex); return deviceList()->contains(dev); } /*! \internal */ -void QTouchDevicePrivate::registerDevice(QTouchDevice *dev) +void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev) { QMutexLocker lock(&devicesMutex); if (deviceList()->isEmpty()) diff --git a/src/gui/kernel/qtouchdevice_p.h b/src/gui/kernel/qtouchdevice_p.h index 9c0bcf3414e4e978a06e05ecab4f402dd0283d22..4aff8f2f33bb72de5b6d9b51e12c6da9b8821176 100644 --- a/src/gui/kernel/qtouchdevice_p.h +++ b/src/gui/kernel/qtouchdevice_p.h @@ -45,7 +45,6 @@ // We mean it. // -#include <QtCore/qobject.h> #include <QtGui/qtouchdevice.h> QT_BEGIN_NAMESPACE @@ -65,8 +64,8 @@ public: QString name; int maxTouchPoints; - static void registerDevice(QTouchDevice *dev); - static bool isRegistered(QTouchDevice *dev); + static void registerDevice(const QTouchDevice *dev); + static bool isRegistered(const QTouchDevice *dev); }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index e697efe31ca8d2580a6185560315cc1a3bb6029b..e93e964c6bc9f8916f380c973c0aaa47615fef03 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -47,6 +47,7 @@ #ifndef QT_NO_ACCESSIBILITY # include "qaccessible.h" #endif +#include "qhighdpiscaling_p.h" #include <private/qevent_p.h> @@ -1085,13 +1086,13 @@ qreal QWindow::devicePixelRatio() const { Q_D(const QWindow); - // If there is no platform window, do the second best thing and - // return the app global devicePixelRatio. This is the highest - // devicePixelRatio found on the system screens, and will be - // correct for single-display systems (a very common case). + // If there is no platform window use the app global devicePixelRatio, + // which is the the highest devicePixelRatio found on the system + // screens, and will be correct for single-display systems (a very common case). if (!d->platformWindow) return qApp->devicePixelRatio(); - return d->platformWindow->devicePixelRatio(); + + return d->platformWindow->devicePixelRatio() * QHighDpiScaling::factor(this); } /*! @@ -1431,7 +1432,13 @@ void QWindow::setGeometry(const QRect &rect) d->positionPolicy = QWindowPrivate::WindowFrameExclusive; if (d->platformWindow) { - d->platformWindow->setGeometry(rect); + QRect nativeRect; + QScreen *newScreen = d->screenForGeometry(rect); + if (newScreen && isTopLevel()) + nativeRect = QHighDpi::toNativePixels(rect, newScreen); + else + nativeRect = QHighDpi::toNativePixels(rect, this); + d->platformWindow->setGeometry(nativeRect); } else { d->geometry = rect; @@ -1446,6 +1453,30 @@ void QWindow::setGeometry(const QRect &rect) } } +/* + This is equivalent to QPlatformWindow::screenForGeometry, but in platform + independent coordinates. The duplication is unfortunate, but there is a + chicken and egg problem here: we cannot convert to native coordinates + before we know which screen we are on. +*/ +QScreen *QWindowPrivate::screenForGeometry(const QRect &newGeometry) +{ + Q_Q(QWindow); + QScreen *currentScreen = q->screen(); + QScreen *fallback = currentScreen; + QPoint center = newGeometry.center(); + if (!q->parent() && currentScreen && !currentScreen->geometry().contains(center)) { + Q_FOREACH (QScreen* screen, currentScreen->virtualSiblings()) { + if (screen->geometry().contains(center)) + return screen; + if (screen->geometry().intersects(newGeometry)) + fallback = screen; + } + } + return fallback; +} + + /*! Returns the geometry of the window, excluding its window frame. @@ -1455,7 +1486,7 @@ QRect QWindow::geometry() const { Q_D(const QWindow); if (d->platformWindow) - return d->platformWindow->geometry(); + return QHighDpi::fromNativePixels(d->platformWindow->geometry(), this); return d->geometry; } @@ -1468,7 +1499,7 @@ QMargins QWindow::frameMargins() const { Q_D(const QWindow); if (d->platformWindow) - return d->platformWindow->frameMargins(); + return QHighDpi::fromNativePixels(d->platformWindow->frameMargins(), this); return QMargins(); } @@ -1482,7 +1513,7 @@ QRect QWindow::frameGeometry() const Q_D(const QWindow); if (d->platformWindow) { QMargins m = frameMargins(); - return d->platformWindow->geometry().adjusted(-m.left(), -m.top(), m.right(), m.bottom()); + return QHighDpi::fromNativePixels(d->platformWindow->geometry(), this).adjusted(-m.left(), -m.top(), m.right(), m.bottom()); } return d->geometry; } @@ -1499,7 +1530,7 @@ QPoint QWindow::framePosition() const Q_D(const QWindow); if (d->platformWindow) { QMargins margins = frameMargins(); - return d->platformWindow->geometry().topLeft() - QPoint(margins.left(), margins.top()); + return QHighDpi::fromNativePixels(d->platformWindow->geometry().topLeft(), this) - QPoint(margins.left(), margins.top()); } return d->geometry.topLeft(); } @@ -1515,7 +1546,7 @@ void QWindow::setFramePosition(const QPoint &point) d->positionPolicy = QWindowPrivate::WindowFrameInclusive; d->positionAutomatic = false; if (d->platformWindow) { - d->platformWindow->setGeometry(QRect(point, size())); + d->platformWindow->setGeometry(QHighDpi::toNativePixels(QRect(point, size()), this)); } else { d->geometry.moveTopLeft(point); } @@ -1575,7 +1606,7 @@ void QWindow::resize(const QSize &newSize) { Q_D(QWindow); if (d->platformWindow) { - d->platformWindow->setGeometry(QRect(position(), newSize)); + d->platformWindow->setGeometry(QHighDpi::toNativePixels(QRect(position(), newSize), this)); } else { const QSize oldSize = d->geometry.size(); d->geometry.setSize(newSize); @@ -2100,6 +2131,8 @@ void QWindowPrivate::deliverUpdateRequest() be handled by the base class. For example, the default implementation of this function relies on QEvent::Timer events. Filtering them away would therefore break the delivery of the update events. + + \since 5.5 */ void QWindow::requestUpdate() { diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h index 67585ce96340e510b1b7855e0f2a93df71073588..b29e7aaae7e26ba62d700db35227d5afab430335 100644 --- a/src/gui/kernel/qwindow.h +++ b/src/gui/kernel/qwindow.h @@ -125,7 +125,7 @@ public: }; Q_ENUM(Visibility) - explicit QWindow(QScreen *screen = 0); + explicit QWindow(QScreen *screen = Q_NULLPTR); explicit QWindow(QWindow *parent); virtual ~QWindow(); @@ -360,12 +360,12 @@ private: #ifndef Q_QDOC template <> inline QWindow *qobject_cast<QWindow*>(QObject *o) { - if (!o || !o->isWindowType()) return 0; + if (!o || !o->isWindowType()) return Q_NULLPTR; return static_cast<QWindow*>(o); } template <> inline const QWindow *qobject_cast<const QWindow*>(const QObject *o) { - if (!o || !o->isWindowType()) return 0; + if (!o || !o->isWindowType()) return Q_NULLPTR; return static_cast<const QWindow*>(o); } #endif // !Q_QDOC diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index 4fc63acf28f16ba1c41f2f0194c45ee335039217..23a6d800c01d3e2152cd75b4b22563f157816fca 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -136,6 +136,7 @@ public: void connectToScreen(QScreen *topLevelScreen); void disconnectFromScreen(); void emitScreenChangedRecursion(QScreen *newScreen); + QScreen *screenForGeometry(const QRect &rect); virtual void clearFocusObject(); virtual QRectF closestAcceptableGeometry(const QRectF &rect) const; diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index c20ea3bbffedd6dce65fdfbe04c123781387a981..9f6d9696bead047756ac18a31b5d4abb10fbc393 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -40,6 +40,7 @@ #include <qpa/qplatformdrag.h> #include <qpa/qplatformintegration.h> #include <qdebug.h> +#include "qhighdpiscaling_p.h" QT_BEGIN_NAMESPACE @@ -140,7 +141,7 @@ void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState */ void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &newRect, const QRect &oldRect) { - QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw,newRect, oldRect); + QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw, QHighDpi::fromNativePixels(newRect, tlw), QHighDpi::fromNativePixels(oldRect, tlw)); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -169,7 +170,7 @@ void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { QWindowSystemInterfacePrivate::MouseEvent * e = - new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, local, global, b, mods, source); + new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -186,7 +187,7 @@ void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timest QWindowSystemInterfacePrivate::MouseEvent * e = new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, QWindowSystemInterfacePrivate::FrameStrutMouse, - local, global, b, mods, source); + QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -367,14 +368,14 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con // Simple case: vertical deltas only: if (angleDelta.y() != 0 && angleDelta.x() == 0) { - e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source); + e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); return; } // Simple case: horizontal deltas only: if (angleDelta.y() == 0 && angleDelta.x() != 0) { - e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source); + e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); return; } @@ -382,12 +383,12 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con // Both horizontal and vertical deltas: Send two wheel events. // The first event contains the Qt 5 pixel and angle delta as points, // and in addition the Qt 4 compatibility vertical angle delta. - e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source); + e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); // The second event contains null pixel and angle points and the // Qt 4 compatibility horizontal angle delta. - e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source); + e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -467,12 +468,16 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *w, QTouchDevice *device, handleTouchEvent(w, time, device, points, mods); } -QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type) +QList<QTouchEvent::TouchPoint> + QWindowSystemInterfacePrivate::fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, + const QWindow *window, + QEvent::Type *type) { QList<QTouchEvent::TouchPoint> touchPoints; Qt::TouchPointStates states; QTouchEvent::TouchPoint p; + touchPoints.reserve(points.count()); QList<QWindowSystemInterface::TouchPoint>::const_iterator point = points.constBegin(); QList<QWindowSystemInterface::TouchPoint>::const_iterator end = points.constEnd(); while (point != end) { @@ -482,16 +487,16 @@ QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints p.setState(point->state); const QPointF screenPos = point->area.center(); - p.setScreenPos(screenPos); - p.setScreenRect(point->area); + p.setScreenPos(QHighDpi::fromNativePixels(screenPos, window)); + p.setScreenRect(QHighDpi::fromNativePixels(point->area, window)); // The local pos and rect are not set, they will be calculated // when the event gets processed by QGuiApplication. - p.setNormalizedPos(point->normalPosition); - p.setVelocity(point->velocity); + p.setNormalizedPos(QHighDpi::fromNativePixels(point->normalPosition, window)); + p.setVelocity(QHighDpi::fromNativePixels(point->velocity, window)); p.setFlags(point->flags); - p.setRawScreenPositions(point->rawPositions); + p.setRawScreenPositions(QHighDpi::fromNativePixels(point->rawPositions, window)); touchPoints.append(p); ++point; @@ -509,6 +514,27 @@ QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints return touchPoints; } +QList<QWindowSystemInterface::TouchPoint> + QWindowSystemInterfacePrivate::toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList, + const QWindow *window) +{ + QList<QWindowSystemInterface::TouchPoint> newList; + newList.reserve(pointList.size()); + foreach (const QTouchEvent::TouchPoint &pt, pointList) { + QWindowSystemInterface::TouchPoint p; + p.id = pt.id(); + p.flags = pt.flags(); + p.normalPosition = QHighDpi::toNativeLocalPosition(pt.normalizedPos(), window); + p.area = QHighDpi::toNativePixels(pt.screenRect(), window); + p.pressure = pt.pressure(); + p.state = pt.state(); + p.velocity = pt.velocity(); + p.rawPositions = pt.rawScreenPositions(); + newList.append(p); + } + return newList; +} + void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTouchDevice *device, const QList<TouchPoint> &points, Qt::KeyboardModifiers mods) { @@ -519,7 +545,7 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTo return; QEvent::Type type; - QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type); + QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, tlw, &type); QWindowSystemInterfacePrivate::TouchEvent *e = new QWindowSystemInterfacePrivate::TouchEvent(tlw, timestamp, type, device, touchPoints, mods); @@ -552,14 +578,14 @@ void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt:: void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const QRect &geometry, const QRect &availableGeometry) { QWindowSystemInterfacePrivate::ScreenGeometryEvent *e = - new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, geometry, availableGeometry); + new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, QHighDpi::fromNativeScreenGeometry(geometry, screen), QHighDpi::fromNative(availableGeometry, screen, geometry.topLeft())); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } void QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal dpiX, qreal dpiY) { QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e = - new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, dpiX, dpiY); + new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, dpiX, dpiY); // ### tja QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -578,7 +604,7 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw) void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion ®ion) { - QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, region); + QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalRegion(region, tlw)); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -670,12 +696,12 @@ int QWindowSystemInterface::windowSystemEventsQueued() #ifndef QT_NO_DRAGANDDROP QPlatformDragQtResponse QWindowSystemInterface::handleDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions) { - return QGuiApplicationPrivate::processDrag(w, dropData, p,supportedActions); + return QGuiApplicationPrivate::processDrag(w, dropData, QHighDpi::fromNativeLocalPosition(p, w) ,supportedActions); } QPlatformDropQtResponse QWindowSystemInterface::handleDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions) { - return QGuiApplicationPrivate::processDrop(w, dropData, p,supportedActions); + return QGuiApplicationPrivate::processDrop(w, dropData, QHighDpi::fromNativeLocalPosition(p, w),supportedActions); } #endif // QT_NO_DRAGANDDROP @@ -709,8 +735,11 @@ void QWindowSystemInterface::handleTabletEvent(QWindow *w, ulong timestamp, cons Qt::KeyboardModifiers modifiers) { QWindowSystemInterfacePrivate::TabletEvent *e = - new QWindowSystemInterfacePrivate::TabletEvent(w, timestamp, local, global, device, pointerType, buttons, pressure, - xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers); + new QWindowSystemInterfacePrivate::TabletEvent(w,timestamp, + QHighDpi::fromNativeLocalPosition(local, w), + QHighDpi::fromNativePixels(global, w), + device, pointerType, buttons, pressure, + xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -862,7 +891,6 @@ Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int return QWindowSystemInterface::tryHandleShortcutEventToObject(o, timestamp, k, mods, text, autorep, count); } - Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device, const QList<QTouchEvent::TouchPoint> &points, Qt::KeyboardModifiers mods = Qt::NoModifier) @@ -907,4 +935,5 @@ bool QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowS return true; } + QT_END_NAMESPACE diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 93cfbb742deae36516b9f348ef9167cf67e406e6..2435b0ad396cc8c4574c930be353f5a616af95e1 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -491,7 +491,12 @@ public: static QMutex flushEventMutex; static bool eventAccepted; - static QList<QTouchEvent::TouchPoint> convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type); + static QList<QTouchEvent::TouchPoint> + fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, + const QWindow *window, QEvent::Type *type = Q_NULLPTR); + static QList<QWindowSystemInterface::TouchPoint> + toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList, + const QWindow *window); static void installWindowSystemEventHandler(QWindowSystemEventHandler *handler); static void removeWindowSystemEventhandler(QWindowSystemEventHandler *handler); diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h index 6f6ff235cf272cf666d3a9b3470e85712fe3b741..cd5686be94c845e6312365e4b03be9b42ad6040f 100644 --- a/src/gui/math3d/qmatrix4x4.h +++ b/src/gui/math3d/qmatrix4x4.h @@ -86,7 +86,7 @@ public: inline void fill(float value); double determinant() const; - QMatrix4x4 inverted(bool *invertible = 0) const; + QMatrix4x4 inverted(bool *invertible = Q_NULLPTR) const; QMatrix4x4 transposed() const; QMatrix3x3 normalMatrix() const; diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index 5b0006ac567ec587dcf71e7793a22c241236383c..3716220a6025263089b45c02360aebe506116e01 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -164,12 +164,12 @@ inline QQuaternion::QQuaternion(float aScalar, float xpos, float ypos, float zpo inline bool QQuaternion::isNull() const { - return xp == 0.0f && yp == 0.0f && zp == 0.0f && wp == 0.0f; + return wp == 0.0f && xp == 0.0f && yp == 0.0f && zp == 0.0f; } inline bool QQuaternion::isIdentity() const { - return xp == 0.0f && yp == 0.0f && zp == 0.0f && wp == 1.0f; + return wp == 1.0f && xp == 0.0f && yp == 0.0f && zp == 0.0f; } inline float QQuaternion::x() const { return xp; } @@ -184,16 +184,16 @@ inline void QQuaternion::setScalar(float aScalar) { wp = aScalar; } Q_DECL_CONSTEXPR inline float QQuaternion::dotProduct(const QQuaternion &q1, const QQuaternion &q2) { - return q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp; + return q1.wp * q2.wp + q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp; } inline QQuaternion QQuaternion::inverted() const { // Need some extra precision if the length is very small. - double len = double(xp) * double(xp) + + double len = double(wp) * double(wp) + + double(xp) * double(xp) + double(yp) * double(yp) + - double(zp) * double(zp) + - double(wp) * double(wp); + double(zp) * double(zp); if (!qFuzzyIsNull(len)) return QQuaternion(wp / len, -xp / len, -yp / len, -zp / len); return QQuaternion(0.0f, 0.0f, 0.0f, 0.0f); @@ -213,28 +213,28 @@ inline QQuaternion QQuaternion::conjugate() const inline QQuaternion &QQuaternion::operator+=(const QQuaternion &quaternion) { + wp += quaternion.wp; xp += quaternion.xp; yp += quaternion.yp; zp += quaternion.zp; - wp += quaternion.wp; return *this; } inline QQuaternion &QQuaternion::operator-=(const QQuaternion &quaternion) { + wp -= quaternion.wp; xp -= quaternion.xp; yp -= quaternion.yp; zp -= quaternion.zp; - wp -= quaternion.wp; return *this; } inline QQuaternion &QQuaternion::operator*=(float factor) { + wp *= factor; xp *= factor; yp *= factor; zp *= factor; - wp *= factor; return *this; } @@ -262,16 +262,16 @@ inline QQuaternion &QQuaternion::operator*=(const QQuaternion &quaternion) inline QQuaternion &QQuaternion::operator/=(float divisor) { + wp /= divisor; xp /= divisor; yp /= divisor; zp /= divisor; - wp /= divisor; return *this; } inline bool operator==(const QQuaternion &q1, const QQuaternion &q2) { - return q1.xp == q2.xp && q1.yp == q2.yp && q1.zp == q2.zp && q1.wp == q2.wp; + return q1.wp == q2.wp && q1.xp == q2.xp && q1.yp == q2.yp && q1.zp == q2.zp; } inline bool operator!=(const QQuaternion &q1, const QQuaternion &q2) @@ -311,10 +311,10 @@ inline const QQuaternion operator/(const QQuaternion &quaternion, float divisor) inline bool qFuzzyCompare(const QQuaternion& q1, const QQuaternion& q2) { - return qFuzzyCompare(q1.xp, q2.xp) && + return qFuzzyCompare(q1.wp, q2.wp) && + qFuzzyCompare(q1.xp, q2.xp) && qFuzzyCompare(q1.yp, q2.yp) && - qFuzzyCompare(q1.zp, q2.zp) && - qFuzzyCompare(q1.wp, q2.wp); + qFuzzyCompare(q1.zp, q2.zp); } #ifndef QT_NO_VECTOR3D diff --git a/src/gui/math3d/qvector2d.h b/src/gui/math3d/qvector2d.h index 137142f381860d5130b2a8011cbefac016ac99b7..c4e62710d9a98fae71552488f021af1a1e9b2d59 100644 --- a/src/gui/math3d/qvector2d.h +++ b/src/gui/math3d/qvector2d.h @@ -122,7 +122,7 @@ private: friend class QVector4D; }; -Q_DECLARE_TYPEINFO(QVector2D, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(QVector2D, Q_PRIMITIVE_TYPE); Q_DECL_CONSTEXPR inline QVector2D::QVector2D() : xp(0.0f), yp(0.0f) {} diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h index 5be637e0c5850671ac62b2b325ed3d3152abbfa1..b62d33da71e51f46df241bf5ab7ac5bb5b2f5eb1 100644 --- a/src/gui/math3d/qvector3d.h +++ b/src/gui/math3d/qvector3d.h @@ -141,7 +141,7 @@ private: #endif }; -Q_DECLARE_TYPEINFO(QVector3D, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(QVector3D, Q_PRIMITIVE_TYPE); Q_DECL_CONSTEXPR inline QVector3D::QVector3D() : xp(0.0f), yp(0.0f), zp(0.0f) {} diff --git a/src/gui/math3d/qvector4d.h b/src/gui/math3d/qvector4d.h index 72db8ac75484ab7a3871dff39bb34d3dd8008db3..0543f0fbe3932c775386494ff7fbdc4724ec7575 100644 --- a/src/gui/math3d/qvector4d.h +++ b/src/gui/math3d/qvector4d.h @@ -131,7 +131,7 @@ private: #endif }; -Q_DECLARE_TYPEINFO(QVector4D, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(QVector4D, Q_PRIMITIVE_TYPE); Q_DECL_CONSTEXPR inline QVector4D::QVector4D() : xp(0.0f), yp(0.0f), zp(0.0f), wp(0.0f) {} diff --git a/src/gui/opengl/opengl.pri b/src/gui/opengl/opengl.pri index 8659bd6deac6dd9382ae4ca62d54df4469da9e18..b13f258fda83218c0aa6d9a5e0269c08f0e4b3ae 100644 --- a/src/gui/opengl/opengl.pri +++ b/src/gui/opengl/opengl.pri @@ -36,7 +36,8 @@ contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) { opengl/qopengltexture.h \ opengl/qopengltexture_p.h \ opengl/qopengltexturehelper_p.h \ - opengl/qopenglpixeltransferoptions.h + opengl/qopenglpixeltransferoptions.h \ + opengl/qopenglextrafunctions.h SOURCES += opengl/qopengl.cpp \ opengl/qopenglfunctions.cpp \ diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp index cc16026ddc1e1a2e673ba163b5df58e1847016a0..c37a09c2f4ebac11622d35a39581e8694050ec65 100644 --- a/src/gui/opengl/qopengl.cpp +++ b/src/gui/opengl/qopengl.cpp @@ -149,20 +149,42 @@ static const char operators[][3] = {"!=", "<", "<=", "=", ">", ">="}; static inline QString valueKey() { return QStringLiteral("value"); } static inline QString opKey() { return QStringLiteral("op"); } static inline QString versionKey() { return QStringLiteral("version"); } +static inline QString releaseKey() { return QStringLiteral("release"); } static inline QString typeKey() { return QStringLiteral("type"); } static inline QString osKey() { return QStringLiteral("os"); } static inline QString vendorIdKey() { return QStringLiteral("vendor_id"); } static inline QString glVendorKey() { return QStringLiteral("gl_vendor"); } static inline QString deviceIdKey() { return QStringLiteral("device_id"); } static inline QString driverVersionKey() { return QStringLiteral("driver_version"); } +static inline QString driverDescriptionKey() { return QStringLiteral("driver_description"); } static inline QString featuresKey() { return QStringLiteral("features"); } static inline QString idKey() { return QStringLiteral("id"); } static inline QString descriptionKey() { return QStringLiteral("description"); } static inline QString exceptionsKey() { return QStringLiteral("exceptions"); } +typedef QJsonArray::ConstIterator JsonArrayConstIt; + +static inline bool contains(const QJsonArray &haystack, unsigned needle) +{ + for (JsonArrayConstIt it = haystack.constBegin(), cend = haystack.constEnd(); it != cend; ++it) { + if (needle == it->toString().toUInt(Q_NULLPTR, /* base */ 0)) + return true; + } + return false; +} + +static inline bool contains(const QJsonArray &haystack, const QString &needle) +{ + for (JsonArrayConstIt it = haystack.constBegin(), cend = haystack.constEnd(); it != cend; ++it) { + if (needle == it->toString()) + return true; + } + return false; +} + namespace { // VersionTerm describing a version term consisting of number and operator -// found in "os", "driver_version", "gl_version". +// found in os.version and driver_version. struct VersionTerm { VersionTerm() : op(NotEqual) {} static VersionTerm fromJson(const QJsonValue &v); @@ -220,9 +242,38 @@ struct OsTypeTerm static OsTypeTerm fromJson(const QJsonValue &v); static QString hostOs(); static QVersionNumber hostKernelVersion() { return QVersionNumber::fromString(QSysInfo::kernelVersion()); } + static QString hostOsRelease() { + QString ver; +#ifdef Q_OS_WIN + switch (QSysInfo::windowsVersion()) { + case QSysInfo::WV_XP: + case QSysInfo::WV_2003: + ver = QStringLiteral("xp"); + break; + case QSysInfo::WV_VISTA: + ver = QStringLiteral("vista"); + break; + case QSysInfo::WV_WINDOWS7: + ver = QStringLiteral("7"); + break; + case QSysInfo::WV_WINDOWS8: + ver = QStringLiteral("8"); + break; + case QSysInfo::WV_WINDOWS8_1: + ver = QStringLiteral("8.1"); + break; + case QSysInfo::WV_WINDOWS10: + ver = QStringLiteral("10"); + break; + default: + break; + } +#endif + return ver; + } bool isNull() const { return type.isEmpty(); } - bool matches(const QString &osName, const QVersionNumber &kernelVersion) const + bool matches(const QString &osName, const QVersionNumber &kernelVersion, const QString &osRelease) const { if (isNull() || osName.isEmpty() || kernelVersion.isNull()) { qWarning() << Q_FUNC_INFO << "called with invalid parameters"; @@ -230,11 +281,17 @@ struct OsTypeTerm } if (type != osName) return false; - return versionTerm.isNull() || versionTerm.matches(kernelVersion); + if (!versionTerm.isNull() && !versionTerm.matches(kernelVersion)) + return false; + // release is a list of Windows versions where the rule should match + if (!release.isEmpty() && !contains(release, osRelease)) + return false; + return true; } QString type; VersionTerm versionTerm; + QJsonArray release; }; OsTypeTerm OsTypeTerm::fromJson(const QJsonValue &v) @@ -245,6 +302,7 @@ OsTypeTerm OsTypeTerm::fromJson(const QJsonValue &v) const QJsonObject o = v.toObject(); result.type = o.value(typeKey()).toString(); result.versionTerm = VersionTerm::fromJson(o.value(versionKey())); + result.release = o.value(releaseKey()).toArray(); return result; } @@ -265,17 +323,6 @@ QString OsTypeTerm::hostOs() } } // anonymous namespace -typedef QJsonArray::ConstIterator JsonArrayConstIt; - -static inline bool contains(const QJsonArray &a, unsigned needle) -{ - for (JsonArrayConstIt it = a.constBegin(), cend = a.constEnd(); it != cend; ++it) { - if (needle == it->toString().toUInt(Q_NULLPTR, /* base */ 0)) - return true; - } - return false; -} - static QString msgSyntaxWarning(const QJsonObject &object, const QString &what) { QString result; @@ -291,17 +338,18 @@ static QString msgSyntaxWarning(const QJsonObject &object, const QString &what) static bool matches(const QJsonObject &object, const QString &osName, const QVersionNumber &kernelVersion, + const QString &osRelease, const QOpenGLConfig::Gpu &gpu) { const OsTypeTerm os = OsTypeTerm::fromJson(object.value(osKey())); - if (!os.isNull() && !os.matches(osName, kernelVersion)) + if (!os.isNull() && !os.matches(osName, kernelVersion, osRelease)) return false; const QJsonValue exceptionsV = object.value(exceptionsKey()); if (exceptionsV.isArray()) { const QJsonArray exceptionsA = exceptionsV.toArray(); for (JsonArrayConstIt it = exceptionsA.constBegin(), cend = exceptionsA.constEnd(); it != cend; ++it) { - if (matches(it->toObject(), osName, kernelVersion, gpu)) + if (matches(it->toObject(), osName, kernelVersion, osRelease, gpu)) return false; } } @@ -350,12 +398,22 @@ static bool matches(const QJsonObject &object, QLatin1String("Driver version must be of type object.")); } } + + if (!gpu.driverDescription.isEmpty()) { + const QJsonValue driverDescriptionV = object.value(driverDescriptionKey()); + if (driverDescriptionV.isString()) { + if (!gpu.driverDescription.contains(driverDescriptionV.toString().toUtf8())) + return false; + } + } + return true; } static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, const QString &osName, const QVersionNumber &kernelVersion, + const QString &osRelease, const QJsonDocument &doc, QSet<QString> *result, QString *errorMessage) @@ -372,7 +430,7 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, for (JsonArrayConstIt eit = entriesA.constBegin(), ecend = entriesA.constEnd(); eit != ecend; ++eit) { if (eit->isObject()) { const QJsonObject object = eit->toObject(); - if (matches(object, osName, kernelVersion, gpu)) { + if (matches(object, osName, kernelVersion, osRelease, gpu)) { const QJsonValue featuresListV = object.value(featuresKey()); if (featuresListV.isArray()) { const QJsonArray featuresListA = featuresListV.toArray(); @@ -388,6 +446,7 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, const QString &osName, const QVersionNumber &kernelVersion, + const QString &osRelease, const QByteArray &jsonAsciiData, QSet<QString> *result, QString *errorMessage) { @@ -403,12 +462,13 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, << error.offset << ")."; return false; } - return readGpuFeatures(gpu, osName, kernelVersion, document, result, errorMessage); + return readGpuFeatures(gpu, osName, kernelVersion, osRelease, document, result, errorMessage); } static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, const QString &osName, const QVersionNumber &kernelVersion, + const QString &osRelease, const QString &fileName, QSet<QString> *result, QString *errorMessage) { @@ -421,7 +481,7 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, << file.errorString(); return false; } - const bool success = readGpuFeatures(gpu, osName, kernelVersion, file.readAll(), result, errorMessage); + const bool success = readGpuFeatures(gpu, osName, kernelVersion, osRelease, file.readAll(), result, errorMessage); if (!success) { errorMessage->prepend(QLatin1String("Error reading \"") + QDir::toNativeSeparators(fileName) @@ -431,37 +491,39 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, } QSet<QString> QOpenGLConfig::gpuFeatures(const QOpenGLConfig::Gpu &gpu, - const QString &osName, - const QVersionNumber &kernelVersion, - const QJsonDocument &doc) + const QString &osName, + const QVersionNumber &kernelVersion, + const QString &osRelease, + const QJsonDocument &doc) { QSet<QString> result; QString errorMessage; - if (!readGpuFeatures(gpu, osName, kernelVersion, doc, &result, &errorMessage)) + if (!readGpuFeatures(gpu, osName, kernelVersion, osRelease, doc, &result, &errorMessage)) qWarning().noquote() << errorMessage; return result; } QSet<QString> QOpenGLConfig::gpuFeatures(const QOpenGLConfig::Gpu &gpu, - const QString &osName, - const QVersionNumber &kernelVersion, - const QString &fileName) + const QString &osName, + const QVersionNumber &kernelVersion, + const QString &osRelease, + const QString &fileName) { QSet<QString> result; QString errorMessage; - if (!readGpuFeatures(gpu, osName, kernelVersion, fileName, &result, &errorMessage)) + if (!readGpuFeatures(gpu, osName, kernelVersion, osRelease, fileName, &result, &errorMessage)) qWarning().noquote() << errorMessage; return result; } QSet<QString> QOpenGLConfig::gpuFeatures(const Gpu &gpu, const QJsonDocument &doc) { - return gpuFeatures(gpu, OsTypeTerm::hostOs(), OsTypeTerm::hostKernelVersion(), doc); + return gpuFeatures(gpu, OsTypeTerm::hostOs(), OsTypeTerm::hostKernelVersion(), OsTypeTerm::hostOsRelease(), doc); } QSet<QString> QOpenGLConfig::gpuFeatures(const Gpu &gpu, const QString &fileName) { - return gpuFeatures(gpu, OsTypeTerm::hostOs(), OsTypeTerm::hostKernelVersion(), fileName); + return gpuFeatures(gpu, OsTypeTerm::hostOs(), OsTypeTerm::hostKernelVersion(), OsTypeTerm::hostOsRelease(), fileName); } QOpenGLConfig::Gpu QOpenGLConfig::Gpu::fromContext() diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h index 72abce760d1e5eb3e79c1b7f1cbe89be6125c3f0..87dc2a830e89409d12bc56bf2cb9ecff82aac024 100644 --- a/src/gui/opengl/qopengl.h +++ b/src/gui/opengl/qopengl.h @@ -83,13 +83,11 @@ typedef void* GLeglImageOES; // include headers on top of each other, meaning that applications can // include gl2.h even if gl31.h gets included here. -// This compile time differentation is important inside Qt because, -// unlike desktop GL, GLES is different when it comes to versioning -// and extensions: Standard functions that are new in a given version -// are always available in a version-specific header and are not -// guaranteed to be dynamically resolvable via eglGetProcAddress (and -// are typically not available as extensions even if they were part of -// an extension for a previous version). +// NB! This file contains the only usages of the ES_3 and ES_3_1 +// macros. They are useless for pretty much anything else. The fact +// that Qt was built against an SDK with f.ex. ES 2 only does not mean +// applications cannot target ES 3. Therefore QOpenGLFunctions and +// friends do everything dynamically and never rely on these macros. # if defined(QT_OPENGL_ES_3_1) # include <GLES3/gl31.h> diff --git a/src/gui/opengl/qopengl_p.h b/src/gui/opengl/qopengl_p.h index 980e02aea6b1690cab4ef56dafbc4f015bc36593..6b66a3ba573b0f49e0071f8b2a93288e66152938 100644 --- a/src/gui/opengl/qopengl_p.h +++ b/src/gui/opengl/qopengl_p.h @@ -49,7 +49,7 @@ #include <private/qopenglcontext_p.h> #include <QtCore/qset.h> #include <QtCore/qstring.h> -#include <private/qversionnumber_p.h> +#include <QtCore/qversionnumber.h> QT_BEGIN_NAMESPACE @@ -79,19 +79,21 @@ public: bool isValid() const { return deviceId || !glVendor.isEmpty(); } bool equals(const Gpu &other) const { return vendorId == other.vendorId && deviceId == other.deviceId && driverVersion == other.driverVersion - && glVendor == other.glVendor; + && driverDescription == other.driverDescription && glVendor == other.glVendor; } uint vendorId; uint deviceId; QVersionNumber driverVersion; + QByteArray driverDescription; QByteArray glVendor; - static Gpu fromDevice(uint vendorId, uint deviceId, QVersionNumber driverVersion) { + static Gpu fromDevice(uint vendorId, uint deviceId, QVersionNumber driverVersion, const QByteArray &driverDescription) { Gpu gpu; gpu.vendorId = vendorId; gpu.deviceId = deviceId; gpu.driverVersion = driverVersion; + gpu.driverDescription = driverDescription; return gpu; } @@ -105,10 +107,10 @@ public: }; static QSet<QString> gpuFeatures(const Gpu &gpu, - const QString &osName, const QVersionNumber &kernelVersion, + const QString &osName, const QVersionNumber &kernelVersion, const QString &osVersion, const QJsonDocument &doc); static QSet<QString> gpuFeatures(const Gpu &gpu, - const QString &osName, const QVersionNumber &kernelVersion, + const QString &osName, const QVersionNumber &kernelVersion, const QString &osVersion, const QString &fileName); static QSet<QString> gpuFeatures(const Gpu &gpu, const QJsonDocument &doc); static QSet<QString> gpuFeatures(const Gpu &gpu, const QString &fileName); diff --git a/src/gui/opengl/qopenglbuffer.h b/src/gui/opengl/qopenglbuffer.h index 847c1efaa03aade6020061d6ca085727ed99cfef..ca3d85d8e005fff48b550405fe6398ef04d38113 100644 --- a/src/gui/opengl/qopenglbuffer.h +++ b/src/gui/opengl/qopenglbuffer.h @@ -118,7 +118,7 @@ public: void write(int offset, const void *data, int count); void allocate(const void *data, int count); - inline void allocate(int count) { allocate(0, count); } + inline void allocate(int count) { allocate(Q_NULLPTR, count); } void *map(QOpenGLBuffer::Access access); void *mapRange(int offset, int count, QOpenGLBuffer::RangeAccessFlags access); diff --git a/src/gui/opengl/qopengldebug.h b/src/gui/opengl/qopengldebug.h index 425ab78d7a7e2eb3461aeb94fbc1784f789b330f..3e93ad4120c1f6f498118c3b937b9cd3b72d2483 100644 --- a/src/gui/opengl/qopengldebug.h +++ b/src/gui/opengl/qopengldebug.h @@ -97,14 +97,14 @@ public: QOpenGLDebugMessage(); QOpenGLDebugMessage(const QOpenGLDebugMessage &debugMessage); - ~QOpenGLDebugMessage(); QOpenGLDebugMessage &operator=(const QOpenGLDebugMessage &debugMessage); #ifdef Q_COMPILER_RVALUE_REFS - inline QOpenGLDebugMessage &operator=(QOpenGLDebugMessage &&debugMessage) - { d.swap(debugMessage.d); return *this; } + QOpenGLDebugMessage &operator=(QOpenGLDebugMessage &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif - inline void swap(QOpenGLDebugMessage &debugMessage) { d.swap(debugMessage.d); } + ~QOpenGLDebugMessage(); + + void swap(QOpenGLDebugMessage &other) Q_DECL_NOTHROW { qSwap(d, other.d); } Source source() const; Type type() const; @@ -156,7 +156,7 @@ public: }; Q_ENUM(LoggingMode) - explicit QOpenGLDebugLogger(QObject *parent = 0); + explicit QOpenGLDebugLogger(QObject *parent = Q_NULLPTR); ~QOpenGLDebugLogger(); bool initialize(); diff --git a/src/gui/opengl/qopenglextensions_p.h b/src/gui/opengl/qopenglextensions_p.h index 7def687f49bc2608deca711ce0a560196f5b2894..aa2a08242dcc41345068e0d186ac41a737299d48 100644 --- a/src/gui/opengl/qopenglextensions_p.h +++ b/src/gui/opengl/qopenglextensions_p.h @@ -45,7 +45,7 @@ // We mean it. // -#include "qopenglfunctions.h" +#include "qopenglextrafunctions.h" #include <QtCore/qlibrary.h> QT_BEGIN_NAMESPACE @@ -57,32 +57,194 @@ class QOpenGLES3Helper public: QOpenGLES3Helper(); - GLvoid* (QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access); + // GLES3 + void (QOPENGLF_APIENTRYP ReadBuffer)(GLenum mode); + void (QOPENGLF_APIENTRYP DrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); + void (QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); + void (QOPENGLF_APIENTRYP TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); + void (QOPENGLF_APIENTRYP CopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); + void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); + void (QOPENGLF_APIENTRYP GenQueries)(GLsizei n, GLuint *ids); + void (QOPENGLF_APIENTRYP DeleteQueries)(GLsizei n, const GLuint *ids); + GLboolean (QOPENGLF_APIENTRYP IsQuery)(GLuint id); + void (QOPENGLF_APIENTRYP BeginQuery)(GLenum target, GLuint id); + void (QOPENGLF_APIENTRYP EndQuery)(GLenum target); + void (QOPENGLF_APIENTRYP GetQueryiv)(GLenum target, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetQueryObjectuiv)(GLuint id, GLenum pname, GLuint *params); GLboolean (QOPENGLF_APIENTRYP UnmapBuffer)(GLenum target); + void (QOPENGLF_APIENTRYP GetBufferPointerv)(GLenum target, GLenum pname, void **params); + void (QOPENGLF_APIENTRYP DrawBuffers)(GLsizei n, const GLenum *bufs); + void (QOPENGLF_APIENTRYP UniformMatrix2x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix3x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix2x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix4x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix3x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix4x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); void (QOPENGLF_APIENTRYP BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); - void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height); - - void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays); - void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays); + void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP FramebufferTextureLayer)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + void *(QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + void (QOPENGLF_APIENTRYP FlushMappedBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length); void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array); + void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays); + void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays); GLboolean (QOPENGLF_APIENTRYP IsVertexArray)(GLuint array); - - void (QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); - void (QOPENGLF_APIENTRYP TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); - void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); - void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); - - void (QOPENGLF_APIENTRYP TexStorage3D)(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth); - void (QOPENGLF_APIENTRYP TexStorage2D)(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP GetIntegeri_v)(GLenum target, GLuint index, GLint *data); + void (QOPENGLF_APIENTRYP BeginTransformFeedback)(GLenum primitiveMode); + void (QOPENGLF_APIENTRYP EndTransformFeedback)(void); + void (QOPENGLF_APIENTRYP BindBufferRange)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + void (QOPENGLF_APIENTRYP BindBufferBase)(GLenum target, GLuint index, GLuint buffer); + void (QOPENGLF_APIENTRYP TransformFeedbackVaryings)(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); + void (QOPENGLF_APIENTRYP GetTransformFeedbackVarying)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); + void (QOPENGLF_APIENTRYP VertexAttribIPointer)(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); + void (QOPENGLF_APIENTRYP GetVertexAttribIiv)(GLuint index, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetVertexAttribIuiv)(GLuint index, GLenum pname, GLuint *params); + void (QOPENGLF_APIENTRYP VertexAttribI4i)(GLuint index, GLint x, GLint y, GLint z, GLint w); + void (QOPENGLF_APIENTRYP VertexAttribI4ui)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + void (QOPENGLF_APIENTRYP VertexAttribI4iv)(GLuint index, const GLint *v); + void (QOPENGLF_APIENTRYP VertexAttribI4uiv)(GLuint index, const GLuint *v); + void (QOPENGLF_APIENTRYP GetUniformuiv)(GLuint program, GLint location, GLuint *params); + GLint (QOPENGLF_APIENTRYP GetFragDataLocation)(GLuint program, const GLchar *name); + void (QOPENGLF_APIENTRYP Uniform1ui)(GLint location, GLuint v0); + void (QOPENGLF_APIENTRYP Uniform2ui)(GLint location, GLuint v0, GLuint v1); + void (QOPENGLF_APIENTRYP Uniform3ui)(GLint location, GLuint v0, GLuint v1, GLuint v2); + void (QOPENGLF_APIENTRYP Uniform4ui)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void (QOPENGLF_APIENTRYP Uniform1uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP Uniform2uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP Uniform3uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP Uniform4uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ClearBufferiv)(GLenum buffer, GLint drawbuffer, const GLint *value); + void (QOPENGLF_APIENTRYP ClearBufferuiv)(GLenum buffer, GLint drawbuffer, const GLuint *value); + void (QOPENGLF_APIENTRYP ClearBufferfv)(GLenum buffer, GLint drawbuffer, const GLfloat *value); + void (QOPENGLF_APIENTRYP ClearBufferfi)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + const GLubyte *(QOPENGLF_APIENTRYP GetStringi)(GLenum name, GLuint index); + void (QOPENGLF_APIENTRYP CopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + void (QOPENGLF_APIENTRYP GetUniformIndices)(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); + void (QOPENGLF_APIENTRYP GetActiveUniformsiv)(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); + GLuint (QOPENGLF_APIENTRYP GetUniformBlockIndex)(GLuint program, const GLchar *uniformBlockName); + void (QOPENGLF_APIENTRYP GetActiveUniformBlockiv)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetActiveUniformBlockName)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); + void (QOPENGLF_APIENTRYP UniformBlockBinding)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + void (QOPENGLF_APIENTRYP DrawArraysInstanced)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); + void (QOPENGLF_APIENTRYP DrawElementsInstanced)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); + GLsync (QOPENGLF_APIENTRYP FenceSync)(GLenum condition, GLbitfield flags); + GLboolean (QOPENGLF_APIENTRYP IsSync)(GLsync sync); + void (QOPENGLF_APIENTRYP DeleteSync)(GLsync sync); + GLenum (QOPENGLF_APIENTRYP ClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); + void (QOPENGLF_APIENTRYP WaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); + void (QOPENGLF_APIENTRYP GetInteger64v)(GLenum pname, GLint64 *data); + void (QOPENGLF_APIENTRYP GetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); + void (QOPENGLF_APIENTRYP GetInteger64i_v)(GLenum target, GLuint index, GLint64 *data); + void (QOPENGLF_APIENTRYP GetBufferParameteri64v)(GLenum target, GLenum pname, GLint64 *params); + void (QOPENGLF_APIENTRYP GenSamplers)(GLsizei count, GLuint *samplers); + void (QOPENGLF_APIENTRYP DeleteSamplers)(GLsizei count, const GLuint *samplers); + GLboolean (QOPENGLF_APIENTRYP IsSampler)(GLuint sampler); + void (QOPENGLF_APIENTRYP BindSampler)(GLuint unit, GLuint sampler); + void (QOPENGLF_APIENTRYP SamplerParameteri)(GLuint sampler, GLenum pname, GLint param); + void (QOPENGLF_APIENTRYP SamplerParameteriv)(GLuint sampler, GLenum pname, const GLint *param); + void (QOPENGLF_APIENTRYP SamplerParameterf)(GLuint sampler, GLenum pname, GLfloat param); + void (QOPENGLF_APIENTRYP SamplerParameterfv)(GLuint sampler, GLenum pname, const GLfloat *param); + void (QOPENGLF_APIENTRYP GetSamplerParameteriv)(GLuint sampler, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetSamplerParameterfv)(GLuint sampler, GLenum pname, GLfloat *params); + void (QOPENGLF_APIENTRYP VertexAttribDivisor)(GLuint index, GLuint divisor); + void (QOPENGLF_APIENTRYP BindTransformFeedback)(GLenum target, GLuint id); + void (QOPENGLF_APIENTRYP DeleteTransformFeedbacks)(GLsizei n, const GLuint *ids); + void (QOPENGLF_APIENTRYP GenTransformFeedbacks)(GLsizei n, GLuint *ids); + GLboolean (QOPENGLF_APIENTRYP IsTransformFeedback)(GLuint id); + void (QOPENGLF_APIENTRYP PauseTransformFeedback)(void); + void (QOPENGLF_APIENTRYP ResumeTransformFeedback)(void); + void (QOPENGLF_APIENTRYP GetProgramBinary)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); + void (QOPENGLF_APIENTRYP ProgramBinary)(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); + void (QOPENGLF_APIENTRYP ProgramParameteri)(GLuint program, GLenum pname, GLint value); + void (QOPENGLF_APIENTRYP InvalidateFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments); + void (QOPENGLF_APIENTRYP InvalidateSubFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP TexStorage2D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP TexStorage3D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + void (QOPENGLF_APIENTRYP GetInternalformativ)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); + + // GLES 3.1 + void (QOPENGLF_APIENTRYP DispatchCompute)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); + void (QOPENGLF_APIENTRYP DispatchComputeIndirect)(GLintptr indirect); + void (QOPENGLF_APIENTRYP DrawArraysIndirect)(GLenum mode, const void *indirect); + void (QOPENGLF_APIENTRYP DrawElementsIndirect)(GLenum mode, GLenum type, const void *indirect); + void (QOPENGLF_APIENTRYP FramebufferParameteri)(GLenum target, GLenum pname, GLint param); + void (QOPENGLF_APIENTRYP GetFramebufferParameteriv)(GLenum target, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetProgramInterfaceiv)(GLuint program, GLenum programInterface, GLenum pname, GLint *params); + GLuint (QOPENGLF_APIENTRYP GetProgramResourceIndex)(GLuint program, GLenum programInterface, const GLchar *name); + void (QOPENGLF_APIENTRYP GetProgramResourceName)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); + void (QOPENGLF_APIENTRYP GetProgramResourceiv)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); + GLint (QOPENGLF_APIENTRYP GetProgramResourceLocation)(GLuint program, GLenum programInterface, const GLchar *name); + void (QOPENGLF_APIENTRYP UseProgramStages)(GLuint pipeline, GLbitfield stages, GLuint program); + void (QOPENGLF_APIENTRYP ActiveShaderProgram)(GLuint pipeline, GLuint program); + GLuint (QOPENGLF_APIENTRYP CreateShaderProgramv)(GLenum type, GLsizei count, const GLchar *const*strings); + void (QOPENGLF_APIENTRYP BindProgramPipeline)(GLuint pipeline); + void (QOPENGLF_APIENTRYP DeleteProgramPipelines)(GLsizei n, const GLuint *pipelines); + void (QOPENGLF_APIENTRYP GenProgramPipelines)(GLsizei n, GLuint *pipelines); + GLboolean (QOPENGLF_APIENTRYP IsProgramPipeline)(GLuint pipeline); + void (QOPENGLF_APIENTRYP GetProgramPipelineiv)(GLuint pipeline, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP ProgramUniform1i)(GLuint program, GLint location, GLint v0); + void (QOPENGLF_APIENTRYP ProgramUniform2i)(GLuint program, GLint location, GLint v0, GLint v1); + void (QOPENGLF_APIENTRYP ProgramUniform3i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); + void (QOPENGLF_APIENTRYP ProgramUniform4i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + void (QOPENGLF_APIENTRYP ProgramUniform1ui)(GLuint program, GLint location, GLuint v0); + void (QOPENGLF_APIENTRYP ProgramUniform2ui)(GLuint program, GLint location, GLuint v0, GLuint v1); + void (QOPENGLF_APIENTRYP ProgramUniform3ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); + void (QOPENGLF_APIENTRYP ProgramUniform4ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void (QOPENGLF_APIENTRYP ProgramUniform1f)(GLuint program, GLint location, GLfloat v0); + void (QOPENGLF_APIENTRYP ProgramUniform2f)(GLuint program, GLint location, GLfloat v0, GLfloat v1); + void (QOPENGLF_APIENTRYP ProgramUniform3f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + void (QOPENGLF_APIENTRYP ProgramUniform4f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + void (QOPENGLF_APIENTRYP ProgramUniform1iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform2iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform3iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform4iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform1uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform2uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform3uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform4uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform1fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniform2fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniform3fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniform4fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ValidateProgramPipeline)(GLuint pipeline); + void (QOPENGLF_APIENTRYP GetProgramPipelineInfoLog)(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); + void (QOPENGLF_APIENTRYP BindImageTexture)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); + void (QOPENGLF_APIENTRYP GetBooleani_v)(GLenum target, GLuint index, GLboolean *data); + void (QOPENGLF_APIENTRYP MemoryBarrierFunc)(GLbitfield barriers); + void (QOPENGLF_APIENTRYP MemoryBarrierByRegion)(GLbitfield barriers); + void (QOPENGLF_APIENTRYP TexStorage2DMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + void (QOPENGLF_APIENTRYP GetMultisamplefv)(GLenum pname, GLuint index, GLfloat *val); + void (QOPENGLF_APIENTRYP SampleMaski)(GLuint maskNumber, GLbitfield mask); + void (QOPENGLF_APIENTRYP GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params); + void (QOPENGLF_APIENTRYP BindVertexBuffer)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); + void (QOPENGLF_APIENTRYP VertexAttribFormat)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + void (QOPENGLF_APIENTRYP VertexAttribIFormat)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + void (QOPENGLF_APIENTRYP VertexAttribBinding)(GLuint attribindex, GLuint bindingindex); + void (QOPENGLF_APIENTRYP VertexBindingDivisor)(GLuint bindingindex, GLuint divisor); + + QPair<int, int> supportedVersion() const { return m_supportedVersion; } private: bool init(); QFunctionPointer resolve(const char *name); - +#ifndef QT_NO_LIBRARY QLibrary m_gl; +#endif + QPair<int, int> m_supportedVersion; }; -class Q_GUI_EXPORT QOpenGLExtensions : public QOpenGLFunctions +class Q_GUI_EXPORT QOpenGLExtensions : public QOpenGLExtraFunctions { Q_DECLARE_PRIVATE(QOpenGLExtensions) public: @@ -113,7 +275,8 @@ public: GeometryShaders = 0x00080000, MapBufferRange = 0x00100000, Sized8Formats = 0x00200000, - DiscardFramebuffer = 0x00400000 + DiscardFramebuffer = 0x00400000, + Sized16Formats = 0x00800000 }; Q_DECLARE_FLAGS(OpenGLExtensions, OpenGLExtension) @@ -121,19 +284,7 @@ public: bool hasOpenGLExtension(QOpenGLExtensions::OpenGLExtension extension) const; GLvoid *glMapBuffer(GLenum target, GLenum access); - GLvoid *glMapBufferRange(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access); - GLboolean glUnmapBuffer(GLenum target); - - void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); - - void glRenderbufferStorageMultisample(GLenum target, GLsizei samples, - GLenum internalFormat, - GLsizei width, GLsizei height); - void glGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data); - void glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments); QOpenGLES3Helper *gles3Helper(); @@ -146,21 +297,12 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLExtensions::OpenGLExtensions) -class QOpenGLExtensionsPrivate : public QOpenGLFunctionsPrivate +class QOpenGLExtensionsPrivate : public QOpenGLExtraFunctionsPrivate { public: explicit QOpenGLExtensionsPrivate(QOpenGLContext *ctx); GLvoid* (QOPENGLF_APIENTRYP MapBuffer)(GLenum target, GLenum access); - GLvoid* (QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, qopengl_GLintptr offset, - qopengl_GLsizeiptr length, GLbitfield access); - GLboolean (QOPENGLF_APIENTRYP UnmapBuffer)(GLenum target); - void (QOPENGLF_APIENTRYP BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); - void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, - GLenum internalFormat, - GLsizei width, GLsizei height); void (QOPENGLF_APIENTRYP GetBufferSubData)(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data); void (QOPENGLF_APIENTRYP DiscardFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments); @@ -177,45 +319,6 @@ inline GLvoid *QOpenGLExtensions::glMapBuffer(GLenum target, GLenum access) return result; } -inline GLvoid *QOpenGLExtensions::glMapBufferRange(GLenum target, qopengl_GLintptr offset, - qopengl_GLsizeiptr length, GLbitfield access) -{ - Q_D(QOpenGLExtensions); - Q_ASSERT(QOpenGLExtensions::isInitialized(d)); - GLvoid *result = d->MapBufferRange(target, offset, length, access); - Q_OPENGL_FUNCTIONS_DEBUG - return result; -} - -inline GLboolean QOpenGLExtensions::glUnmapBuffer(GLenum target) -{ - Q_D(QOpenGLExtensions); - Q_ASSERT(QOpenGLExtensions::isInitialized(d)); - GLboolean result = d->UnmapBuffer(target); - Q_OPENGL_FUNCTIONS_DEBUG - return result; -} - -inline void QOpenGLExtensions::glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) -{ - Q_D(QOpenGLExtensions); - Q_ASSERT(QOpenGLExtensions::isInitialized(d)); - d->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - Q_OPENGL_FUNCTIONS_DEBUG -} - -inline void QOpenGLExtensions::glRenderbufferStorageMultisample(GLenum target, GLsizei samples, - GLenum internalFormat, - GLsizei width, GLsizei height) -{ - Q_D(QOpenGLExtensions); - Q_ASSERT(QOpenGLExtensions::isInitialized(d)); - d->RenderbufferStorageMultisample(target, samples, internalFormat, width, height); - Q_OPENGL_FUNCTIONS_DEBUG -} - inline void QOpenGLExtensions::glGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data) { Q_D(QOpenGLExtensions); diff --git a/src/gui/opengl/qopenglextrafunctions.h b/src/gui/opengl/qopenglextrafunctions.h new file mode 100644 index 0000000000000000000000000000000000000000..6558284bd091228335e3e0c69004744c4c21f251 --- /dev/null +++ b/src/gui/opengl/qopenglextrafunctions.h @@ -0,0 +1,1990 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QOPENGLEXTRAFUNCTIONS_H +#define QOPENGLEXTRAFUNCTIONS_H + +#include <QtCore/qglobal.h> + +#ifndef QT_NO_OPENGL + +#include <QtGui/qopenglfunctions.h> + +QT_BEGIN_NAMESPACE + +class QOpenGLExtraFunctionsPrivate; + +#undef glReadBuffer +#undef glDrawRangeElements +#undef glTexImage3D +#undef glTexSubImage3D +#undef glCopyTexSubImage3D +#undef glCompressedTexImage3D +#undef glCompressedTexSubImage3D +#undef glGenQueries +#undef glDeleteQueries +#undef glIsQuery +#undef glBeginQuery +#undef glEndQuery +#undef glGetQueryiv +#undef glGetQueryObjectuiv +#undef glUnmapBuffer +#undef glGetBufferPointerv +#undef glDrawBuffers +#undef glUniformMatrix2x3fv +#undef glUniformMatrix3x2fv +#undef glUniformMatrix2x4fv +#undef glUniformMatrix4x2fv +#undef glUniformMatrix3x4fv +#undef glUniformMatrix4x3fv +#undef glBlitFramebuffer +#undef glRenderbufferStorageMultisample +#undef glFramebufferTextureLayer +#undef glMapBufferRange +#undef glFlushMappedBufferRange +#undef glBindVertexArray +#undef glDeleteVertexArrays +#undef glGenVertexArrays +#undef glIsVertexArray +#undef glGetIntegeri_v +#undef glBeginTransformFeedback +#undef glEndTransformFeedback +#undef glBindBufferRange +#undef glBindBufferBase +#undef glTransformFeedbackVaryings +#undef glGetTransformFeedbackVarying +#undef glVertexAttribIPointer +#undef glGetVertexAttribIiv +#undef glGetVertexAttribIuiv +#undef glVertexAttribI4i +#undef glVertexAttribI4ui +#undef glVertexAttribI4iv +#undef glVertexAttribI4uiv +#undef glGetUniformuiv +#undef glGetFragDataLocation +#undef glUniform1ui +#undef glUniform2ui +#undef glUniform3ui +#undef glUniform4ui +#undef glUniform1uiv +#undef glUniform2uiv +#undef glUniform3uiv +#undef glUniform4uiv +#undef glClearBufferiv +#undef glClearBufferuiv +#undef glClearBufferfv +#undef glClearBufferfi +#undef glGetStringi +#undef glCopyBufferSubData +#undef glGetUniformIndices +#undef glGetActiveUniformsiv +#undef glGetUniformBlockIndex +#undef glGetActiveUniformBlockiv +#undef glGetActiveUniformBlockName +#undef glUniformBlockBinding +#undef glDrawArraysInstanced +#undef glDrawElementsInstanced +#undef glFenceSync +#undef glIsSync +#undef glDeleteSync +#undef glClientWaitSync +#undef glWaitSync +#undef glGetInteger64v +#undef glGetSynciv +#undef glGetInteger64i_v +#undef glGetBufferParameteri64v +#undef glGenSamplers +#undef glDeleteSamplers +#undef glIsSampler +#undef glBindSampler +#undef glSamplerParameteri +#undef glSamplerParameteriv +#undef glSamplerParameterf +#undef glSamplerParameterfv +#undef glGetSamplerParameteriv +#undef glGetSamplerParameterfv +#undef glVertexAttribDivisor +#undef glBindTransformFeedback +#undef glDeleteTransformFeedbacks +#undef glGenTransformFeedbacks +#undef glIsTransformFeedback +#undef glPauseTransformFeedback +#undef glResumeTransformFeedback +#undef glGetProgramBinary +#undef glProgramBinary +#undef glProgramParameteri +#undef glInvalidateFramebuffer +#undef glInvalidateSubFramebuffer +#undef glTexStorage2D +#undef glTexStorage3D +#undef glGetInternalformativ + +#undef glDispatchCompute +#undef glDispatchComputeIndirect +#undef glDrawArraysIndirect +#undef glDrawElementsIndirect +#undef glFramebufferParameteri +#undef glGetFramebufferParameteriv +#undef glGetProgramInterfaceiv +#undef glGetProgramResourceIndex +#undef glGetProgramResourceName +#undef glGetProgramResourceiv +#undef glGetProgramResourceLocation +#undef glUseProgramStages +#undef glActiveShaderProgram +#undef glCreateShaderProgramv +#undef glBindProgramPipeline +#undef glDeleteProgramPipelines +#undef glGenProgramPipelines +#undef glIsProgramPipeline +#undef glGetProgramPipelineiv +#undef glProgramUniform1i +#undef glProgramUniform2i +#undef glProgramUniform3i +#undef glProgramUniform4i +#undef glProgramUniform1ui +#undef glProgramUniform2ui +#undef glProgramUniform3ui +#undef glProgramUniform4ui +#undef glProgramUniform1f +#undef glProgramUniform2f +#undef glProgramUniform3f +#undef glProgramUniform4f +#undef glProgramUniform1iv +#undef glProgramUniform2iv +#undef glProgramUniform3iv +#undef glProgramUniform4iv +#undef glProgramUniform1uiv +#undef glProgramUniform2uiv +#undef glProgramUniform3uiv +#undef glProgramUniform4uiv +#undef glProgramUniform1fv +#undef glProgramUniform2fv +#undef glProgramUniform3fv +#undef glProgramUniform4fv +#undef glProgramUniformMatrix2fv +#undef glProgramUniformMatrix3fv +#undef glProgramUniformMatrix4fv +#undef glProgramUniformMatrix2x3fv +#undef glProgramUniformMatrix3x2fv +#undef glProgramUniformMatrix2x4fv +#undef glProgramUniformMatrix4x2fv +#undef glProgramUniformMatrix3x4fv +#undef glProgramUniformMatrix4x3fv +#undef glValidateProgramPipeline +#undef glGetProgramPipelineInfoLog +#undef glBindImageTexture +#undef glGetBooleani_v +#undef glMemoryBarrier +#undef glMemoryBarrierByRegion +#undef glTexStorage2DMultisample +#undef glGetMultisamplefv +#undef glSampleMaski +#undef glGetTexLevelParameteriv +#undef glGetTexLevelParameterfv +#undef glBindVertexBuffer +#undef glVertexAttribFormat +#undef glVertexAttribIFormat +#undef glVertexAttribBinding +#undef glVertexBindingDivisor + +class Q_GUI_EXPORT QOpenGLExtraFunctions : public QOpenGLFunctions +{ + Q_DECLARE_PRIVATE(QOpenGLExtraFunctions) + +public: + QOpenGLExtraFunctions(); + QOpenGLExtraFunctions(QOpenGLContext *context); + ~QOpenGLExtraFunctions() {} + + // GLES3 + void glReadBuffer(GLenum mode); + void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); + void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); + void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); + void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + void glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); + void glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); + void glGenQueries(GLsizei n, GLuint *ids); + void glDeleteQueries(GLsizei n, const GLuint *ids); + GLboolean glIsQuery(GLuint id); + void glBeginQuery(GLenum target, GLuint id); + void glEndQuery(GLenum target); + void glGetQueryiv(GLenum target, GLenum pname, GLint *params); + void glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params); + GLboolean glUnmapBuffer(GLenum target); + void glGetBufferPointerv(GLenum target, GLenum pname, void **params); + void glDrawBuffers(GLsizei n, const GLenum *bufs); + void glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + void glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + void glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + void *glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + void glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length); + void glBindVertexArray(GLuint array); + void glDeleteVertexArrays(GLsizei n, const GLuint *arrays); + void glGenVertexArrays(GLsizei n, GLuint *arrays); + GLboolean glIsVertexArray(GLuint array); + void glGetIntegeri_v(GLenum target, GLuint index, GLint *data); + void glBeginTransformFeedback(GLenum primitiveMode); + void glEndTransformFeedback(void); + void glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + void glBindBufferBase(GLenum target, GLuint index, GLuint buffer); + void glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); + void glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); + void glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); + void glGetVertexAttribIiv(GLuint index, GLenum pname, GLint *params); + void glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params); + void glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w); + void glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + void glVertexAttribI4iv(GLuint index, const GLint *v); + void glVertexAttribI4uiv(GLuint index, const GLuint *v); + void glGetUniformuiv(GLuint program, GLint location, GLuint *params); + GLint glGetFragDataLocation(GLuint program, const GLchar *name); + void glUniform1ui(GLint location, GLuint v0); + void glUniform2ui(GLint location, GLuint v0, GLuint v1); + void glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2); + void glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void glUniform1uiv(GLint location, GLsizei count, const GLuint *value); + void glUniform2uiv(GLint location, GLsizei count, const GLuint *value); + void glUniform3uiv(GLint location, GLsizei count, const GLuint *value); + void glUniform4uiv(GLint location, GLsizei count, const GLuint *value); + void glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value); + void glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value); + void glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value); + void glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + const GLubyte *glGetStringi(GLenum name, GLuint index); + void glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + void glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); + void glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); + GLuint glGetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName); + void glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); + void glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); + void glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + void glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); + void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); + GLsync glFenceSync(GLenum condition, GLbitfield flags); + GLboolean glIsSync(GLsync sync); + void glDeleteSync(GLsync sync); + GLenum glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); + void glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); + void glGetInteger64v(GLenum pname, GLint64 *data); + void glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); + void glGetInteger64i_v(GLenum target, GLuint index, GLint64 *data); + void glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params); + void glGenSamplers(GLsizei count, GLuint *samplers); + void glDeleteSamplers(GLsizei count, const GLuint *samplers); + GLboolean glIsSampler(GLuint sampler); + void glBindSampler(GLuint unit, GLuint sampler); + void glSamplerParameteri(GLuint sampler, GLenum pname, GLint param); + void glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param); + void glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param); + void glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param); + void glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params); + void glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params); + void glVertexAttribDivisor(GLuint index, GLuint divisor); + void glBindTransformFeedback(GLenum target, GLuint id); + void glDeleteTransformFeedbacks(GLsizei n, const GLuint *ids); + void glGenTransformFeedbacks(GLsizei n, GLuint *ids); + GLboolean glIsTransformFeedback(GLuint id); + void glPauseTransformFeedback(void); + void glResumeTransformFeedback(void); + void glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); + void glProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); + void glProgramParameteri(GLuint program, GLenum pname, GLint value); + void glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments); + void glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); + void glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); + void glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + void glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); + + // GLES 3.1 + void glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); + void glDispatchComputeIndirect(GLintptr indirect); + void glDrawArraysIndirect(GLenum mode, const void *indirect); + void glDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect); + void glFramebufferParameteri(GLenum target, GLenum pname, GLint param); + void glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params); + void glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint *params); + GLuint glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name); + void glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); + void glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); + GLint glGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar *name); + void glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program); + void glActiveShaderProgram(GLuint pipeline, GLuint program); + GLuint glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const*strings); + void glBindProgramPipeline(GLuint pipeline); + void glDeleteProgramPipelines(GLsizei n, const GLuint *pipelines); + void glGenProgramPipelines(GLsizei n, GLuint *pipelines); + GLboolean glIsProgramPipeline(GLuint pipeline); + void glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params); + void glProgramUniform1i(GLuint program, GLint location, GLint v0); + void glProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1); + void glProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); + void glProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + void glProgramUniform1ui(GLuint program, GLint location, GLuint v0); + void glProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1); + void glProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); + void glProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void glProgramUniform1f(GLuint program, GLint location, GLfloat v0); + void glProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1); + void glProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + void glProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + void glProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value); + void glProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint *value); + void glProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint *value); + void glProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint *value); + void glProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint *value); + void glProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint *value); + void glProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint *value); + void glProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint *value); + void glProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void glProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void glProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void glProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void glProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glValidateProgramPipeline(GLuint pipeline); + void glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); + void glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); + void glGetBooleani_v(GLenum target, GLuint index, GLboolean *data); + void glMemoryBarrier(GLbitfield barriers); + void glMemoryBarrierByRegion(GLbitfield barriers); + void glTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + void glGetMultisamplefv(GLenum pname, GLuint index, GLfloat *val); + void glSampleMaski(GLuint maskNumber, GLbitfield mask); + void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params); + void glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params); + void glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); + void glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + void glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + void glVertexAttribBinding(GLuint attribindex, GLuint bindingindex); + void glVertexBindingDivisor(GLuint bindingindex, GLuint divisor); + +private: + static bool isInitialized(const QOpenGLExtraFunctionsPrivate *d) { return d != 0; } +}; + +class QOpenGLExtraFunctionsPrivate : public QOpenGLFunctionsPrivate +{ +public: + QOpenGLExtraFunctionsPrivate(QOpenGLContext *ctx); + + // GLES3 + void (QOPENGLF_APIENTRYP ReadBuffer)(GLenum mode); + void (QOPENGLF_APIENTRYP DrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); + void (QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); + void (QOPENGLF_APIENTRYP TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); + void (QOPENGLF_APIENTRYP CopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); + void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); + void (QOPENGLF_APIENTRYP GenQueries)(GLsizei n, GLuint *ids); + void (QOPENGLF_APIENTRYP DeleteQueries)(GLsizei n, const GLuint *ids); + GLboolean (QOPENGLF_APIENTRYP IsQuery)(GLuint id); + void (QOPENGLF_APIENTRYP BeginQuery)(GLenum target, GLuint id); + void (QOPENGLF_APIENTRYP EndQuery)(GLenum target); + void (QOPENGLF_APIENTRYP GetQueryiv)(GLenum target, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetQueryObjectuiv)(GLuint id, GLenum pname, GLuint *params); + GLboolean (QOPENGLF_APIENTRYP UnmapBuffer)(GLenum target); + void (QOPENGLF_APIENTRYP GetBufferPointerv)(GLenum target, GLenum pname, void **params); + void (QOPENGLF_APIENTRYP DrawBuffers)(GLsizei n, const GLenum *bufs); + void (QOPENGLF_APIENTRYP UniformMatrix2x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix3x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix2x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix4x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix3x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix4x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP FramebufferTextureLayer)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + void *(QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + void (QOPENGLF_APIENTRYP FlushMappedBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length); + void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array); + void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays); + void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays); + GLboolean (QOPENGLF_APIENTRYP IsVertexArray)(GLuint array); + void (QOPENGLF_APIENTRYP GetIntegeri_v)(GLenum target, GLuint index, GLint *data); + void (QOPENGLF_APIENTRYP BeginTransformFeedback)(GLenum primitiveMode); + void (QOPENGLF_APIENTRYP EndTransformFeedback)(void); + void (QOPENGLF_APIENTRYP BindBufferRange)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + void (QOPENGLF_APIENTRYP BindBufferBase)(GLenum target, GLuint index, GLuint buffer); + void (QOPENGLF_APIENTRYP TransformFeedbackVaryings)(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); + void (QOPENGLF_APIENTRYP GetTransformFeedbackVarying)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); + void (QOPENGLF_APIENTRYP VertexAttribIPointer)(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); + void (QOPENGLF_APIENTRYP GetVertexAttribIiv)(GLuint index, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetVertexAttribIuiv)(GLuint index, GLenum pname, GLuint *params); + void (QOPENGLF_APIENTRYP VertexAttribI4i)(GLuint index, GLint x, GLint y, GLint z, GLint w); + void (QOPENGLF_APIENTRYP VertexAttribI4ui)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + void (QOPENGLF_APIENTRYP VertexAttribI4iv)(GLuint index, const GLint *v); + void (QOPENGLF_APIENTRYP VertexAttribI4uiv)(GLuint index, const GLuint *v); + void (QOPENGLF_APIENTRYP GetUniformuiv)(GLuint program, GLint location, GLuint *params); + GLint (QOPENGLF_APIENTRYP GetFragDataLocation)(GLuint program, const GLchar *name); + void (QOPENGLF_APIENTRYP Uniform1ui)(GLint location, GLuint v0); + void (QOPENGLF_APIENTRYP Uniform2ui)(GLint location, GLuint v0, GLuint v1); + void (QOPENGLF_APIENTRYP Uniform3ui)(GLint location, GLuint v0, GLuint v1, GLuint v2); + void (QOPENGLF_APIENTRYP Uniform4ui)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void (QOPENGLF_APIENTRYP Uniform1uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP Uniform2uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP Uniform3uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP Uniform4uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ClearBufferiv)(GLenum buffer, GLint drawbuffer, const GLint *value); + void (QOPENGLF_APIENTRYP ClearBufferuiv)(GLenum buffer, GLint drawbuffer, const GLuint *value); + void (QOPENGLF_APIENTRYP ClearBufferfv)(GLenum buffer, GLint drawbuffer, const GLfloat *value); + void (QOPENGLF_APIENTRYP ClearBufferfi)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + const GLubyte *(QOPENGLF_APIENTRYP GetStringi)(GLenum name, GLuint index); + void (QOPENGLF_APIENTRYP CopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + void (QOPENGLF_APIENTRYP GetUniformIndices)(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); + void (QOPENGLF_APIENTRYP GetActiveUniformsiv)(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); + GLuint (QOPENGLF_APIENTRYP GetUniformBlockIndex)(GLuint program, const GLchar *uniformBlockName); + void (QOPENGLF_APIENTRYP GetActiveUniformBlockiv)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetActiveUniformBlockName)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); + void (QOPENGLF_APIENTRYP UniformBlockBinding)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + void (QOPENGLF_APIENTRYP DrawArraysInstanced)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); + void (QOPENGLF_APIENTRYP DrawElementsInstanced)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); + GLsync (QOPENGLF_APIENTRYP FenceSync)(GLenum condition, GLbitfield flags); + GLboolean (QOPENGLF_APIENTRYP IsSync)(GLsync sync); + void (QOPENGLF_APIENTRYP DeleteSync)(GLsync sync); + GLenum (QOPENGLF_APIENTRYP ClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); + void (QOPENGLF_APIENTRYP WaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); + void (QOPENGLF_APIENTRYP GetInteger64v)(GLenum pname, GLint64 *data); + void (QOPENGLF_APIENTRYP GetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); + void (QOPENGLF_APIENTRYP GetInteger64i_v)(GLenum target, GLuint index, GLint64 *data); + void (QOPENGLF_APIENTRYP GetBufferParameteri64v)(GLenum target, GLenum pname, GLint64 *params); + void (QOPENGLF_APIENTRYP GenSamplers)(GLsizei count, GLuint *samplers); + void (QOPENGLF_APIENTRYP DeleteSamplers)(GLsizei count, const GLuint *samplers); + GLboolean (QOPENGLF_APIENTRYP IsSampler)(GLuint sampler); + void (QOPENGLF_APIENTRYP BindSampler)(GLuint unit, GLuint sampler); + void (QOPENGLF_APIENTRYP SamplerParameteri)(GLuint sampler, GLenum pname, GLint param); + void (QOPENGLF_APIENTRYP SamplerParameteriv)(GLuint sampler, GLenum pname, const GLint *param); + void (QOPENGLF_APIENTRYP SamplerParameterf)(GLuint sampler, GLenum pname, GLfloat param); + void (QOPENGLF_APIENTRYP SamplerParameterfv)(GLuint sampler, GLenum pname, const GLfloat *param); + void (QOPENGLF_APIENTRYP GetSamplerParameteriv)(GLuint sampler, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetSamplerParameterfv)(GLuint sampler, GLenum pname, GLfloat *params); + void (QOPENGLF_APIENTRYP VertexAttribDivisor)(GLuint index, GLuint divisor); + void (QOPENGLF_APIENTRYP BindTransformFeedback)(GLenum target, GLuint id); + void (QOPENGLF_APIENTRYP DeleteTransformFeedbacks)(GLsizei n, const GLuint *ids); + void (QOPENGLF_APIENTRYP GenTransformFeedbacks)(GLsizei n, GLuint *ids); + GLboolean (QOPENGLF_APIENTRYP IsTransformFeedback)(GLuint id); + void (QOPENGLF_APIENTRYP PauseTransformFeedback)(void); + void (QOPENGLF_APIENTRYP ResumeTransformFeedback)(void); + void (QOPENGLF_APIENTRYP GetProgramBinary)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); + void (QOPENGLF_APIENTRYP ProgramBinary)(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); + void (QOPENGLF_APIENTRYP ProgramParameteri)(GLuint program, GLenum pname, GLint value); + void (QOPENGLF_APIENTRYP InvalidateFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments); + void (QOPENGLF_APIENTRYP InvalidateSubFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP TexStorage2D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP TexStorage3D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + void (QOPENGLF_APIENTRYP GetInternalformativ)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); + + // GLES 3.1 + void (QOPENGLF_APIENTRYP DispatchCompute)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); + void (QOPENGLF_APIENTRYP DispatchComputeIndirect)(GLintptr indirect); + void (QOPENGLF_APIENTRYP DrawArraysIndirect)(GLenum mode, const void *indirect); + void (QOPENGLF_APIENTRYP DrawElementsIndirect)(GLenum mode, GLenum type, const void *indirect); + void (QOPENGLF_APIENTRYP FramebufferParameteri)(GLenum target, GLenum pname, GLint param); + void (QOPENGLF_APIENTRYP GetFramebufferParameteriv)(GLenum target, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetProgramInterfaceiv)(GLuint program, GLenum programInterface, GLenum pname, GLint *params); + GLuint (QOPENGLF_APIENTRYP GetProgramResourceIndex)(GLuint program, GLenum programInterface, const GLchar *name); + void (QOPENGLF_APIENTRYP GetProgramResourceName)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); + void (QOPENGLF_APIENTRYP GetProgramResourceiv)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); + GLint (QOPENGLF_APIENTRYP GetProgramResourceLocation)(GLuint program, GLenum programInterface, const GLchar *name); + void (QOPENGLF_APIENTRYP UseProgramStages)(GLuint pipeline, GLbitfield stages, GLuint program); + void (QOPENGLF_APIENTRYP ActiveShaderProgram)(GLuint pipeline, GLuint program); + GLuint (QOPENGLF_APIENTRYP CreateShaderProgramv)(GLenum type, GLsizei count, const GLchar *const*strings); + void (QOPENGLF_APIENTRYP BindProgramPipeline)(GLuint pipeline); + void (QOPENGLF_APIENTRYP DeleteProgramPipelines)(GLsizei n, const GLuint *pipelines); + void (QOPENGLF_APIENTRYP GenProgramPipelines)(GLsizei n, GLuint *pipelines); + GLboolean (QOPENGLF_APIENTRYP IsProgramPipeline)(GLuint pipeline); + void (QOPENGLF_APIENTRYP GetProgramPipelineiv)(GLuint pipeline, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP ProgramUniform1i)(GLuint program, GLint location, GLint v0); + void (QOPENGLF_APIENTRYP ProgramUniform2i)(GLuint program, GLint location, GLint v0, GLint v1); + void (QOPENGLF_APIENTRYP ProgramUniform3i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); + void (QOPENGLF_APIENTRYP ProgramUniform4i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + void (QOPENGLF_APIENTRYP ProgramUniform1ui)(GLuint program, GLint location, GLuint v0); + void (QOPENGLF_APIENTRYP ProgramUniform2ui)(GLuint program, GLint location, GLuint v0, GLuint v1); + void (QOPENGLF_APIENTRYP ProgramUniform3ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); + void (QOPENGLF_APIENTRYP ProgramUniform4ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void (QOPENGLF_APIENTRYP ProgramUniform1f)(GLuint program, GLint location, GLfloat v0); + void (QOPENGLF_APIENTRYP ProgramUniform2f)(GLuint program, GLint location, GLfloat v0, GLfloat v1); + void (QOPENGLF_APIENTRYP ProgramUniform3f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + void (QOPENGLF_APIENTRYP ProgramUniform4f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + void (QOPENGLF_APIENTRYP ProgramUniform1iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform2iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform3iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform4iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform1uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform2uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform3uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform4uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform1fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniform2fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniform3fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniform4fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ValidateProgramPipeline)(GLuint pipeline); + void (QOPENGLF_APIENTRYP GetProgramPipelineInfoLog)(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); + void (QOPENGLF_APIENTRYP BindImageTexture)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); + void (QOPENGLF_APIENTRYP GetBooleani_v)(GLenum target, GLuint index, GLboolean *data); + void (QOPENGLF_APIENTRYP MemoryBarrierFunc)(GLbitfield barriers); + void (QOPENGLF_APIENTRYP MemoryBarrierByRegion)(GLbitfield barriers); + void (QOPENGLF_APIENTRYP TexStorage2DMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + void (QOPENGLF_APIENTRYP GetMultisamplefv)(GLenum pname, GLuint index, GLfloat *val); + void (QOPENGLF_APIENTRYP SampleMaski)(GLuint maskNumber, GLbitfield mask); + void (QOPENGLF_APIENTRYP GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params); + void (QOPENGLF_APIENTRYP BindVertexBuffer)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); + void (QOPENGLF_APIENTRYP VertexAttribFormat)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + void (QOPENGLF_APIENTRYP VertexAttribIFormat)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + void (QOPENGLF_APIENTRYP VertexAttribBinding)(GLuint attribindex, GLuint bindingindex); + void (QOPENGLF_APIENTRYP VertexBindingDivisor)(GLuint bindingindex, GLuint divisor); +}; + +// GLES 3.0 and 3.1 + +inline void QOpenGLExtraFunctions::glBeginQuery(GLenum target, GLuint id) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BeginQuery(target, id); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBeginTransformFeedback(GLenum primitiveMode) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BeginTransformFeedback(primitiveMode); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindBufferBase(GLenum target, GLuint index, GLuint buffer) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindBufferBase(target, index, buffer); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindBufferRange(target, index, buffer, offset, size); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindSampler(GLuint unit, GLuint sampler) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindSampler(unit, sampler); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindTransformFeedback(GLenum target, GLuint id) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindTransformFeedback(target, id); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindVertexArray(GLuint array) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindVertexArray(array); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ClearBufferfi(buffer, drawbuffer, depth, stencil); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ClearBufferfv(buffer, drawbuffer, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ClearBufferiv(buffer, drawbuffer, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ClearBufferuiv(buffer, drawbuffer, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLenum QOpenGLExtraFunctions::glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLenum result = d->ClientWaitSync(sync, flags, timeout); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->CompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->CopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDeleteQueries(GLsizei n, const GLuint * ids) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DeleteQueries(n, ids); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDeleteSamplers(GLsizei count, const GLuint * samplers) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DeleteSamplers(count, samplers); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDeleteSync(GLsync sync) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DeleteSync(sync); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDeleteTransformFeedbacks(GLsizei n, const GLuint * ids) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DeleteTransformFeedbacks(n, ids); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDeleteVertexArrays(GLsizei n, const GLuint * arrays) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DeleteVertexArrays(n, arrays); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DrawArraysInstanced(mode, first, count, instancecount); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDrawBuffers(GLsizei n, const GLenum * bufs) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DrawBuffers(n, bufs); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DrawElementsInstanced(mode, count, type, indices, instancecount); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DrawRangeElements(mode, start, end, count, type, indices); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glEndQuery(GLenum target) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->EndQuery(target); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glEndTransformFeedback() +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->EndTransformFeedback(); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLsync QOpenGLExtraFunctions::glFenceSync(GLenum condition, GLbitfield flags) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLsync result = d->FenceSync(condition, flags); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->FlushMappedBufferRange(target, offset, length); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->FramebufferTextureLayer(target, attachment, texture, level, layer); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGenQueries(GLsizei n, GLuint* ids) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GenQueries(n, ids); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGenSamplers(GLsizei count, GLuint* samplers) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GenSamplers(count, samplers); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGenTransformFeedbacks(GLsizei n, GLuint* ids) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GenTransformFeedbacks(n, ids); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGenVertexArrays(GLsizei n, GLuint* arrays) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GenVertexArrays(n, arrays); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetActiveUniformBlockiv(program, uniformBlockIndex, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetBufferParameteri64v(target, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetBufferPointerv(GLenum target, GLenum pname, void ** params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetBufferPointerv(target, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLint QOpenGLExtraFunctions::glGetFragDataLocation(GLuint program, const GLchar * name) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLint result = d->GetFragDataLocation(program, name); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glGetInteger64i_v(GLenum target, GLuint index, GLint64* data) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetInteger64i_v(target, index, data); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetInteger64v(GLenum pname, GLint64* data) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetInteger64v(pname, data); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetIntegeri_v(GLenum target, GLuint index, GLint* data) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetIntegeri_v(target, index, data); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetInternalformativ(target, internalformat, pname, bufSize, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void * binary) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetProgramBinary(program, bufSize, length, binaryFormat, binary); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetQueryObjectuiv(id, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetQueryiv(GLenum target, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetQueryiv(target, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetSamplerParameterfv(sampler, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetSamplerParameteriv(sampler, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline const GLubyte * QOpenGLExtraFunctions::glGetStringi(GLenum name, GLuint index) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + const GLubyte * result = d->GetStringi(name, index); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetSynciv(sync, pname, bufSize, length, values); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetTransformFeedbackVarying(program, index, bufSize, length, size, type, name); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLuint QOpenGLExtraFunctions::glGetUniformBlockIndex(GLuint program, const GLchar * uniformBlockName) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLuint result = d->GetUniformBlockIndex(program, uniformBlockName); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint* uniformIndices) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetUniformIndices(program, uniformCount, uniformNames, uniformIndices); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetUniformuiv(GLuint program, GLint location, GLuint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetUniformuiv(program, location, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetVertexAttribIiv(index, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetVertexAttribIuiv(index, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->InvalidateFramebuffer(target, numAttachments, attachments); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->InvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLboolean QOpenGLExtraFunctions::glIsQuery(GLuint id) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLboolean result = d->IsQuery(id); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline GLboolean QOpenGLExtraFunctions::glIsSampler(GLuint sampler) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLboolean result = d->IsSampler(sampler); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline GLboolean QOpenGLExtraFunctions::glIsSync(GLsync sync) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLboolean result = d->IsSync(sync); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline GLboolean QOpenGLExtraFunctions::glIsTransformFeedback(GLuint id) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLboolean result = d->IsTransformFeedback(id); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline GLboolean QOpenGLExtraFunctions::glIsVertexArray(GLuint array) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLboolean result = d->IsVertexArray(array); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void * QOpenGLExtraFunctions::glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + void *result = d->MapBufferRange(target, offset, length, access); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glPauseTransformFeedback() +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->PauseTransformFeedback(); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramBinary(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramBinary(program, binaryFormat, binary, length); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramParameteri(GLuint program, GLenum pname, GLint value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramParameteri(program, pname, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glReadBuffer(GLenum src) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ReadBuffer(src); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->RenderbufferStorageMultisample(target, samples, internalformat, width, height); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glResumeTransformFeedback() +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ResumeTransformFeedback(); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->SamplerParameterf(sampler, pname, param); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat * param) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->SamplerParameterfv(sampler, pname, param); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->SamplerParameteri(sampler, pname, param); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint * param) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->SamplerParameteriv(sampler, pname, param); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->TexStorage2D(target, levels, internalformat, width, height); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->TexStorage3D(target, levels, internalformat, width, height, depth); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->TransformFeedbackVaryings(program, count, varyings, bufferMode); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform1ui(GLint location, GLuint v0) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform1ui(location, v0); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform1uiv(GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform1uiv(location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform2ui(GLint location, GLuint v0, GLuint v1) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform2ui(location, v0, v1); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform2uiv(GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform2uiv(location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform3ui(location, v0, v1, v2); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform3uiv(GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform3uiv(location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform4ui(location, v0, v1, v2, v3); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform4uiv(GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform4uiv(location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UniformMatrix2x3fv(location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UniformMatrix2x4fv(location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UniformMatrix3x2fv(location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UniformMatrix3x4fv(location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UniformMatrix4x2fv(location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UniformMatrix4x3fv(location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLboolean QOpenGLExtraFunctions::glUnmapBuffer(GLenum target) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLboolean result = d->UnmapBuffer(target); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glVertexAttribDivisor(GLuint index, GLuint divisor) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribDivisor(index, divisor); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribI4i(index, x, y, z, w); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribI4iv(GLuint index, const GLint * v) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribI4iv(index, v); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribI4ui(index, x, y, z, w); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribI4uiv(GLuint index, const GLuint * v) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribI4uiv(index, v); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribIPointer(index, size, type, stride, pointer); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->WaitSync(sync, flags, timeout); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glActiveShaderProgram(GLuint pipeline, GLuint program) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ActiveShaderProgram(pipeline, program); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindImageTexture(unit, texture, level, layered, layer, access, format); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindProgramPipeline(GLuint pipeline) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindProgramPipeline(pipeline); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindVertexBuffer(bindingindex, buffer, offset, stride); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLuint QOpenGLExtraFunctions::glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const* strings) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLuint result = d->CreateShaderProgramv(type, count, strings); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glDeleteProgramPipelines(GLsizei n, const GLuint * pipelines) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DeleteProgramPipelines(n, pipelines); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DispatchCompute(num_groups_x, num_groups_y, num_groups_z); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDispatchComputeIndirect(GLintptr indirect) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DispatchComputeIndirect(indirect); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDrawArraysIndirect(GLenum mode, const void * indirect) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DrawArraysIndirect(mode, indirect); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDrawElementsIndirect(GLenum mode, GLenum type, const void * indirect) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DrawElementsIndirect(mode, type, indirect); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glFramebufferParameteri(GLenum target, GLenum pname, GLint param) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->FramebufferParameteri(target, pname, param); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGenProgramPipelines(GLsizei n, GLuint* pipelines) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GenProgramPipelines(n, pipelines); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetBooleani_v(GLenum target, GLuint index, GLboolean* data) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetBooleani_v(target, index, data); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetFramebufferParameteriv(target, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetMultisamplefv(GLenum pname, GLuint index, GLfloat* val) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetMultisamplefv(pname, index, val); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetProgramInterfaceiv(program, programInterface, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetProgramPipelineInfoLog(pipeline, bufSize, length, infoLog); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetProgramPipelineiv(pipeline, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLuint QOpenGLExtraFunctions::glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar * name) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLuint result = d->GetProgramResourceIndex(program, programInterface, name); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline GLint QOpenGLExtraFunctions::glGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar * name) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLint result = d->GetProgramResourceLocation(program, programInterface, name); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetProgramResourceName(program, programInterface, index, bufSize, length, name); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei* length, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetTexLevelParameterfv(target, level, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetTexLevelParameteriv(target, level, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLboolean QOpenGLExtraFunctions::glIsProgramPipeline(GLuint pipeline) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLboolean result = d->IsProgramPipeline(pipeline); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glMemoryBarrier(GLbitfield barriers) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->MemoryBarrierFunc(barriers); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glMemoryBarrierByRegion(GLbitfield barriers) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->MemoryBarrierByRegion(barriers); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform1f(GLuint program, GLint location, GLfloat v0) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform1f(program, location, v0); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform1fv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform1i(GLuint program, GLint location, GLint v0) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform1i(program, location, v0); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform1iv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform1ui(GLuint program, GLint location, GLuint v0) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform1ui(program, location, v0); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform1uiv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform2f(program, location, v0, v1); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform2fv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform2i(program, location, v0, v1); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform2iv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform2ui(program, location, v0, v1); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform2uiv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform3f(program, location, v0, v1, v2); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform3fv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform3i(program, location, v0, v1, v2); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform3iv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform3ui(program, location, v0, v1, v2); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform3uiv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform4f(program, location, v0, v1, v2, v3); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform4fv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform4i(program, location, v0, v1, v2, v3); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform4iv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform4ui(program, location, v0, v1, v2, v3); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform4uiv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix2fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix2x3fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix2x4fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix3fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix3x2fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix3x4fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix4fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix4x2fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix4x3fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glSampleMaski(GLuint maskNumber, GLbitfield mask) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->SampleMaski(maskNumber, mask); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->TexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UseProgramStages(pipeline, stages, program); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glValidateProgramPipeline(GLuint pipeline) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ValidateProgramPipeline(pipeline); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribBinding(GLuint attribindex, GLuint bindingindex) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribBinding(attribindex, bindingindex); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribFormat(attribindex, size, type, normalized, relativeoffset); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribIFormat(attribindex, size, type, relativeoffset); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexBindingDivisor(GLuint bindingindex, GLuint divisor) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexBindingDivisor(bindingindex, divisor); + Q_OPENGL_FUNCTIONS_DEBUG +} + +QT_END_NAMESPACE + +#endif // QT_NO_OPENGL + +#endif diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 8d298496dfff1f2a169d8d510e9f3bfc7dca50c5..3596591cf65c5768020da1ec43975ccd16bf8586 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -166,7 +166,7 @@ void QOpenGLFramebufferObjectFormat::detach() the format of an OpenGL framebuffer object. By default the format specifies a non-multisample framebuffer object with no - attachments, texture target \c GL_TEXTURE_2D, and internal format \c GL_RGBA8. + depth/stencil attachments, texture target \c GL_TEXTURE_2D, and internal format \c GL_RGBA8. On OpenGL/ES systems, the default internal format is \c GL_RGBA. \sa samples(), attachment(), internalTextureFormat() @@ -436,10 +436,10 @@ namespace } } -void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSize &sz, - QOpenGLFramebufferObject::Attachment attachment, - GLenum texture_target, GLenum internal_format, - GLint samples, bool mipmap) +void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSize &size, + QOpenGLFramebufferObject::Attachment attachment, + GLenum texture_target, GLenum internal_format, + GLint samples, bool mipmap) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); @@ -458,9 +458,13 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi samples = qBound(0, int(samples), int(maxSamples)); } + colorAttachments.append(ColorAttachment(size, internal_format)); + + dsSize = size; + samples = qMax(0, samples); requestedSamples = samples; - size = sz; + target = texture_target; QT_RESET_GLERROR(); // reset error state @@ -471,64 +475,30 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi QOpenGLContextPrivate::get(ctx)->qgl_current_fbo_invalid = true; - GLuint color_buffer = 0; - QT_CHECK_GLERROR(); - // init texture - if (samples == 0) { - initTexture(texture_target, internal_format, size, mipmap); - } else { - GLenum storageFormat = internal_format; - // ES requires a sized format. The older desktop extension does not. Correct the format on ES. - if (ctx->isOpenGLES() && internal_format == GL_RGBA) { - if (funcs.hasOpenGLExtension(QOpenGLExtensions::Sized8Formats)) - storageFormat = GL_RGBA8; - else - storageFormat = GL_RGBA4; - } - - mipmap = false; - funcs.glGenRenderbuffers(1, &color_buffer); - funcs.glBindRenderbuffer(GL_RENDERBUFFER, color_buffer); - funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storageFormat, size.width(), size.height()); - funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_RENDERBUFFER, color_buffer); - QT_CHECK_GLERROR(); - valid = checkFramebufferStatus(ctx); - - if (valid) { - // Query the actual number of samples. This can be greater than the requested - // value since the typically supported values are 0, 4, 8, ..., and the - // requests are mapped to the next supported value. - funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples); - color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc); - } - } format.setTextureTarget(target); - format.setSamples(int(samples)); format.setInternalTextureFormat(internal_format); format.setMipmap(mipmap); - initAttachments(ctx, attachment); + if (samples == 0) + initTexture(0); + else + initColorBuffer(0, &samples); + + format.setSamples(int(samples)); - if (valid) { + initDepthStencilAttachments(ctx, attachment); + + if (valid) fbo_guard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc); - } else { - if (color_buffer_guard) { - color_buffer_guard->free(); - color_buffer_guard = 0; - } else if (texture_guard) { - texture_guard->free(); - texture_guard = 0; - } + else funcs.glDeleteFramebuffers(1, &fbo); - } + QT_CHECK_GLERROR(); } -void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal_format, - const QSize &size, bool mipmap) +void QOpenGLFramebufferObjectPrivate::initTexture(int idx) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); GLuint texture = 0; @@ -541,37 +511,76 @@ void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + ColorAttachment &color(colorAttachments[idx]); + GLuint pixelType = GL_UNSIGNED_BYTE; - if (internal_format == GL_RGB10_A2 || internal_format == GL_RGB10) + if (color.internalFormat == GL_RGB10_A2 || color.internalFormat == GL_RGB10) pixelType = GL_UNSIGNED_INT_2_10_10_10_REV; - funcs.glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, + funcs.glTexImage2D(target, 0, color.internalFormat, color.size.width(), color.size.height(), 0, GL_RGBA, pixelType, NULL); - if (mipmap) { - int width = size.width(); - int height = size.height(); + if (format.mipmap()) { + int width = color.size.width(); + int height = color.size.height(); int level = 0; while (width > 1 || height > 1) { width = qMax(1, width >> 1); height = qMax(1, height >> 1); ++level; - funcs.glTexImage2D(target, level, internal_format, width, height, 0, + funcs.glTexImage2D(target, level, color.internalFormat, width, height, 0, GL_RGBA, pixelType, NULL); } } - funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + idx, target, texture, 0); QT_CHECK_GLERROR(); funcs.glBindTexture(target, 0); valid = checkFramebufferStatus(ctx); - if (valid) - texture_guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc); - else + if (valid) { + color.guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc); + } else { funcs.glDeleteTextures(1, &texture); + } +} + +void QOpenGLFramebufferObjectPrivate::initColorBuffer(int idx, GLint *samples) +{ + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + GLuint color_buffer = 0; + + ColorAttachment &color(colorAttachments[idx]); + + GLenum storageFormat = color.internalFormat; + // ES requires a sized format. The older desktop extension does not. Correct the format on ES. + if (ctx->isOpenGLES() && color.internalFormat == GL_RGBA) { + if (funcs.hasOpenGLExtension(QOpenGLExtensions::Sized8Formats)) + storageFormat = GL_RGBA8; + else + storageFormat = GL_RGBA4; + } + + funcs.glGenRenderbuffers(1, &color_buffer); + funcs.glBindRenderbuffer(GL_RENDERBUFFER, color_buffer); + funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, *samples, storageFormat, color.size.width(), color.size.height()); + funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + idx, + GL_RENDERBUFFER, color_buffer); + + QT_CHECK_GLERROR(); + valid = checkFramebufferStatus(ctx); + if (valid) { + // Query the actual number of samples. This can be greater than the requested + // value since the typically supported values are 0, 4, 8, ..., and the + // requests are mapped to the next supported value. + funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, samples); + color.guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc); + } else { + funcs.glDeleteRenderbuffers(1, &color_buffer); + } } -void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment) +void QOpenGLFramebufferObjectPrivate::initDepthStencilAttachments(QOpenGLContext *ctx, + QOpenGLFramebufferObject::Attachment attachment) { // Use the same sample count for all attachments. format.samples() already contains // the actual number of samples for the color attachment and is not suitable. Use @@ -608,10 +617,10 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer)); if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - GL_DEPTH24_STENCIL8, size.width(), size.height()); + GL_DEPTH24_STENCIL8, dsSize.width(), dsSize.height()); else funcs.glRenderbufferStorage(GL_RENDERBUFFER, - GL_DEPTH24_STENCIL8, size.width(), size.height()); + GL_DEPTH24_STENCIL8, dsSize.width(), dsSize.height()); stencil_buffer = depth_buffer; funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, @@ -636,25 +645,25 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen if (ctx->isOpenGLES()) { if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - GL_DEPTH_COMPONENT24, size.width(), size.height()); + GL_DEPTH_COMPONENT24, dsSize.width(), dsSize.height()); else funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - GL_DEPTH_COMPONENT16, size.width(), size.height()); + GL_DEPTH_COMPONENT16, dsSize.width(), dsSize.height()); } else { funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - GL_DEPTH_COMPONENT, size.width(), size.height()); + GL_DEPTH_COMPONENT, dsSize.width(), dsSize.height()); } } else { if (ctx->isOpenGLES()) { if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) { funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, - size.width(), size.height()); + dsSize.width(), dsSize.height()); } else { funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, - size.width(), size.height()); + dsSize.width(), dsSize.height()); } } else { - funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height()); + funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, dsSize.width(), dsSize.height()); } } funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, @@ -678,9 +687,9 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen #endif if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) - funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, size.width(), size.height()); + funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, dsSize.width(), dsSize.height()); else - funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, size.width(), size.height()); + funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, dsSize.width(), dsSize.height()); funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil_buffer); @@ -756,6 +765,11 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen format, and will be bound to the \c GL_COLOR_ATTACHMENT0 attachment in the framebuffer object. + Multiple render targets are also supported, in case the OpenGL + implementation supports this. Here there will be multiple textures (or, in + case of multisampling, renderbuffers) present and each of them will get + attached to \c GL_COLOR_ATTACHMENT0, \c 1, \c 2, ... + If you want to use a framebuffer object with multisampling enabled as a texture, you first need to copy from it to a regular framebuffer object using QOpenGLContext::blitFramebuffer(). @@ -785,6 +799,16 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen \sa attachment() */ +static inline GLenum effectiveInternalFormat(GLenum internalFormat) +{ + if (!internalFormat) +#ifdef QT_OPENGL_ES_2 + internalFormat = GL_RGBA; +#else + internalFormat = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; +#endif + return internalFormat; +} /*! \fn QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum target) @@ -814,13 +838,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum tar : d_ptr(new QOpenGLFramebufferObjectPrivate) { Q_D(QOpenGLFramebufferObject); - d->init(this, size, NoAttachment, target, -#ifndef QT_OPENGL_ES_2 - QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8 -#else - GL_RGBA -#endif - ); + d->init(this, size, NoAttachment, target, effectiveInternalFormat(0)); } /*! \overload @@ -834,13 +852,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, GLenum : d_ptr(new QOpenGLFramebufferObjectPrivate) { Q_D(QOpenGLFramebufferObject); - d->init(this, QSize(width, height), NoAttachment, target, -#ifndef QT_OPENGL_ES_2 - QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8 -#else - GL_RGBA -#endif - ); + d->init(this, QSize(width, height), NoAttachment, target, effectiveInternalFormat(0)); } /*! \overload @@ -877,7 +889,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, const buffer of the given \a width and \a height. The \a attachment parameter describes the depth/stencil buffer - configuration, \a target the texture target and \a internal_format + configuration, \a target the texture target and \a internalFormat the internal texture format. The default texture target is \c GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8 for desktop OpenGL and \c GL_RGBA for OpenGL/ES. @@ -885,17 +897,11 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, const \sa size(), texture(), attachment() */ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attachment attachment, - GLenum target, GLenum internal_format) + GLenum target, GLenum internalFormat) : d_ptr(new QOpenGLFramebufferObjectPrivate) { Q_D(QOpenGLFramebufferObject); - if (!internal_format) -#ifdef QT_OPENGL_ES_2 - internal_format = GL_RGBA; -#else - internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; -#endif - d->init(this, QSize(width, height), attachment, target, internal_format); + d->init(this, QSize(width, height), attachment, target, effectiveInternalFormat(internalFormat)); } /*! \overload @@ -904,7 +910,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attach buffer of the given \a size. The \a attachment parameter describes the depth/stencil buffer - configuration, \a target the texture target and \a internal_format + configuration, \a target the texture target and \a internalFormat the internal texture format. The default texture target is \c GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8 for desktop OpenGL and \c GL_RGBA for OpenGL/ES. @@ -912,17 +918,11 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attach \sa size(), texture(), attachment() */ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, Attachment attachment, - GLenum target, GLenum internal_format) + GLenum target, GLenum internalFormat) : d_ptr(new QOpenGLFramebufferObjectPrivate) { Q_D(QOpenGLFramebufferObject); - if (!internal_format) -#ifdef QT_OPENGL_ES_2 - internal_format = GL_RGBA; -#else - internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; -#endif - d->init(this, size, attachment, target, internal_format); + d->init(this, size, attachment, target, effectiveInternalFormat(internalFormat)); } /*! @@ -936,10 +936,12 @@ QOpenGLFramebufferObject::~QOpenGLFramebufferObject() if (isBound()) release(); - if (d->texture_guard) - d->texture_guard->free(); - if (d->color_buffer_guard) - d->color_buffer_guard->free(); + foreach (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color, d->colorAttachments) { + if (color.guard) + color.guard->free(); + } + d->colorAttachments.clear(); + if (d->depth_buffer_guard) d->depth_buffer_guard->free(); if (d->stencil_buffer_guard && d->stencil_buffer_guard != d->depth_buffer_guard) @@ -948,6 +950,70 @@ QOpenGLFramebufferObject::~QOpenGLFramebufferObject() d->fbo_guard->free(); } +/*! + Creates and attaches an additional texture or renderbuffer of size \a width + and \a height. + + There is always an attachment at GL_COLOR_ATTACHMENT0. Call this function + to set up additional attachments at GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, ... + + When \a internalFormat is not \c 0, it specifies the internal format of the + texture or renderbuffer. Otherwise a default of GL_RGBA or GL_RGBA8 is + used. + + \note This is only functional when multiple render targets are supported by + the OpenGL implementation. When that is not the case, the function will not + add any additional color attachments. Call + QOpenGLFunctions::hasOpenGLFeature() with + QOpenGLFunctions::MultipleRenderTargets at runtime to check if MRT is + supported. + + \note The internal format of the color attachments may differ but there may + be limitations on the supported combinations, depending on the drivers. + + \note The size of the color attachments may differ but rendering is limited + to the area that fits all the attachments, according to the OpenGL + specification. Some drivers may not be fully conformant in this respect, + however. + + \since 5.6 + */ +void QOpenGLFramebufferObject::addColorAttachment(const QSize &size, GLenum internalFormat) +{ + Q_D(QOpenGLFramebufferObject); + + if (!QOpenGLContext::currentContext()->functions()->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) { + qWarning("Multiple render targets not supported, ignoring extra color attachment request"); + return; + } + + QOpenGLFramebufferObjectPrivate::ColorAttachment color(size, effectiveInternalFormat(internalFormat)); + d->colorAttachments.append(color); + const int idx = d->colorAttachments.count() - 1; + + if (d->requestedSamples == 0) { + d->initTexture(idx); + } else { + GLint samples = d->requestedSamples; + d->initColorBuffer(idx, &samples); + } +} + +/*! \overload + + Creates and attaches an additional texture or renderbuffer of size \a width and \a height. + + When \a internalFormat is not \c 0, it specifies the internal format of the texture or + renderbuffer. Otherwise a default of GL_RGBA or GL_RGBA8 is used. + + \since 5.6 + */ +void QOpenGLFramebufferObject::addColorAttachment(int width, int height, GLenum internalFormat) +{ + addColorAttachment(QSize(width, height), internalFormat); +} + /*! \fn bool QOpenGLFramebufferObject::isValid() const @@ -1002,10 +1068,16 @@ bool QOpenGLFramebufferObject::bind() QOpenGLContextPrivate::get(current)->qgl_current_fbo_invalid = true; - if (d->texture_guard || d->format.samples() != 0) - d->valid = d->checkFramebufferStatus(current); - else - d->initTexture(d->format.textureTarget(), d->format.internalTextureFormat(), d->size, d->format.mipmap()); + if (d->format.samples() == 0) { + // Create new textures to replace the ones stolen via takeTexture(). + for (int i = 0; i < d->colorAttachments.count(); ++i) { + if (!d->colorAttachments[i].guard) + d->initTexture(i); + } + } + + d->valid = d->checkFramebufferStatus(current); + return d->valid; } @@ -1052,12 +1124,36 @@ bool QOpenGLFramebufferObject::release() If a multisample framebuffer object is used then the value returned from this function will be invalid. - \sa takeTexture() + When multiple textures are attached, the return value is the ID of + the first one. + + \sa takeTexture(), textures() */ GLuint QOpenGLFramebufferObject::texture() const { Q_D(const QOpenGLFramebufferObject); - return d->texture_guard ? d->texture_guard->id() : 0; + return d->colorAttachments[0].guard ? d->colorAttachments[0].guard->id() : 0; +} + +/*! + Returns the texture id for all attached textures. + + If a multisample framebuffer object is used, then an empty vector is returned. + + \since 5.6 + + \sa takeTextures(), texture() +*/ +QVector<GLuint> QOpenGLFramebufferObject::textures() const +{ + Q_D(const QOpenGLFramebufferObject); + QVector<GLuint> ids; + if (d->format.samples() != 0) + return ids; + ids.reserve(d->colorAttachments.count()); + foreach (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color, d->colorAttachments) + ids.append(color.guard ? color.guard->id() : 0); + return ids; } /*! @@ -1076,34 +1172,72 @@ GLuint QOpenGLFramebufferObject::texture() const \since 5.3 - \sa texture(), bind(), release() + \sa texture(), bind(), release(), takeTextures() */ GLuint QOpenGLFramebufferObject::takeTexture() +{ + return takeTexture(0); +} + +/*! \overload + + Returns the texture id for the texture attached to the color attachment of + index \a colorAttachmentIndex of this framebuffer object. The ownership of + the texture is transferred to the caller. + + When \a colorAttachmentIndex is \c 0, the behavior is identical to the + parameter-less variant of this function. + + If the framebuffer object is currently bound, an implicit release() + will be done. During the next call to bind() a new texture will be + created. + + If a multisample framebuffer object is used, then there is no + texture and the return value from this function will be invalid. + Similarly, incomplete framebuffer objects will also return 0. + + \since 5.6 + */ +GLuint QOpenGLFramebufferObject::takeTexture(int colorAttachmentIndex) { Q_D(QOpenGLFramebufferObject); GLuint id = 0; - if (isValid() && d->texture_guard) { + if (isValid() && d->format.samples() == 0 && d->colorAttachments.count() > colorAttachmentIndex) { QOpenGLContext *current = QOpenGLContext::currentContext(); if (current && current->shareGroup() == d->fbo_guard->group() && isBound()) release(); - id = d->texture_guard->id(); + id = d->colorAttachments[colorAttachmentIndex].guard ? d->colorAttachments[colorAttachmentIndex].guard->id() : 0; // Do not call free() on texture_guard, just null it out. // This way the texture will not be deleted when the guard is destroyed. - d->texture_guard = 0; + d->colorAttachments[colorAttachmentIndex].guard = 0; } return id; } /*! - \fn QSize QOpenGLFramebufferObject::size() const + \return the size of the color and depth/stencil attachments attached to + this framebuffer object. +*/ +QSize QOpenGLFramebufferObject::size() const +{ + Q_D(const QOpenGLFramebufferObject); + return d->dsSize; +} - Returns the size of the texture attached to this framebuffer +/*! + \return the sizes of all color attachments attached to this framebuffer object. + + \since 5.6 */ -QSize QOpenGLFramebufferObject::size() const +QVector<QSize> QOpenGLFramebufferObject::sizes() const { Q_D(const QOpenGLFramebufferObject); - return d->size; + QVector<QSize> sz; + sz.reserve(d->colorAttachments.size()); + foreach (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color, d->colorAttachments) + sz.append(color.size); + return sz; } /*! @@ -1231,6 +1365,37 @@ Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, */ QImage QOpenGLFramebufferObject::toImage(bool flipped) const +{ + return toImage(flipped, 0); +} + +/*! + \fn QImage QOpenGLFramebufferObject::toImage() const + \overload + + Returns the contents of this framebuffer object as a QImage. This method flips + the image from OpenGL coordinates to raster coordinates. +*/ +// ### Qt 6: Remove this method and make it a default argument instead. +QImage QOpenGLFramebufferObject::toImage() const +{ + return toImage(true, 0); +} + +/*! \overload + + Returns the contents of the color attachment of index \a + colorAttachmentIndex of this framebuffer object as a QImage. This method + flips the image from OpenGL coordinates to raster coordinates when \a + flipped is set to \c true. + + \note This overload is only fully functional when multiple render targets are + supported by the OpenGL implementation. When that is not the case, only one + color attachment will be set up. + + \since 5.6 +*/ +QImage QOpenGLFramebufferObject::toImage(bool flipped, int colorAttachmentIndex) const { Q_D(const QOpenGLFramebufferObject); if (!d->valid) @@ -1242,6 +1407,11 @@ QImage QOpenGLFramebufferObject::toImage(bool flipped) const return QImage(); } + if (d->colorAttachments.count() <= colorAttachmentIndex) { + qWarning("QOpenGLFramebufferObject::toImage() called for missing color attachment"); + return QImage(); + } + GLuint prevFbo = 0; ctx->functions()->glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *) &prevFbo); @@ -1249,16 +1419,33 @@ QImage QOpenGLFramebufferObject::toImage(bool flipped) const const_cast<QOpenGLFramebufferObject *>(this)->bind(); QImage image; + QOpenGLExtraFunctions *extraFuncs = ctx->extraFunctions(); // qt_gl_read_framebuffer doesn't work on a multisample FBO if (format().samples() != 0) { - QOpenGLFramebufferObject temp(size(), QOpenGLFramebufferObjectFormat()); - QRect rect(QPoint(0, 0), size()); - blitFramebuffer(&temp, rect, const_cast<QOpenGLFramebufferObject *>(this), rect); - - image = temp.toImage(flipped); + if (extraFuncs->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) { + QOpenGLFramebufferObject temp(d->colorAttachments[colorAttachmentIndex].size, QOpenGLFramebufferObjectFormat()); + blitFramebuffer(&temp, rect, const_cast<QOpenGLFramebufferObject *>(this), rect, + GL_COLOR_BUFFER_BIT, GL_NEAREST, + colorAttachmentIndex, 0); + image = temp.toImage(flipped); + } else { + QOpenGLFramebufferObject temp(size(), QOpenGLFramebufferObjectFormat()); + blitFramebuffer(&temp, rect, const_cast<QOpenGLFramebufferObject *>(this), rect); + image = temp.toImage(flipped); + } } else { - image = qt_gl_read_framebuffer(d->size, format().internalTextureFormat(), true, flipped); + if (extraFuncs->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) { + extraFuncs->glReadBuffer(GL_COLOR_ATTACHMENT0 + colorAttachmentIndex); + image = qt_gl_read_framebuffer(d->colorAttachments[colorAttachmentIndex].size, + d->colorAttachments[colorAttachmentIndex].internalFormat, + true, flipped); + extraFuncs->glReadBuffer(GL_COLOR_ATTACHMENT0); + } else { + image = qt_gl_read_framebuffer(d->colorAttachments[0].size, + d->colorAttachments[0].internalFormat, + true, flipped); + } } if (prevFbo != d->fbo()) @@ -1267,19 +1454,6 @@ QImage QOpenGLFramebufferObject::toImage(bool flipped) const return image; } -/*! - \fn QImage QOpenGLFramebufferObject::toImage() const - \overload - - Returns the contents of this framebuffer object as a QImage. This method flips - the image from OpenGL coordinates to raster coordinates. -*/ -// ### Qt 6: Remove this method and make it a default argument instead. -QImage QOpenGLFramebufferObject::toImage() const -{ - return toImage(true); -} - /*! \fn bool QOpenGLFramebufferObject::bindDefault() @@ -1366,7 +1540,7 @@ void QOpenGLFramebufferObject::setAttachment(QOpenGLFramebufferObject::Attachmen #endif d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo()); QOpenGLContextPrivate::get(current)->qgl_current_fbo_invalid = true; - d->initAttachments(current, attachment); + d->initDepthStencilAttachments(current, attachment); } /*! @@ -1428,6 +1602,18 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, buffers, filter); } +/*! \overload + * + Convenience overload to blit between two framebuffer objects. +*/ +void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect, + QOpenGLFramebufferObject *source, const QRect &sourceRect, + GLbitfield buffers, + GLenum filter) +{ + blitFramebuffer(target, targetRect, source, sourceRect, buffers, filter, 0, 0); +} + /*! Blits from the \a sourceRect rectangle in the \a source framebuffer object to the \a targetRect rectangle in the \a target framebuffer object. @@ -1456,12 +1642,18 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, \note The scissor test will restrict the blit area if enabled. + When multiple render targets are in use, \a readColorAttachmentIndex and \a + drawColorAttachmentIndex specify the index of the color attachments in the + source and destination framebuffers. + \sa hasOpenGLFramebufferBlit() */ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect, - QOpenGLFramebufferObject *source, const QRect &sourceRect, - GLbitfield buffers, - GLenum filter) + QOpenGLFramebufferObject *source, const QRect &sourceRect, + GLbitfield buffers, + GLenum filter, + int readColorAttachmentIndex, + int drawColorAttachmentIndex) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); if (!ctx) @@ -1489,10 +1681,21 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, source ? source->handle() : defaultFboId); extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target ? target->handle() : defaultFboId); + if (extensions.hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) { + extensions.glReadBuffer(GL_COLOR_ATTACHMENT0 + readColorAttachmentIndex); + if (target) { + GLenum drawBuf = GL_COLOR_ATTACHMENT0 + drawColorAttachmentIndex; + extensions.glDrawBuffers(1, &drawBuf); + } + } + extensions.glBlitFramebuffer(sx0, sy0, sx1, sy1, tx0, ty0, tx1, ty1, buffers, filter); + if (extensions.hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) + extensions.glReadBuffer(GL_COLOR_ATTACHMENT0); + ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, prevFbo); // sets both READ and DRAW } diff --git a/src/gui/opengl/qopenglframebufferobject.h b/src/gui/opengl/qopenglframebufferobject.h index 4ce0ee26cb7e635c6975c26563ad1c44f0ab25c9..cead4ad10f4ab680421a51400f7f2d0d7359a001 100644 --- a/src/gui/opengl/qopenglframebufferobject.h +++ b/src/gui/opengl/qopenglframebufferobject.h @@ -63,15 +63,18 @@ public: QOpenGLFramebufferObject(int width, int height, GLenum target = GL_TEXTURE_2D); QOpenGLFramebufferObject(const QSize &size, Attachment attachment, - GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0); + GLenum target = GL_TEXTURE_2D, GLenum internalFormat = 0); QOpenGLFramebufferObject(int width, int height, Attachment attachment, - GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0); + GLenum target = GL_TEXTURE_2D, GLenum internalFormat = 0); QOpenGLFramebufferObject(const QSize &size, const QOpenGLFramebufferObjectFormat &format); QOpenGLFramebufferObject(int width, int height, const QOpenGLFramebufferObjectFormat &format); virtual ~QOpenGLFramebufferObject(); + void addColorAttachment(const QSize &size, GLenum internalFormat = 0); + void addColorAttachment(int width, int height, GLenum internalFormat = 0); + QOpenGLFramebufferObjectFormat format() const; bool isValid() const; @@ -83,12 +86,19 @@ public: int height() const { return size().height(); } GLuint texture() const; + QVector<GLuint> textures() const; + GLuint takeTexture(); + GLuint takeTexture(int colorAttachmentIndex); + QSize size() const; + QVector<QSize> sizes() const; + QImage toImage() const; QImage toImage(bool flipped) const; - Attachment attachment() const; + QImage toImage(bool flipped, int colorAttachmentIndex) const; + Attachment attachment() const; void setAttachment(Attachment attachment); GLuint handle() const; @@ -98,6 +108,12 @@ public: static bool hasOpenGLFramebufferObjects(); static bool hasOpenGLFramebufferBlit(); + static void blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect, + QOpenGLFramebufferObject *source, const QRect &sourceRect, + GLbitfield buffers, + GLenum filter, + int readColorAttachmentIndex, + int drawColorAttachmentIndex); static void blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect, QOpenGLFramebufferObject *source, const QRect &sourceRect, GLbitfield buffers = GL_COLOR_BUFFER_BIT, diff --git a/src/gui/opengl/qopenglframebufferobject_p.h b/src/gui/opengl/qopenglframebufferobject_p.h index 7f0068dfc45102c955f6d19f0decfbe60425060d..6c45fda57f367a26f08f10b0c58d5ad9fb8e598c 100644 --- a/src/gui/opengl/qopenglframebufferobject_p.h +++ b/src/gui/opengl/qopenglframebufferobject_p.h @@ -102,32 +102,41 @@ public: class QOpenGLFramebufferObjectPrivate { public: - QOpenGLFramebufferObjectPrivate() : fbo_guard(0), texture_guard(0), depth_buffer_guard(0) - , stencil_buffer_guard(0), color_buffer_guard(0) + QOpenGLFramebufferObjectPrivate() : fbo_guard(0), depth_buffer_guard(0) + , stencil_buffer_guard(0) , valid(false) {} ~QOpenGLFramebufferObjectPrivate() {} - void init(QOpenGLFramebufferObject *q, const QSize& sz, + void init(QOpenGLFramebufferObject *q, const QSize &size, QOpenGLFramebufferObject::Attachment attachment, - GLenum internal_format, GLenum texture_target, + GLenum texture_target, GLenum internal_format, GLint samples = 0, bool mipmap = false); - void initTexture(GLenum target, GLenum internal_format, const QSize &size, bool mipmap); - void initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment); + void initTexture(int idx); + void initColorBuffer(int idx, GLint *samples); + void initDepthStencilAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment); bool checkFramebufferStatus(QOpenGLContext *ctx) const; QOpenGLSharedResourceGuard *fbo_guard; - QOpenGLSharedResourceGuard *texture_guard; QOpenGLSharedResourceGuard *depth_buffer_guard; QOpenGLSharedResourceGuard *stencil_buffer_guard; - QOpenGLSharedResourceGuard *color_buffer_guard; GLenum target; - QSize size; + QSize dsSize; QOpenGLFramebufferObjectFormat format; int requestedSamples; uint valid : 1; QOpenGLFramebufferObject::Attachment fbo_attachment; QOpenGLExtensions funcs; + struct ColorAttachment { + ColorAttachment() : internalFormat(0), guard(0) { } + ColorAttachment(const QSize &size, GLenum internalFormat) + : size(size), internalFormat(internalFormat), guard(0) { } + QSize size; + GLenum internalFormat; + QOpenGLSharedResourceGuard *guard; + }; + QVector<ColorAttachment> colorAttachments; + inline GLuint fbo() const { return fbo_guard ? fbo_guard->id() : 0; } }; diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index b9d674fd3bc6ca6d3e96fa27be7630f28241ded9..668eaa9a89f6193c7f7df13149bd1c9e65bc25a5 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -32,12 +32,14 @@ ****************************************************************************/ #include "qopenglfunctions.h" +#include "qopenglextrafunctions.h" #include "qopenglextensions_p.h" #include "qdebug.h" #include <QtGui/private/qopenglcontext_p.h> #include <QtGui/private/qopengl_p.h> #include <QtGui/private/qguiapplication_p.h> #include <qpa/qplatformintegration.h> +#include <QtCore/qloggingcategory.h> #ifdef Q_OS_IOS #include <dlfcn.h> @@ -49,6 +51,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcGLES3, "qt.opengl.es3") + /*! \class QOpenGLFunctions \brief The QOpenGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API. @@ -155,6 +159,8 @@ QT_BEGIN_NAMESPACE QOpenGLFunctions funcs(QOpenGLContext::currentContext()); bool npot = funcs.hasOpenGLFeature(QOpenGLFunctions::NPOTTextures); \endcode + + \sa QOpenGLContext, QSurfaceFormat */ /*! @@ -178,6 +184,7 @@ QT_BEGIN_NAMESPACE \value NPOTTextureRepeat Non power of two textures can use GL_REPEAT as wrap parameter. \value FixedFunctionPipeline The fixed function pipeline is available. \value TextureRGFormats The GL_RED and GL_RG texture formats are available. + \value MultipleRenderTargets Multiple color attachments to framebuffer objects are available. */ // Hidden private fields for additional extension data. @@ -251,12 +258,11 @@ QOpenGLFunctions::QOpenGLFunctions(QOpenGLContext *context) } QOpenGLExtensions::QOpenGLExtensions() - : QOpenGLFunctions() { } QOpenGLExtensions::QOpenGLExtensions(QOpenGLContext *context) - : QOpenGLFunctions(context) + : QOpenGLExtraFunctions(context) { } @@ -270,7 +276,7 @@ static int qt_gl_resolve_features() { QOpenGLContext *ctx = QOpenGLContext::currentContext(); if (ctx->isOpenGLES()) { - // OpenGL ES 2 + // OpenGL ES int features = QOpenGLFunctions::Multitexture | QOpenGLFunctions::Shaders | QOpenGLFunctions::Buffers | @@ -289,8 +295,14 @@ static int qt_gl_resolve_features() if (extensions.match("GL_OES_texture_npot")) features |= QOpenGLFunctions::NPOTTextures | QOpenGLFunctions::NPOTTextureRepeat; - if (ctx->format().majorVersion() >= 3 || extensions.match("GL_EXT_texture_rg")) - features |= QOpenGLFunctions::TextureRGFormats; + if (ctx->format().majorVersion() >= 3 || extensions.match("GL_EXT_texture_rg")) { + // Mesa's GLES implementation (as of 10.6.0) is unable to handle this, even though it provides 3.0. + const char *renderer = reinterpret_cast<const char *>(ctx->functions()->glGetString(GL_RENDERER)); + if (!(renderer && strstr(renderer, "Mesa"))) + features |= QOpenGLFunctions::TextureRGFormats; + } + if (ctx->format().majorVersion() >= 3) + features |= QOpenGLFunctions::MultipleRenderTargets; return features; } else { // OpenGL @@ -299,10 +311,9 @@ static int qt_gl_resolve_features() QOpenGLExtensionMatcher extensions; if (format.majorVersion() >= 3) - features |= QOpenGLFunctions::Framebuffers; - else if (extensions.match("GL_EXT_framebuffer_object") || - extensions.match("GL_ARB_framebuffer_object")) - features |= QOpenGLFunctions::Framebuffers; + features |= QOpenGLFunctions::Framebuffers | QOpenGLFunctions::MultipleRenderTargets; + else if (extensions.match("GL_EXT_framebuffer_object") || extensions.match("GL_ARB_framebuffer_object")) + features |= QOpenGLFunctions::Framebuffers | QOpenGLFunctions::MultipleRenderTargets; if (format.majorVersion() >= 2) { features |= QOpenGLFunctions::BlendColor | @@ -419,11 +430,14 @@ static int qt_gl_resolve_extensions() // We don't match GL_APPLE_texture_format_BGRA8888 here because it has different semantics. if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888")) extensions |= QOpenGLExtensions::BGRATextureFormat; - if (extensionMatcher.match("GL_EXT_discard_framebuffer")) extensions |= QOpenGLExtensions::DiscardFramebuffer; + if (extensionMatcher.match("GL_EXT_texture_norm16")) + extensions |= QOpenGLExtensions::Sized16Formats; } else { - extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer; + extensions |= QOpenGLExtensions::ElementIndexUint + | QOpenGLExtensions::MapBuffer + | QOpenGLExtensions::Sized16Formats; if (format.version() >= qMakePair(1, 2)) extensions |= QOpenGLExtensions::BGRATextureFormat; @@ -2117,6 +2131,9 @@ public: template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10> ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10); + template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11> + ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11); + private: FuncType Base::*funcPointerName; FuncType fallbackFuncPointer; @@ -2168,6 +2185,9 @@ public: template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10> void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10); + template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11> + void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11); + private: FuncType Base::*funcPointerName; FuncType fallbackFuncPointer; @@ -2417,6 +2437,14 @@ void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2, P3 p3, P4 (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } +template <typename Base, typename FuncType, int Policy> template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11> +void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11) +{ + RESOLVER_COMMON_VOID + + (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); +} + template <typename ReturnType, int Policy, typename Base, typename FuncType> Resolver<Base, FuncType, Policy, ReturnType> functionResolverWithFallback(FuncType Base::*func, FuncType fallback, const char *name, const char *alternate = 0) { @@ -2429,7 +2457,7 @@ Resolver<Base, FuncType, Policy, ReturnType> functionResolver(FuncType Base::*fu return Resolver<Base, FuncType, Policy, ReturnType>(func, 0, name, alternate); } -} +} // namespace #define RESOLVE_FUNC(RETURN_TYPE, POLICY, NAME) \ return functionResolver<RETURN_TYPE, POLICY>(&QOpenGLExtensionsPrivate::NAME, "gl" #NAME) @@ -3197,75 +3225,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribPointer(GLuint indx, GL #endif // !QT_OPENGL_ES_2 -// Functions part of the OpenGL ES 3.0+ standard need special handling. These, -// just like the 2.0 functions, are not guaranteed to be resolvable via -// eglGetProcAddress or similar. Calling them directly is, unlike the 2.0 -// functions, not feasible because one may build the binaries on a GLES3-capable -// system and then deploy on a GLES2-only system that does not have these -// symbols. Until ES3 gets universally available, they have to be dlsym'ed. - -Q_GLOBAL_STATIC(QOpenGLES3Helper, qgles3Helper) - -bool QOpenGLES3Helper::init() -{ -#ifndef Q_OS_IOS -# ifdef Q_OS_WIN -# ifndef QT_DEBUG - m_gl.setFileName(QStringLiteral("libGLESv2")); -# else - m_gl.setFileName(QStringLiteral("libGLESv2d")); -# endif -# else - m_gl.setFileName(QStringLiteral("GLESv2")); -# endif // Q_OS_WIN - return m_gl.load(); -#else - return true; -#endif // Q_OS_IOS -} - -QFunctionPointer QOpenGLES3Helper::resolve(const char *name) -{ -#ifdef Q_OS_IOS - return QFunctionPointer(dlsym(RTLD_DEFAULT, name)); -#else - return m_gl.resolve(name); -#endif -} - -QOpenGLES3Helper::QOpenGLES3Helper() -{ - if (init()) { - MapBufferRange = (GLvoid* (QOPENGLF_APIENTRYP)(GLenum, qopengl_GLintptr, qopengl_GLsizeiptr, GLbitfield)) resolve("glMapBufferRange"); - UnmapBuffer = (GLboolean (QOPENGLF_APIENTRYP)(GLenum)) resolve("glUnmapBuffer"); - BlitFramebuffer = (void (QOPENGLF_APIENTRYP)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) resolve("glBlitFramebuffer"); - RenderbufferStorageMultisample = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)) resolve("glRenderbufferStorageMultisample"); - - GenVertexArrays = (void (QOPENGLF_APIENTRYP)(GLsizei, GLuint *)) resolve("glGenVertexArrays"); - DeleteVertexArrays = (void (QOPENGLF_APIENTRYP)(GLsizei, const GLuint *)) resolve("glDeleteVertexArrays"); - BindVertexArray = (void (QOPENGLF_APIENTRYP)(GLuint)) resolve("glBindVertexArray"); - IsVertexArray = (GLboolean (QOPENGLF_APIENTRYP)(GLuint)) resolve("glIsVertexArray"); - - TexImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) resolve("glTexImage3D"); - TexSubImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) resolve("glTexSubImage3D"); - CompressedTexImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) resolve("glCompressedTexImage3D"); - CompressedTexSubImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) resolve("glCompressedTexSubImage3D"); - - TexStorage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei)) resolve("glTexStorage3D"); - TexStorage2D = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)) resolve("glTexStorage2D"); - - if (!MapBufferRange || !GenVertexArrays || !TexImage3D || !TexStorage3D) - qFatal("OpenGL ES 3.0 entry points not found"); - } else { - qFatal("Failed to load libGLESv2"); - } -} - -static inline bool isES3() -{ - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - return ctx->isOpenGLES() && ctx->format().majorVersion() >= 3; -} +// Extensions not standard in any ES version static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBuffer(GLenum target, GLenum access) { @@ -3273,7 +3233,8 @@ static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBuffer(GLenum target, GLenum // differentiate between glUnmapBufferOES and glUnmapBuffer causes extra // headache. QOpenGLBuffer::map() will handle this automatically, while direct // calls are better off with migrating to the standard glMapBufferRange. - if (isES3()) { + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (ctx->isOpenGLES() && ctx->format().majorVersion() >= 3) { qWarning("QOpenGLFunctions: glMapBuffer is not available in OpenGL ES 3.0 and up. Use glMapBufferRange instead."); return 0; } else { @@ -3281,44 +3242,6 @@ static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBuffer(GLenum target, GLenum } } -static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBufferRange(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access) -{ - if (isES3()) - return qgles3Helper()->MapBufferRange(target, offset, length, access); - else - RESOLVE_FUNC(GLvoid *, 0, MapBufferRange)(target, offset, length, access); -} - -static GLboolean QOPENGLF_APIENTRY qopenglfResolveUnmapBuffer(GLenum target) -{ - if (isES3()) - return qgles3Helper()->UnmapBuffer(target); - else - RESOLVE_FUNC(GLboolean, ResolveOES, UnmapBuffer)(target); -} - -static void QOPENGLF_APIENTRY qopenglfResolveBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) -{ - if (isES3()) - qgles3Helper()->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - else - RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, BlitFramebuffer) - (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); -} - -static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLenum target, GLsizei samples, - GLenum internalFormat, - GLsizei width, GLsizei height) -{ - if (isES3()) - qgles3Helper()->RenderbufferStorageMultisample(target, samples, internalFormat, width, height); - else - RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, RenderbufferStorageMultisample) - (target, samples, internalFormat, width, height); -} - static void QOPENGLF_APIENTRY qopenglfResolveGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data) { RESOLVE_FUNC_VOID(ResolveEXT, GetBufferSubData) @@ -3559,15 +3482,4114 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *) #endif // !QT_OPENGL_ES_2 } -QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx) - : QOpenGLFunctionsPrivate(ctx), - flushVendorChecked(false) -{ - MapBuffer = qopenglfResolveMapBuffer; - MapBufferRange = qopenglfResolveMapBufferRange; - UnmapBuffer = qopenglfResolveUnmapBuffer; - BlitFramebuffer = qopenglfResolveBlitFramebuffer; - RenderbufferStorageMultisample = qopenglfResolveRenderbufferStorageMultisample; +/*! + \class QOpenGLExtraFunctions + \brief The QOpenGLExtraFunctions class provides cross-platform access to the OpenGL ES 3.0 and 3.1 API. + \since 5.6 + \ingroup painting-3D + \inmodule QtGui + + This subclass of QOpenGLFunctions includes the OpenGL ES 3.0 and 3.1 + functions. These will only work when an OpenGL ES 3.0 or 3.1 context, or an + OpenGL context of a version containing the functions in question either in + core or as extension, is in use. This allows developing GLES 3.0 and 3.1 + applications in a cross-platform manner: development can happen on a desktop + platform with OpenGL 3.x or 4.x, deploying to a real GLES 3.1 device later + on will require no or minimal changes to the application. + + \note This class is different from the versioned OpenGL wrappers, for + instance QOpenGLFunctions_3_2_Core. The versioned function wrappers target a + given version and profile of OpenGL. They are therefore not suitable for + cross-OpenGL-OpenGLES development. + */ + +/*! + \fn void QOpenGLExtraFunctions::glBeginQuery(GLenum target, GLuint id) + + Convenience function that calls glBeginQuery(\a target, \a id). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBeginQuery.xml}{glBeginQuery()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBeginTransformFeedback(GLenum primitiveMode) + + Convenience function that calls glBeginTransformFeedback(\a primitiveMode). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBeginTransformFeedback.xml}{glBeginTransformFeedback()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindBufferBase(GLenum target, GLuint index, GLuint buffer) + + Convenience function that calls glBindBufferBase(\a target, \a index, \a buffer). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindBufferBase.xml}{glBindBufferBase()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) + + Convenience function that calls glBindBufferRange(\a target, \a index, \a buffer, \a offset, \a size). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindBufferRange.xml}{glBindBufferRange()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindSampler(GLuint unit, GLuint sampler) + + Convenience function that calls glBindSampler(\a unit, \a sampler). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindSampler.xml}{glBindSampler()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindTransformFeedback(GLenum target, GLuint id) + + Convenience function that calls glBindTransformFeedback(\a target, \a id). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindTransformFeedback.xml}{glBindTransformFeedback()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindVertexArray(GLuint array) + + Convenience function that calls glBindVertexArray(\a array). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindVertexArray.xml}{glBindVertexArray()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) + + Convenience function that calls glBlitFramebuffer(\a srcX0, \a srcY0, \a srcX1, \a srcY1, \a dstX0, \a dstY0, \a dstX1, \a dstY1, \a mask, \a filter). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBlitFramebuffer.xml}{glBlitFramebuffer()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) + + Convenience function that calls glClearBufferfi(\a buffer, \a drawbuffer, \a depth, \a stencil). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glClearBufferfi.xml}{glClearBufferfi()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat * value) + + Convenience function that calls glClearBufferfv(\a buffer, \a drawbuffer, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glClearBufferfv.xml}{glClearBufferfv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint * value) + + Convenience function that calls glClearBufferiv(\a buffer, \a drawbuffer, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glClearBufferiv.xml}{glClearBufferiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint * value) + + Convenience function that calls glClearBufferuiv(\a buffer, \a drawbuffer, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glClearBufferuiv.xml}{glClearBufferuiv()}. +*/ + +/*! + \fn GLenum QOpenGLExtraFunctions::glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) + + Convenience function that calls glClientWaitSync(\a sync, \a flags, \a timeout). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glClientWaitSync.xml}{glClientWaitSync()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data) + + Convenience function that calls glCompressedTexImage3D(\a target, \a level, \a internalformat, \a width, \a height, \a depth, \a border, \a imageSize, \a data). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glCompressedTexImage3D.xml}{glCompressedTexImage3D()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data) + + Convenience function that calls glCompressedTexSubImage3D(\a target, \a level, \a xoffset, \a yoffset, \a zoffset, \a width, \a height, \a depth, \a format, \a imageSize, \a data). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glCompressedTexSubImage3D.xml}{glCompressedTexSubImage3D()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) + + Convenience function that calls glCopyBufferSubData(\a readTarget, writeTarget, \a readOffset, \a writeOffset, \a size). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glCopyBufferSubData.xml}{glCopyBufferSubData()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) + + Convenience function that calls glCopyTexSubImage3D(\a target, \a level, \a xoffset, \a yoffset, \a zoffset, \a x, \a y, \a width, \a height). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glCopyTexSubImage3D.xml}{glCopyTexSubImage3D()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDeleteQueries(GLsizei n, const GLuint * ids) + + Convenience function that calls glDeleteQueries(\a n, \a ids). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteQueries.xml}{glDeleteQueries()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDeleteSamplers(GLsizei count, const GLuint * samplers) + + Convenience function that calls glDeleteSamplers(\a count, \a samplers). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteSamplers.xml}{glDeleteSamplers()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDeleteSync(GLsync sync) + + Convenience function that calls glDeleteSync(\a sync). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteSync.xml}{glDeleteSync()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDeleteTransformFeedbacks(GLsizei n, const GLuint * ids) + + Convenience function that calls glDeleteTransformFeedbacks(\a n, \a ids). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteTransformFeedbacks.xml}{glDeleteTransformFeedbacks()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDeleteVertexArrays(GLsizei n, const GLuint * arrays) + + Convenience function that calls glDeleteVertexArrays(\a n, \a arrays). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteVertexArrays.xml}{glDeleteVertexArrays()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) + + Convenience function that calls glDrawArraysInstanced(\a mode, \a first, \a count, \a instancecount). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawArraysInstanced.xml}{glDrawArraysInstanced()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDrawBuffers(GLsizei n, const GLenum * bufs) + + Convenience function that calls glDrawBuffers(\a n, \a bufs). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawBuffers.xml}{glDrawBuffers()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount) + + Convenience function that calls glDrawElementsInstanced(\a mode, \a count, \a type, \a indices, \a instancecount). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawElementsInstanced.xml}{glDrawElementsInstanced()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices) + + Convenience function that calls glDrawRangeElements(\a mode, \a start, \a end, \a count, \a type, \a indices). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawRangeElements.xml}{glDrawRangeElements()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glEndQuery(GLenum target) + + Convenience function that calls glEndQuery(\a target). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glEndQuery.xml}{glEndQuery()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glEndTransformFeedback() + + Convenience function that calls glEndTransformFeedback(). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glEndTransformFeedback.xml}{glEndTransformFeedback()}. +*/ + +/*! + \fn GLsync QOpenGLExtraFunctions::glFenceSync(GLenum condition, GLbitfield flags) + + Convenience function that calls glFenceSync(\a condition, \a flags). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glFenceSync.xml}{glFenceSync()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) + + Convenience function that calls glFlushMappedBufferRange(\a target, \a offset, \a length). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glFlushMappedBufferRange.xml}{glFlushMappedBufferRange()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) + + Convenience function that calls glFramebufferTextureLayer(\a target, \a attachment, \a texture, \a level, \a layer). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glFramebufferTextureLayer.xml}{glFramebufferTextureLayer()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGenQueries(GLsizei n, GLuint* ids) + + Convenience function that calls glGenQueries(\a n, \a ids). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenQueries.xml}{glGenQueries()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGenSamplers(GLsizei count, GLuint* samplers) + + Convenience function that calls glGenSamplers(\a count, \a samplers). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenSamplers.xml}{glGenSamplers()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGenTransformFeedbacks(GLsizei n, GLuint* ids) + + Convenience function that calls glGenTransformFeedbacks(\a n, \a ids). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenTransformFeedbacks.xml}{glGenTransformFeedbacks()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGenVertexArrays(GLsizei n, GLuint* arrays) + + Convenience function that calls glGenVertexArrays(\a n, \a arrays). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenVertexArrays.xml}{glGenVertexArrays()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) + + Convenience function that calls glGetActiveUniformBlockName(\a program, \a uniformBlockIndex, \a bufSize, \a length, \a uniformBlockName). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetActiveUniformBlockName.xml}{glGetActiveUniformBlockName()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) + + Convenience function that calls glGetActiveUniformBlockiv(\a program, \a uniformBlockIndex, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetActiveUniformBlockiv.xml}{glGetActiveUniformBlockiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint* params) + + Convenience function that calls glGetActiveUniformsiv(\a program, \a uniformCount, \a uniformIndices, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetActiveUniformsiv.xml}{glGetActiveUniformsiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) + + Convenience function that calls glGetBufferParameteri64v(\a target, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetBufferParameteri64v.xml}{glGetBufferParameteri64v()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetBufferPointerv(GLenum target, GLenum pname, void ** params) + + Convenience function that calls glGetBufferPointerv(\a target, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetBufferPointerv.xml}{glGetBufferPointerv()}. +*/ + +/*! + \fn GLint QOpenGLExtraFunctions::glGetFragDataLocation(GLuint program, const GLchar * name) + + Convenience function that calls glGetFragDataLocation(\a program, \a name). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetFragDataLocation.xml}{glGetFragDataLocation()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetInteger64i_v(GLenum target, GLuint index, GLint64* data) + + Convenience function that calls glGetInteger64i_v(\a target, \a index, \a data). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetInteger64i_v.xml}{glGetInteger64i_v()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetInteger64v(GLenum pname, GLint64* data) + + Convenience function that calls glGetInteger64v(\a pname, \a data). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetInteger64v.xml}{glGetInteger64v()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetIntegeri_v(GLenum target, GLuint index, GLint* data) + + Convenience function that calls glGetIntegeri_v(\a target, \a index, \a data). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetIntegeri_v.xml}{glGetIntegeri_v()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) + + Convenience function that calls glGetInternalformativ(\a target, \a internalformat, \a pname, \a bufSize, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetInternalformativ.xml}{glGetInternalformativ()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void * binary) + + Convenience function that calls glGetProgramBinary(\a program, \a bufSize, \a length, \a binaryFormat, \a binary). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramBinary.xml}{glGetProgramBinary()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) + + Convenience function that calls glGetQueryObjectuiv(\a id, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetQueryObjectuiv.xml}{glGetQueryObjectuiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetQueryiv(GLenum target, GLenum pname, GLint* params) + + Convenience function that calls glGetQueryiv(\a target, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetQueryiv.xml}{glGetQueryiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) + + Convenience function that calls glGetSamplerParameterfv(\a sampler, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetSamplerParameterfv.xml}{glGetSamplerParameterfv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) + + Convenience function that calls glGetSamplerParameteriv(\a sampler, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetSamplerParameteriv.xml}{glGetSamplerParameteriv()}. +*/ + +/*! + \fn const GLubyte * QOpenGLExtraFunctions::glGetStringi(GLenum name, GLuint index) + + Convenience function that calls glGetStringi(\a name, \a index). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetStringi.xml}{glGetStringi()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) + + Convenience function that calls glGetSynciv(\a sync, \a pname, \a bufSize, \a length, \a values). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetSynciv.xml}{glGetSynciv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) + + Convenience function that calls glGetTransformFeedbackVarying(\a program, \a index, \a bufSize, \a length, \a size, \a type, \a name). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetTransformFeedbackVarying.xml}{glGetTransformFeedbackVarying()}. +*/ + +/*! + \fn GLuint QOpenGLExtraFunctions::glGetUniformBlockIndex(GLuint program, const GLchar * uniformBlockName) + + Convenience function that calls glGetUniformBlockIndex(\a program, \a uniformBlockName). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetUniformBlockIndex.xml}{glGetUniformBlockIndex()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint* uniformIndices) + + Convenience function that calls glGetUniformIndices(\a program, \a uniformCount, \a uniformNames, \a uniformIndices). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetUniformIndices.xml}{glGetUniformIndices()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetUniformuiv(GLuint program, GLint location, GLuint* params) + + Convenience function that calls glGetUniformuiv(\a program, \a location, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetUniformuiv.xml}{glGetUniformuiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) + + Convenience function that calls glGetVertexAttribIiv(\a index, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetVertexAttribIiv.xml}{glGetVertexAttribIiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) + + Convenience function that calls glGetVertexAttribIuiv(\a index, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetVertexAttribIuiv.xml}{glGetVertexAttribIuiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments) + + Convenience function that calls glInvalidateFramebuffer(\a target, \a numAttachments, \a attachments). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glInvalidateFramebuffer.xml}{glInvalidateFramebuffer()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height) + + Convenience function that calls glInvalidateSubFramebuffer(\a target, \a numAttachments, \a attachments, \a x, \a y, \a width, \a height). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glInvalidateSubFramebuffer.xml}{glInvalidateSubFramebuffer()}. +*/ + +/*! + \fn GLboolean QOpenGLExtraFunctions::glIsQuery(GLuint id) + + Convenience function that calls glIsQuery(\a id). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsQuery.xml}{glIsQuery()}. +*/ + +/*! + \fn GLboolean QOpenGLExtraFunctions::glIsSampler(GLuint sampler) + + Convenience function that calls glIsSampler(\a sampler). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsSampler.xml}{glIsSampler()}. +*/ + +/*! + \fn GLboolean QOpenGLExtraFunctions::glIsSync(GLsync sync) + + Convenience function that calls glIsSync(\a sync). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsSync.xml}{glIsSync()}. +*/ + +/*! + \fn GLboolean QOpenGLExtraFunctions::glIsTransformFeedback(GLuint id) + + Convenience function that calls glIsTransformFeedback(\a id). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsTransformFeedback.xml}{glIsTransformFeedback()}. +*/ + +/*! + \fn GLboolean QOpenGLExtraFunctions::glIsVertexArray(GLuint array) + + Convenience function that calls glIsVertexArray(\a array). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsVertexArray.xml}{glIsVertexArray()}. +*/ + +/*! + \fn void * QOpenGLExtraFunctions::glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) + + Convenience function that calls glMapBufferRange(\a target, \a offset, \a length, \a access). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glMapBufferRange.xml}{glMapBufferRange()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glPauseTransformFeedback() + + Convenience function that calls glPauseTransformFeedback(). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glPauseTransformFeedback.xml}{glPauseTransformFeedback()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramBinary(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length) + + Convenience function that calls glProgramBinary(\a program, \a binaryFormat, \a binary, \a length). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramBinary.xml}{glProgramBinary()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramParameteri(GLuint program, GLenum pname, GLint value) + + Convenience function that calls glProgramParameteri(\a program, \a pname, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramParameteri.xml}{glProgramParameteri()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glReadBuffer(GLenum src) + + Convenience function that calls glReadBuffer(\a src). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glReadBuffer.xml}{glReadBuffer()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) + + Convenience function that calls glRenderbufferStorageMultisample(\a target, \a samples, \a internalformat, \a width, \a height). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glRenderbufferStorageMultisample.xml}{glRenderbufferStorageMultisample()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glResumeTransformFeedback() + + Convenience function that calls glResumeTransformFeedback(). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glResumeTransformFeedback.xml}{glResumeTransformFeedback()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) + + Convenience function that calls glSamplerParameterf(\a sampler, \a pname, \a param). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glSamplerParameterf.xml}{glSamplerParameterf()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat * param) + + Convenience function that calls glSamplerParameterfv(\a sampler, pname, \a param). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glSamplerParameterfv.xml}{glSamplerParameterfv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) + + Convenience function that calls glSamplerParameteri(\a sampler, \a pname, \a param). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glSamplerParameteri.xml}{glSamplerParameteri()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint * param) + + Convenience function that calls glSamplerParameteriv(\a sampler, \a pname, \a param). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glSamplerParameteriv.xml}{glSamplerParameteriv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels) + + Convenience function that calls glTexImage3D(\a target, \a level, \a internalformat, \a width, \a height, \a depth, \a border, \a format, \a type, \a pixels). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexImage3D.xml}{glTexImage3D()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) + + Convenience function that calls glTexStorage2D(\a target, \a levels, \a internalformat, \a width, \a height). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexStorage2D.xml}{glTexStorage2D()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) + + Convenience function that calls glTexStorage3D(\a target, \a levels, \a internalformat, \a width, \a height, \a depth). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexStorage3D.xml}{glTexStorage3D()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels) + + Convenience function that calls glTexSubImage3D(\a target, \a level, \a xoffset, \a yoffset, \a zoffset, \a width, \a height, \a depth, \a format, \a type, \a pixels). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexSubImage3D.xml}{glTexSubImage3D()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode) + + Convenience function that calls glTransformFeedbackVaryings(\a program, \a count, \a varyings, \a bufferMode). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glTransformFeedbackVaryings.xml}{glTransformFeedbackVaryings()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform1ui(GLint location, GLuint v0) + + Convenience function that calls glUniform1ui(\a location, \a v0). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform1ui.xml}{glUniform1ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform1uiv(GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glUniform1uiv(\a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform1uiv.xml}{glUniform1uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform2ui(GLint location, GLuint v0, GLuint v1) + + Convenience function that calls glUniform2ui(\a location, \a v0, \a v1). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform2ui.xml}{glUniform2ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform2uiv(GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glUniform2uiv(\a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform2uiv.xml}{glUniform2uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) + + Convenience function that calls glUniform3ui(\a location, \a v0, \a v1, \a v2). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform3ui.xml}{glUniform3ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform3uiv(GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glUniform3uiv(\a location, count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform3uiv.xml}{glUniform3uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) + + Convenience function that calls glUniform4ui(\a location, \a v0, \a v1, \a v2, \a v3). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform4ui.xml}{glUniform4ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform4uiv(GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glUniform4uiv(\a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform4uiv.xml}{glUniform4uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) + + Convenience function that calls glUniformBlockBinding(\a program, \a uniformBlockIndex, \a uniformBlockBinding). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformBlockBinding.xml}{glUniformBlockBinding()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glUniformMatrix2x3fv(\a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix2x3fv.xml}{glUniformMatrix2x3fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glUniformMatrix2x4fv(\a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix2x4fv.xml}{glUniformMatrix2x4fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glUniformMatrix3x2fv(\a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix3x2fv.xml}{glUniformMatrix3x2fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glUniformMatrix3x4fv(\a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix3x4fv.xml}{glUniformMatrix3x4fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glUniformMatrix4x2fv(\a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix4x2fv.xml}{glUniformMatrix4x2fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glUniformMatrix4x3fv(\a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix4x3fv.xml}{glUniformMatrix4x3fv()}. +*/ + +/*! + \fn GLboolean QOpenGLExtraFunctions::glUnmapBuffer(GLenum target) + + Convenience function that calls glUnmapBuffer(\a target). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUnmapBuffer.xml}{glUnmapBuffer()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribDivisor(GLuint index, GLuint divisor) + + Convenience function that calls glVertexAttribDivisor(\a index, \a divisor). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribDivisor.xml}{glVertexAttribDivisor()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) + + Convenience function that calls glVertexAttribI4i(\a index, \a x, \a y, \a z, \a w). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribI4i.xml}{glVertexAttribI4i()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribI4iv(GLuint index, const GLint * v) + + Convenience function that calls glVertexAttribI4iv(\a index, \a v). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribI4iv.xml}{glVertexAttribI4iv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) + + Convenience function that calls glVertexAttribI4ui(\a index, \a x, \a y, \a z, \a w). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribI4ui.xml}{glVertexAttribI4ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribI4uiv(GLuint index, const GLuint * v) + + Convenience function that calls glVertexAttribI4uiv(\a index, \a v). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribI4uiv.xml}{glVertexAttribI4uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) + + Convenience function that calls glVertexAttribIPointer(\a index, \a size, \a type, \a stride, \a pointer). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribIPointer.xml}{glVertexAttribIPointer()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) + + Convenience function that calls glWaitSync(\a sync, \a flags, \a timeout). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glWaitSync.xml}{glWaitSync()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glActiveShaderProgram(GLuint pipeline, GLuint program) + + Convenience function that calls glActiveShaderProgram(pipeline, program). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glActiveShaderProgram.xml}{glActiveShaderProgram()}. +*/ + +/*! + \fn void QOpenGLFunctions::glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) + + Convenience function that calls glBindImageTexture(unit, texture, level, layered, layer, access, format). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindImageTexture.xml}{glBindImageTexture()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindProgramPipeline(GLuint pipeline) + + Convenience function that calls glBindProgramPipeline(pipeline). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindProgramPipeline.xml}{glBindProgramPipeline()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) + + Convenience function that calls glBindVertexBuffer(bindingindex, buffer, offset, stride). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindVertexBuffer.xml}{glBindVertexBuffer()}. +*/ + +/*! + \fn GLuint QOpenGLExtraFunctions::glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const* strings) + + Convenience function that calls glCreateShaderProgramv(type, count, strings). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glCreateShaderProgramv.xml}{glCreateShaderProgramv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDeleteProgramPipelines(GLsizei n, const GLuint * pipelines) + + Convenience function that calls glDeleteProgramPipelines(n, pipelines). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteProgramPipelines.xml}{glDeleteProgramPipelines()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) + + Convenience function that calls glDispatchCompute(num_groups_x, num_groups_y, num_groups_z). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDispatchCompute.xml}{glDispatchCompute()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDispatchComputeIndirect(GLintptr indirect) + + Convenience function that calls glDispatchComputeIndirect(indirect). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDispatchComputeIndirect.xml}{glDispatchComputeIndirect()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDrawArraysIndirect(GLenum mode, const void * indirect) + + Convenience function that calls glDrawArraysIndirect(mode, indirect). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawArraysIndirect.xml}{glDrawArraysIndirect()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDrawElementsIndirect(GLenum mode, GLenum type, const void * indirect) + + Convenience function that calls glDrawElementsIndirect(mode, type, indirect). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawElementsIndirect.xml}{glDrawElementsIndirect()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glFramebufferParameteri(GLenum target, GLenum pname, GLint param) + + Convenience function that calls glFramebufferParameteri(target, pname, param). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glFramebufferParameteri.xml}{glFramebufferParameteri()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGenProgramPipelines(GLsizei n, GLuint* pipelines) + + Convenience function that calls glGenProgramPipelines(n, pipelines). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenProgramPipelines.xml}{glGenProgramPipelines()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetBooleani_v(GLenum target, GLuint index, GLboolean* data) + + Convenience function that calls glGetBooleani_v(target, index, data). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetBooleani_v.xml}{glGetBooleani_v()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint* params) + + Convenience function that calls glGetFramebufferParameteriv(target, pname, params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetFramebufferParameteriv.xml}{glGetFramebufferParameteriv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetMultisamplefv(GLenum pname, GLuint index, GLfloat* val) + + Convenience function that calls glGetMultisamplefv(pname, index, val). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetMultisamplefv.xml}{glGetMultisamplefv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params) + + Convenience function that calls glGetProgramInterfaceiv(program, programInterface, pname, params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramInterfaceiv.xml}{glGetProgramInterfaceiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) + + Convenience function that calls glGetProgramPipelineInfoLog(pipeline, bufSize, length, infoLog). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramPipelineInfoLog.xml}{glGetProgramPipelineInfoLog()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint* params) + + Convenience function that calls glGetProgramPipelineiv(pipeline, pname, params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramPipelineiv.xml}{glGetProgramPipelineiv()}. +*/ + +/*! + \fn GLuint QOpenGLExtraFunctions::glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar * name) + + Convenience function that calls glGetProgramResourceIndex(program, programInterface, name). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramResourceIndex.xml}{glGetProgramResourceIndex()}. +*/ + +/*! + \fn GLint QOpenGLExtraFunctions::glGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar * name) + + Convenience function that calls glGetProgramResourceLocation(program, programInterface, name). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramResourceLocation.xml}{glGetProgramResourceLocation()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name) + + Convenience function that calls glGetProgramResourceName(program, programInterface, index, bufSize, length, name). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramResourceName.xml}{glGetProgramResourceName()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei* length, GLint* params) + + Convenience function that calls glGetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramResourceiv.xml}{glGetProgramResourceiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params) + + Convenience function that calls glGetTexLevelParameterfv(target, level, pname, params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetTexLevelParameterfv.xml}{glGetTexLevelParameterfv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params) + + Convenience function that calls glGetTexLevelParameteriv(target, level, pname, params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetTexLevelParameteriv.xml}{glGetTexLevelParameteriv()}. +*/ + +/*! + \fn GLboolean QOpenGLExtraFunctions::glIsProgramPipeline(GLuint pipeline) + + Convenience function that calls glIsProgramPipeline(pipeline). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsProgramPipeline.xml}{glIsProgramPipeline()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glMemoryBarrier(GLbitfield barriers) + + Convenience function that calls glMemoryBarrier(barriers). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glMemoryBarrier.xml}{glMemoryBarrier()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glMemoryBarrierByRegion(GLbitfield barriers) + + Convenience function that calls glMemoryBarrierByRegion(barriers). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glMemoryBarrierByRegion.xml}{glMemoryBarrierByRegion()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform1f(GLuint program, GLint location, GLfloat v0) + + Convenience function that calls glProgramUniform1f(program, location, v0). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1f.xml}{glProgramUniform1f()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) + + Convenience function that calls glProgramUniform1fv(program, location, count, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1fv.xml}{glProgramUniform1fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform1i(GLuint program, GLint location, GLint v0) + + Convenience function that calls glProgramUniform1i(program, location, v0). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1i.xml}{glProgramUniform1i()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint * value) + + Convenience function that calls glProgramUniform1iv(program, location, count, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1iv.xml}{glProgramUniform1iv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform1ui(GLuint program, GLint location, GLuint v0) + + Convenience function that calls glProgramUniform1ui(program, location, v0). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1ui.xml}{glProgramUniform1ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glProgramUniform1uiv(program, location, count, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1uiv.xml}{glProgramUniform1uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1) + + Convenience function that calls glProgramUniform2f(program, location, v0, v1). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2f.xml}{glProgramUniform2f()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) + + Convenience function that calls glProgramUniform2fv(program, location, count, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2fv.xml}{glProgramUniform2fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1) + + Convenience function that calls glProgramUniform2i(program, location, v0, v1). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2i.xml}{glProgramUniform2i()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint * value) + + Convenience function that calls glProgramUniform2iv(program, location, count, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2iv.xml}{glProgramUniform2iv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1) + + Convenience function that calls glProgramUniform2ui(program, location, v0, v1). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2ui.xml}{glProgramUniform2ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glProgramUniform2uiv(program, location, count, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2uiv.xml}{glProgramUniform2uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) + + Convenience function that calls glProgramUniform3f(program, location, v0, v1, v2). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3f.xml}{glProgramUniform3f()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) + + Convenience function that calls glProgramUniform3fv(program, location, count, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3fv.xml}{glProgramUniform3fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) + + Convenience function that calls glProgramUniform3i(program, location, v0, v1, v2). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3i.xml}{glProgramUniform3i()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint * value) + + Convenience function that calls glProgramUniform3iv(program, location, count, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3iv.xml}{glProgramUniform3iv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) + + Convenience function that calls glProgramUniform3ui(program, location, v0, v1, v2). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3ui.xml}{glProgramUniform3ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glProgramUniform3uiv(program, location, count, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3uiv.xml}{glProgramUniform3uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) + + Convenience function that calls glProgramUniform4f(program, location, v0, v1, v2, v3). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4f.xml}{glProgramUniform4f()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) + + Convenience function that calls glProgramUniform4fv(program, location, count, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4fv.xml}{glProgramUniform4fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) + + Convenience function that calls glProgramUniform4i(program, location, v0, v1, v2, v3). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4i.xml}{glProgramUniform4i()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint * value) + + Convenience function that calls glProgramUniform4iv(program, location, count, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4iv.xml}{glProgramUniform4iv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) + + Convenience function that calls glProgramUniform4ui(program, location, v0, v1, v2, v3). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4ui.xml}{glProgramUniform4ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glProgramUniform4uiv(program, location, count, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4uiv.xml}{glProgramUniform4uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix2fv(program, location, count, transpose, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix2fv.xml}{glProgramUniformMatrix2fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix2x3fv(program, location, count, transpose, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix2x3fv.xml}{glProgramUniformMatrix2x3fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix2x4fv(program, location, count, transpose, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix2x4fv.xml}{glProgramUniformMatrix2x4fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix3fv(program, location, count, transpose, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix3fv.xml}{glProgramUniformMatrix3fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix3x2fv(program, location, count, transpose, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix3x2fv.xml}{glProgramUniformMatrix3x2fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix3x4fv(program, location, count, transpose, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix3x4fv.xml}{glProgramUniformMatrix3x4fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix4fv(program, location, count, transpose, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix4fv.xml}{glProgramUniformMatrix4fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix4x2fv(program, location, count, transpose, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix4x2fv.xml}{glProgramUniformMatrix4x2fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix4x3fv(program, location, count, transpose, value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix4x3fv.xml}{glProgramUniformMatrix4x3fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glSampleMaski(GLuint maskNumber, GLbitfield mask) + + Convenience function that calls glSampleMaski(maskNumber, mask). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glSampleMaski.xml}{glSampleMaski()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) + + Convenience function that calls glTexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexStorage2DMultisample.xml}{glTexStorage2DMultisample()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) + + Convenience function that calls glUseProgramStages(pipeline, stages, program). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUseProgramStages.xml}{glUseProgramStages()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glValidateProgramPipeline(GLuint pipeline) + + Convenience function that calls glValidateProgramPipeline(pipeline). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glValidateProgramPipeline.xml}{glValidateProgramPipeline()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribBinding(GLuint attribindex, GLuint bindingindex) + + Convenience function that calls glVertexAttribBinding(attribindex, bindingindex). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribBinding.xml}{glVertexAttribBinding()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) + + Convenience function that calls glVertexAttribFormat(attribindex, size, type, normalized, relativeoffset). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribFormat.xml}{glVertexAttribFormat()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) + + Convenience function that calls glVertexAttribIFormat(attribindex, size, type, relativeoffset). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribIFormat.xml}{glVertexAttribIFormat()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexBindingDivisor(GLuint bindingindex, GLuint divisor) + + Convenience function that calls glVertexBindingDivisor(bindingindex, divisor). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexBindingDivisor.xml}{glVertexBindingDivisor()}. +*/ + +/*! + \fn bool QOpenGLExtraFunctions::isInitialized(const QOpenGLExtraFunctionsPrivate *d) + \internal +*/ + +// Functions part of the OpenGL ES 3.0+ standard need special handling. These, just like +// the 2.0 functions, are not guaranteed to be resolvable via eglGetProcAddress or +// similar. (we cannot count on EGL_KHR_(client_)get_all_proc_addresses being available) + +// Calling them directly is, unlike the 2.0 functions, not feasible because one may build +// the binaries on a GLES3-capable system and then deploy on a GLES2-only system that does +// not have these symbols, and vice versa. Until ES3 becomes universally available, they +// have to be dlsym'ed. + +Q_GLOBAL_STATIC(QOpenGLES3Helper, qgles3Helper) + +bool QOpenGLES3Helper::init() +{ +#ifdef QT_NO_LIBRARY + return false; +#elif !defined(Q_OS_IOS) +# ifdef Q_OS_WIN +# ifndef QT_DEBUG + m_gl.setFileName(QStringLiteral("libGLESv2")); +# else + m_gl.setFileName(QStringLiteral("libGLESv2d")); +# endif +# else +# ifdef Q_OS_ANDROID + m_gl.setFileName(QStringLiteral("GLESv2")); +# else + m_gl.setFileNameAndVersion(QStringLiteral("GLESv2"), 2); +# endif +# endif // Q_OS_WIN + return m_gl.load(); +#else + return true; +#endif // Q_OS_IOS +} + +QFunctionPointer QOpenGLES3Helper::resolve(const char *name) +{ +#ifdef Q_OS_IOS + return QFunctionPointer(dlsym(RTLD_DEFAULT, name)); +#elif !defined(QT_NO_LIBRARY) + return m_gl.resolve(name); +#else + Q_UNUSED(name); + return 0; +#endif +} + +QOpenGLES3Helper::QOpenGLES3Helper() +{ + m_supportedVersion = qMakePair(2, 0); + + if (init()) { + const QPair<int, int> contextVersion = QOpenGLContext::currentContext()->format().version(); + + qCDebug(lcGLES3, "Resolving OpenGL ES 3.0 entry points"); + + BeginQuery = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint)) resolve("glBeginQuery"); + BeginTransformFeedback = (void (QOPENGLF_APIENTRYP) (GLenum)) resolve("glBeginTransformFeedback"); + BindBufferBase = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLuint)) resolve("glBindBufferBase"); + BindBufferRange = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) resolve("glBindBufferRange"); + BindSampler = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glBindSampler"); + BindTransformFeedback = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint)) resolve("glBindTransformFeedback"); + BindVertexArray = (void (QOPENGLF_APIENTRYP) (GLuint)) resolve("glBindVertexArray"); + BlitFramebuffer = (void (QOPENGLF_APIENTRYP) (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) resolve("glBlitFramebuffer"); + ClearBufferfi = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLfloat, GLint)) resolve("glClearBufferfi"); + ClearBufferfv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, const GLfloat *)) resolve("glClearBufferfv"); + ClearBufferiv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, const GLint *)) resolve("glClearBufferiv"); + ClearBufferuiv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, const GLuint *)) resolve("glClearBufferuiv"); + ClientWaitSync = (GLenum (QOPENGLF_APIENTRYP) (GLsync, GLbitfield, GLuint64)) resolve("glClientWaitSync"); + CompressedTexImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const void *)) resolve("glCompressedTexImage3D"); + CompressedTexSubImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const void *)) resolve("glCompressedTexSubImage3D"); + CopyBufferSubData = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr)) resolve("glCopyBufferSubData"); + CopyTexSubImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) resolve("glCopyTexSubImage3D"); + DeleteQueries = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteQueries"); + DeleteSamplers = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteSamplers"); + DeleteSync = (void (QOPENGLF_APIENTRYP) (GLsync)) resolve("glDeleteSync"); + DeleteTransformFeedbacks = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteTransformFeedbacks"); + DeleteVertexArrays = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteVertexArrays"); + DrawArraysInstanced = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLsizei, GLsizei)) resolve("glDrawArraysInstanced"); + DrawBuffers = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLenum *)) resolve("glDrawBuffers"); + DrawElementsInstanced = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, const void *, GLsizei)) resolve("glDrawElementsInstanced"); + DrawRangeElements = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLuint, GLsizei, GLenum, const void *)) resolve("glDrawRangeElements"); + EndQuery = (void (QOPENGLF_APIENTRYP) (GLenum)) resolve("glEndQuery"); + EndTransformFeedback = (void (QOPENGLF_APIENTRYP) ()) resolve("glEndTransformFeedback"); + FenceSync = (GLsync (QOPENGLF_APIENTRYP) (GLenum, GLbitfield)) resolve("glFenceSync"); + FlushMappedBufferRange = (void (QOPENGLF_APIENTRYP) (GLenum, GLintptr, GLsizeiptr)) resolve("glFlushMappedBufferRange"); + FramebufferTextureLayer = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLuint, GLint, GLint)) resolve("glFramebufferTextureLayer"); + GenQueries = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenQueries"); + GenSamplers = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenSamplers"); + GenTransformFeedbacks = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenTransformFeedbacks"); + GenVertexArrays = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenVertexArrays"); + GetActiveUniformBlockName = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLsizei, GLsizei*, GLchar*)) resolve("glGetActiveUniformBlockName"); + GetActiveUniformBlockiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLenum, GLint*)) resolve("glGetActiveUniformBlockiv"); + GetActiveUniformsiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, const GLuint *, GLenum, GLint*)) resolve("glGetActiveUniformsiv"); + GetBufferParameteri64v = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLint64*)) resolve("glGetBufferParameteri64v"); + GetBufferPointerv = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, void **)) resolve("glGetBufferPointerv"); + GetFragDataLocation = (GLint (QOPENGLF_APIENTRYP) (GLuint, const GLchar *)) resolve("glGetFragDataLocation"); + GetInteger64i_v = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLint64*)) resolve("glGetInteger64i_v"); + GetInteger64v = (void (QOPENGLF_APIENTRYP) (GLenum, GLint64*)) resolve("glGetInteger64v"); + GetIntegeri_v = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLint*)) resolve("glGetIntegeri_v"); + GetInternalformativ = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLenum, GLsizei, GLint*)) resolve("glGetInternalformativ"); + GetProgramBinary = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, GLsizei*, GLenum*, void *)) resolve("glGetProgramBinary"); + GetQueryObjectuiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLuint*)) resolve("glGetQueryObjectuiv"); + GetQueryiv = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLint*)) resolve("glGetQueryiv"); + GetSamplerParameterfv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLfloat*)) resolve("glGetSamplerParameterfv"); + GetSamplerParameteriv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint*)) resolve("glGetSamplerParameteriv"); + GetStringi = (const GLubyte * (QOPENGLF_APIENTRYP) (GLenum, GLuint)) resolve("glGetStringi"); + GetSynciv = (void (QOPENGLF_APIENTRYP) (GLsync, GLenum, GLsizei, GLsizei*, GLint*)) resolve("glGetSynciv"); + GetTransformFeedbackVarying = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLsizei, GLsizei*, GLsizei*, GLenum*, GLchar*)) resolve("glGetTransformFeedbackVarying"); + GetUniformBlockIndex = (GLuint (QOPENGLF_APIENTRYP) (GLuint, const GLchar *)) resolve("glGetUniformBlockIndex"); + GetUniformIndices = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, const GLchar *const*, GLuint*)) resolve("glGetUniformIndices"); + GetUniformuiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint*)) resolve("glGetUniformuiv"); + GetVertexAttribIiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint*)) resolve("glGetVertexAttribIiv"); + GetVertexAttribIuiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLuint*)) resolve("glGetVertexAttribIuiv"); + InvalidateFramebuffer = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, const GLenum *)) resolve("glInvalidateFramebuffer"); + InvalidateSubFramebuffer = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, const GLenum *, GLint, GLint, GLsizei, GLsizei)) resolve("glInvalidateSubFramebuffer"); + IsQuery = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsQuery"); + IsSampler = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsSampler"); + IsSync = (GLboolean (QOPENGLF_APIENTRYP) (GLsync)) resolve("glIsSync"); + IsTransformFeedback = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsTransformFeedback"); + IsVertexArray = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsVertexArray"); + MapBufferRange = (void * (QOPENGLF_APIENTRYP) (GLenum, GLintptr, GLsizeiptr, GLbitfield)) resolve("glMapBufferRange"); + PauseTransformFeedback = (void (QOPENGLF_APIENTRYP) ()) resolve("glPauseTransformFeedback"); + ProgramBinary = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, const void *, GLsizei)) resolve("glProgramBinary"); + ProgramParameteri = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint)) resolve("glProgramParameteri"); + ReadBuffer = (void (QOPENGLF_APIENTRYP) (GLenum)) resolve("glReadBuffer"); + RenderbufferStorageMultisample = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, GLsizei, GLsizei)) resolve("glRenderbufferStorageMultisample"); + ResumeTransformFeedback = (void (QOPENGLF_APIENTRYP) ()) resolve("glResumeTransformFeedback"); + SamplerParameterf = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLfloat)) resolve("glSamplerParameterf"); + SamplerParameterfv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, const GLfloat *)) resolve("glSamplerParameterfv"); + SamplerParameteri = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint)) resolve("glSamplerParameteri"); + SamplerParameteriv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, const GLint *)) resolve("glSamplerParameteriv"); + TexImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const void *)) resolve("glTexImage3D"); + TexStorage2D = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, GLsizei, GLsizei)) resolve("glTexStorage2D"); + TexStorage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei)) resolve("glTexStorage3D"); + TexSubImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const void *)) resolve("glTexSubImage3D"); + TransformFeedbackVaryings = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, const GLchar *const*, GLenum)) resolve("glTransformFeedbackVaryings"); + Uniform1ui = (void (QOPENGLF_APIENTRYP) (GLint, GLuint)) resolve("glUniform1ui"); + Uniform1uiv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, const GLuint *)) resolve("glUniform1uiv"); + Uniform2ui = (void (QOPENGLF_APIENTRYP) (GLint, GLuint, GLuint)) resolve("glUniform2ui"); + Uniform2uiv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, const GLuint *)) resolve("glUniform2uiv"); + Uniform3ui = (void (QOPENGLF_APIENTRYP) (GLint, GLuint, GLuint, GLuint)) resolve("glUniform3ui"); + Uniform3uiv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, const GLuint *)) resolve("glUniform3uiv"); + Uniform4ui = (void (QOPENGLF_APIENTRYP) (GLint, GLuint, GLuint, GLuint, GLuint)) resolve("glUniform4ui"); + Uniform4uiv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, const GLuint *)) resolve("glUniform4uiv"); + UniformBlockBinding = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLuint)) resolve("glUniformBlockBinding"); + UniformMatrix2x3fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix2x3fv"); + UniformMatrix2x4fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix2x4fv"); + UniformMatrix3x2fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix3x2fv"); + UniformMatrix3x4fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix3x4fv"); + UniformMatrix4x2fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix4x2fv"); + UniformMatrix4x3fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix4x3fv"); + UnmapBuffer = (GLboolean (QOPENGLF_APIENTRYP) (GLenum)) resolve("glUnmapBuffer"); + VertexAttribDivisor = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glVertexAttribDivisor"); + VertexAttribI4i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint, GLint, GLint)) resolve("glVertexAttribI4i"); + VertexAttribI4iv = (void (QOPENGLF_APIENTRYP) (GLuint, const GLint *)) resolve("glVertexAttribI4iv"); + VertexAttribI4ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLuint, GLuint, GLuint)) resolve("glVertexAttribI4ui"); + VertexAttribI4uiv = (void (QOPENGLF_APIENTRYP) (GLuint, const GLuint *)) resolve("glVertexAttribI4uiv"); + VertexAttribIPointer = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLenum, GLsizei, const void *)) resolve("glVertexAttribIPointer"); + WaitSync = (void (QOPENGLF_APIENTRYP) (GLsync, GLbitfield, GLuint64)) resolve("glWaitSync"); + + if (!BeginQuery || !BlitFramebuffer || !GenTransformFeedbacks || !GenVertexArrays || !MapBufferRange + || !RenderbufferStorageMultisample || !TexStorage2D || !WaitSync) { + qWarning("OpenGL ES 3.0 entry points not found. This is odd because the driver returned a context of version %d.%d", + contextVersion.first, contextVersion.second); + return; + } + m_supportedVersion = qMakePair(3, 0); + + if (contextVersion >= qMakePair(3, 1)) { + qCDebug(lcGLES3, "Resolving OpenGL ES 3.1 entry points"); + + ActiveShaderProgram = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glActiveShaderProgram"); + BindImageTexture = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLint, GLboolean, GLint, GLenum, GLenum)) resolve("glBindImageTexture"); + BindProgramPipeline = (void (QOPENGLF_APIENTRYP) (GLuint)) resolve("glBindProgramPipeline"); + BindVertexBuffer = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLintptr, GLsizei)) resolve("glBindVertexBuffer"); + CreateShaderProgramv = (GLuint (QOPENGLF_APIENTRYP) (GLenum, GLsizei, const GLchar *const*)) resolve("glCreateShaderProgramv"); + DeleteProgramPipelines = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteProgramPipelines"); + DispatchCompute = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLuint)) resolve("glDispatchCompute"); + DispatchComputeIndirect = (void (QOPENGLF_APIENTRYP) (GLintptr)) resolve("glDispatchComputeIndirect"); + DrawArraysIndirect = (void (QOPENGLF_APIENTRYP) (GLenum, const void *)) resolve("glDrawArraysIndirect"); + DrawElementsIndirect = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, const void *)) resolve("glDrawElementsIndirect"); + FramebufferParameteri = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLint)) resolve("glFramebufferParameteri"); + GenProgramPipelines = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenProgramPipelines"); + GetBooleani_v = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLboolean*)) resolve("glGetBooleani_v"); + GetFramebufferParameteriv = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLint*)) resolve("glGetFramebufferParameteriv"); + GetMultisamplefv = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLfloat*)) resolve("glGetMultisamplefv"); + GetProgramInterfaceiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLenum, GLint*)) resolve("glGetProgramInterfaceiv"); + GetProgramPipelineInfoLog = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, GLsizei*, GLchar*)) resolve("glGetProgramPipelineInfoLog"); + GetProgramPipelineiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint*)) resolve("glGetProgramPipelineiv"); + GetProgramResourceIndex = (GLuint (QOPENGLF_APIENTRYP) (GLuint, GLenum, const GLchar *)) resolve("glGetProgramResourceIndex"); + GetProgramResourceLocation = (GLint (QOPENGLF_APIENTRYP) (GLuint, GLenum, const GLchar *)) resolve("glGetProgramResourceLocation"); + GetProgramResourceName = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLuint, GLsizei, GLsizei*, GLchar*)) resolve("glGetProgramResourceName"); + GetProgramResourceiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLuint, GLsizei, const GLenum *, GLsizei, GLsizei*, GLint*)) resolve("glGetProgramResourceiv"); + GetTexLevelParameterfv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLenum, GLfloat*)) resolve("glGetTexLevelParameterfv"); + GetTexLevelParameteriv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLenum, GLint*)) resolve("glGetTexLevelParameteriv"); + IsProgramPipeline = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsProgramPipeline"); + MemoryBarrierFunc = (void (QOPENGLF_APIENTRYP) (GLbitfield)) resolve("glMemoryBarrier"); + MemoryBarrierByRegion = (void (QOPENGLF_APIENTRYP) (GLbitfield)) resolve("glMemoryBarrierByRegion"); + ProgramUniform1f = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLfloat)) resolve("glProgramUniform1f"); + ProgramUniform1fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLfloat *)) resolve("glProgramUniform1fv"); + ProgramUniform1i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint)) resolve("glProgramUniform1i"); + ProgramUniform1iv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLint *)) resolve("glProgramUniform1iv"); + ProgramUniform1ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint)) resolve("glProgramUniform1ui"); + ProgramUniform1uiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLuint *)) resolve("glProgramUniform1uiv"); + ProgramUniform2f = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLfloat, GLfloat)) resolve("glProgramUniform2f"); + ProgramUniform2fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLfloat *)) resolve("glProgramUniform2fv"); + ProgramUniform2i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint, GLint)) resolve("glProgramUniform2i"); + ProgramUniform2iv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLint *)) resolve("glProgramUniform2iv"); + ProgramUniform2ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint, GLuint)) resolve("glProgramUniform2ui"); + ProgramUniform2uiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLuint *)) resolve("glProgramUniform2uiv"); + ProgramUniform3f = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLfloat, GLfloat, GLfloat)) resolve("glProgramUniform3f"); + ProgramUniform3fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLfloat *)) resolve("glProgramUniform3fv"); + ProgramUniform3i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint, GLint, GLint)) resolve("glProgramUniform3i"); + ProgramUniform3iv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLint *)) resolve("glProgramUniform3iv"); + ProgramUniform3ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint, GLuint, GLuint)) resolve("glProgramUniform3ui"); + ProgramUniform3uiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLuint *)) resolve("glProgramUniform3uiv"); + ProgramUniform4f = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLfloat, GLfloat, GLfloat, GLfloat)) resolve("glProgramUniform4f"); + ProgramUniform4fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLfloat *)) resolve("glProgramUniform4fv"); + ProgramUniform4i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint, GLint, GLint, GLint)) resolve("glProgramUniform4i"); + ProgramUniform4iv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLint *)) resolve("glProgramUniform4iv"); + ProgramUniform4ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint, GLuint, GLuint, GLuint)) resolve("glProgramUniform4ui"); + ProgramUniform4uiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLuint *)) resolve("glProgramUniform4uiv"); + ProgramUniformMatrix2fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix2fv"); + ProgramUniformMatrix2x3fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix2x3fv"); + ProgramUniformMatrix2x4fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix2x4fv"); + ProgramUniformMatrix3fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix3fv"); + ProgramUniformMatrix3x2fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix3x2fv"); + ProgramUniformMatrix3x4fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix3x4fv"); + ProgramUniformMatrix4fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix4fv"); + ProgramUniformMatrix4x2fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix4x2fv"); + ProgramUniformMatrix4x3fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix4x3fv"); + SampleMaski = (void (QOPENGLF_APIENTRYP) (GLuint, GLbitfield)) resolve("glSampleMaski"); + TexStorage2DMultisample = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLboolean)) resolve("glTexStorage2DMultisample"); + UseProgramStages = (void (QOPENGLF_APIENTRYP) (GLuint, GLbitfield, GLuint)) resolve("glUseProgramStages"); + ValidateProgramPipeline = (void (QOPENGLF_APIENTRYP) (GLuint)) resolve("glValidateProgramPipeline"); + VertexAttribBinding = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glVertexAttribBinding"); + VertexAttribFormat = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLenum, GLboolean, GLuint)) resolve("glVertexAttribFormat"); + VertexAttribIFormat = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLenum, GLuint)) resolve("glVertexAttribIFormat"); + VertexBindingDivisor = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glVertexBindingDivisor"); + + if (!ActiveShaderProgram || !BindImageTexture || !DispatchCompute || !DrawArraysIndirect + || !GenProgramPipelines || !MemoryBarrierFunc) { + qWarning("OpenGL ES 3.1 entry points not found. This is odd because the driver returned a context of version %d.%d", + contextVersion.first, contextVersion.second); + return; + } + m_supportedVersion = qMakePair(3, 1); + } + } else { + qFatal("Failed to load libGLESv2"); + } +} + +// GLES 3.0 and 3.1 + +// Checks for true OpenGL ES 3.x. OpenGL with GL_ARB_ES3_compatibility +// does not count because there the plain resolvers work anyhow. +static inline bool isES3(int minor) +{ + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + + const bool libMatches = QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES; + const bool contextMatches = ctx->isOpenGLES() && ctx->format().version() >= qMakePair(3, minor); + + // Resolving happens whenever qgles3Helper() is called first. So do it only + // when the driver gives a 3.0+ context. + if (libMatches && contextMatches) + return qgles3Helper()->supportedVersion() >= qMakePair(3, minor); + + return false; +} + +// Go through the dlsym-based helper for real ES 3, resolve using +// wglGetProcAddress or similar when on plain OpenGL. + +static void QOPENGLF_APIENTRY qopenglfResolveBeginQuery(GLenum target, GLuint id) +{ + if (isES3(0)) + qgles3Helper()->BeginQuery(target, id); + else + RESOLVE_FUNC_VOID(0, BeginQuery)(target, id); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBeginTransformFeedback(GLenum primitiveMode) +{ + if (isES3(0)) + qgles3Helper()->BeginTransformFeedback(primitiveMode); + else + RESOLVE_FUNC_VOID(0, BeginTransformFeedback)(primitiveMode); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindBufferBase(GLenum target, GLuint index, GLuint buffer) +{ + if (isES3(0)) + qgles3Helper()->BindBufferBase(target, index, buffer); + else + RESOLVE_FUNC_VOID(0, BindBufferBase)(target, index, buffer); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +{ + if (isES3(0)) + qgles3Helper()->BindBufferRange(target, index, buffer, offset, size); + else + RESOLVE_FUNC_VOID(0, BindBufferRange)(target, index, buffer, offset, size); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindSampler(GLuint unit, GLuint sampler) +{ + if (isES3(0)) + qgles3Helper()->BindSampler(unit, sampler); + else + RESOLVE_FUNC_VOID(0, BindSampler)(unit, sampler); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindTransformFeedback(GLenum target, GLuint id) +{ + if (isES3(0)) + qgles3Helper()->BindTransformFeedback(target, id); + else + RESOLVE_FUNC_VOID(0, BindTransformFeedback)(target, id); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindVertexArray(GLuint array) +{ + if (isES3(0)) + qgles3Helper()->BindVertexArray(array); + else + RESOLVE_FUNC_VOID(0, BindVertexArray)(array); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) +{ + if (isES3(0)) + qgles3Helper()->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + else + RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, BlitFramebuffer) + (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +} + +static void QOPENGLF_APIENTRY qopenglfResolveClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) +{ + if (isES3(0)) + qgles3Helper()->ClearBufferfi(buffer, drawbuffer, depth, stencil); + else + RESOLVE_FUNC_VOID(0, ClearBufferfi)(buffer, drawbuffer, depth, stencil); +} + +static void QOPENGLF_APIENTRY qopenglfResolveClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat * value) +{ + if (isES3(0)) + qgles3Helper()->ClearBufferfv(buffer, drawbuffer, value); + else + RESOLVE_FUNC_VOID(0, ClearBufferfv)(buffer, drawbuffer, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint * value) +{ + if (isES3(0)) + qgles3Helper()->ClearBufferiv(buffer, drawbuffer, value); + else + RESOLVE_FUNC_VOID(0, ClearBufferiv)(buffer, drawbuffer, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint * value) +{ + if (isES3(0)) + qgles3Helper()->ClearBufferuiv(buffer, drawbuffer, value); + else + RESOLVE_FUNC_VOID(0, ClearBufferuiv)(buffer, drawbuffer, value); +} + +static GLenum QOPENGLF_APIENTRY qopenglfResolveClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + if (isES3(0)) + return qgles3Helper()->ClientWaitSync(sync, flags, timeout); + else + RESOLVE_FUNC(GLenum, 0, ClientWaitSync)(sync, flags, timeout); +} + +static void QOPENGLF_APIENTRY qopenglfResolveCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data) +{ + if (isES3(0)) + qgles3Helper()->CompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data); + else + RESOLVE_FUNC_VOID(0, CompressedTexImage3D)(target, level, internalformat, width, height, depth, border, imageSize, data); +} + +static void QOPENGLF_APIENTRY qopenglfResolveCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data) +{ + if (isES3(0)) + qgles3Helper()->CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); + else + RESOLVE_FUNC_VOID(0, CompressedTexSubImage3D)(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); +} + +static void QOPENGLF_APIENTRY qopenglfResolveCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) +{ + if (isES3(0)) + qgles3Helper()->CopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size); + else + RESOLVE_FUNC_VOID(0, CopyBufferSubData)(readTarget, writeTarget, readOffset, writeOffset, size); +} + +static void QOPENGLF_APIENTRY qopenglfResolveCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +{ + if (isES3(0)) + qgles3Helper()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); + else + RESOLVE_FUNC_VOID(0, CopyTexSubImage3D)(target, level, xoffset, yoffset, zoffset, x, y, width, height); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDeleteQueries(GLsizei n, const GLuint * ids) +{ + if (isES3(0)) + qgles3Helper()->DeleteQueries(n, ids); + else + RESOLVE_FUNC_VOID(0, DeleteQueries)(n, ids); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDeleteSamplers(GLsizei count, const GLuint * samplers) +{ + if (isES3(0)) + qgles3Helper()->DeleteSamplers(count, samplers); + else + RESOLVE_FUNC_VOID(0, DeleteSamplers)(count, samplers); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDeleteSync(GLsync sync) +{ + if (isES3(0)) + qgles3Helper()->DeleteSync(sync); + else + RESOLVE_FUNC_VOID(0, DeleteSync)(sync); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDeleteTransformFeedbacks(GLsizei n, const GLuint * ids) +{ + if (isES3(0)) + qgles3Helper()->DeleteTransformFeedbacks(n, ids); + else + RESOLVE_FUNC_VOID(0, DeleteTransformFeedbacks)(n, ids); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDeleteVertexArrays(GLsizei n, const GLuint * arrays) +{ + if (isES3(0)) + qgles3Helper()->DeleteVertexArrays(n, arrays); + else + RESOLVE_FUNC_VOID(0, DeleteVertexArrays)(n, arrays); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) +{ + if (isES3(0)) + qgles3Helper()->DrawArraysInstanced(mode, first, count, instancecount); + else + RESOLVE_FUNC_VOID(0, DrawArraysInstanced)(mode, first, count, instancecount); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDrawBuffers(GLsizei n, const GLenum * bufs) +{ + if (isES3(0)) + qgles3Helper()->DrawBuffers(n, bufs); + else + RESOLVE_FUNC_VOID(0, DrawBuffers)(n, bufs); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount) +{ + if (isES3(0)) + qgles3Helper()->DrawElementsInstanced(mode, count, type, indices, instancecount); + else + RESOLVE_FUNC_VOID(0, DrawElementsInstanced)(mode, count, type, indices, instancecount); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices) +{ + if (isES3(0)) + qgles3Helper()->DrawRangeElements(mode, start, end, count, type, indices); + else + RESOLVE_FUNC_VOID(0, DrawRangeElements)(mode, start, end, count, type, indices); +} + +static void QOPENGLF_APIENTRY qopenglfResolveEndQuery(GLenum target) +{ + if (isES3(0)) + qgles3Helper()->EndQuery(target); + else + RESOLVE_FUNC_VOID(0, EndQuery)(target); +} + +static void QOPENGLF_APIENTRY qopenglfResolveEndTransformFeedback() +{ + if (isES3(0)) + qgles3Helper()->EndTransformFeedback(); + else + RESOLVE_FUNC_VOID(0, EndTransformFeedback)(); +} + +static GLsync QOPENGLF_APIENTRY qopenglfResolveFenceSync(GLenum condition, GLbitfield flags) +{ + if (isES3(0)) + return qgles3Helper()->FenceSync(condition, flags); + else + RESOLVE_FUNC(GLsync, 0, FenceSync)(condition, flags); +} + +static void QOPENGLF_APIENTRY qopenglfResolveFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) +{ + if (isES3(0)) + qgles3Helper()->FlushMappedBufferRange(target, offset, length); + else + RESOLVE_FUNC_VOID(0, FlushMappedBufferRange)(target, offset, length); +} + +static void QOPENGLF_APIENTRY qopenglfResolveFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) +{ + if (isES3(0)) + qgles3Helper()->FramebufferTextureLayer(target, attachment, texture, level, layer); + else + RESOLVE_FUNC_VOID(0, FramebufferTextureLayer)(target, attachment, texture, level, layer); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGenQueries(GLsizei n, GLuint* ids) +{ + if (isES3(0)) + qgles3Helper()->GenQueries(n, ids); + else + RESOLVE_FUNC_VOID(0, GenQueries)(n, ids); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGenSamplers(GLsizei count, GLuint* samplers) +{ + if (isES3(0)) + qgles3Helper()->GenSamplers(count, samplers); + else + RESOLVE_FUNC_VOID(0, GenSamplers)(count, samplers); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGenTransformFeedbacks(GLsizei n, GLuint* ids) +{ + if (isES3(0)) + qgles3Helper()->GenTransformFeedbacks(n, ids); + else + RESOLVE_FUNC_VOID(0, GenTransformFeedbacks)(n, ids); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGenVertexArrays(GLsizei n, GLuint* arrays) +{ + if (isES3(0)) + qgles3Helper()->GenVertexArrays(n, arrays); + else + RESOLVE_FUNC_VOID(0, GenVertexArrays)(n, arrays); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) +{ + if (isES3(0)) + qgles3Helper()->GetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName); + else + RESOLVE_FUNC_VOID(0, GetActiveUniformBlockName)(program, uniformBlockIndex, bufSize, length, uniformBlockName); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) +{ + if (isES3(0)) + qgles3Helper()->GetActiveUniformBlockiv(program, uniformBlockIndex, pname, params); + else + RESOLVE_FUNC_VOID(0, GetActiveUniformBlockiv)(program, uniformBlockIndex, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint* params) +{ + if (isES3(0)) + qgles3Helper()->GetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params); + else + RESOLVE_FUNC_VOID(0, GetActiveUniformsiv)(program, uniformCount, uniformIndices, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) +{ + if (isES3(0)) + qgles3Helper()->GetBufferParameteri64v(target, pname, params); + else + RESOLVE_FUNC_VOID(0, GetBufferParameteri64v)(target, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetBufferPointerv(GLenum target, GLenum pname, void ** params) +{ + if (isES3(0)) + qgles3Helper()->GetBufferPointerv(target, pname, params); + else + RESOLVE_FUNC_VOID(0, GetBufferPointerv)(target, pname, params); +} + +static GLint QOPENGLF_APIENTRY qopenglfResolveGetFragDataLocation(GLuint program, const GLchar * name) +{ + if (isES3(0)) + return qgles3Helper()->GetFragDataLocation(program, name); + else + RESOLVE_FUNC(GLint, 0, GetFragDataLocation)(program, name); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetInteger64i_v(GLenum target, GLuint index, GLint64* data) +{ + if (isES3(0)) + qgles3Helper()->GetInteger64i_v(target, index, data); + else + RESOLVE_FUNC_VOID(0, GetInteger64i_v)(target, index, data); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetInteger64v(GLenum pname, GLint64* data) +{ + if (isES3(0)) + qgles3Helper()->GetInteger64v(pname, data); + else + RESOLVE_FUNC_VOID(0, GetInteger64v)(pname, data); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetIntegeri_v(GLenum target, GLuint index, GLint* data) +{ + if (isES3(0)) + qgles3Helper()->GetIntegeri_v(target, index, data); + else + RESOLVE_FUNC_VOID(0, GetIntegeri_v)(target, index, data); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) +{ + if (isES3(0)) + qgles3Helper()->GetInternalformativ(target, internalformat, pname, bufSize, params); + else + RESOLVE_FUNC_VOID(0, GetInternalformativ)(target, internalformat, pname, bufSize, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void * binary) +{ + if (isES3(0)) + qgles3Helper()->GetProgramBinary(program, bufSize, length, binaryFormat, binary); + else + RESOLVE_FUNC_VOID(0, GetProgramBinary)(program, bufSize, length, binaryFormat, binary); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) +{ + if (isES3(0)) + qgles3Helper()->GetQueryObjectuiv(id, pname, params); + else + RESOLVE_FUNC_VOID(0, GetQueryObjectuiv)(id, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetQueryiv(GLenum target, GLenum pname, GLint* params) +{ + if (isES3(0)) + qgles3Helper()->GetQueryiv(target, pname, params); + else + RESOLVE_FUNC_VOID(0, GetQueryiv)(target, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) +{ + if (isES3(0)) + qgles3Helper()->GetSamplerParameterfv(sampler, pname, params); + else + RESOLVE_FUNC_VOID(0, GetSamplerParameterfv)(sampler, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) +{ + if (isES3(0)) + qgles3Helper()->GetSamplerParameteriv(sampler, pname, params); + else + RESOLVE_FUNC_VOID(0, GetSamplerParameteriv)(sampler, pname, params); +} + +static const GLubyte * QOPENGLF_APIENTRY qopenglfResolveGetStringi(GLenum name, GLuint index) +{ + if (isES3(0)) + return qgles3Helper()->GetStringi(name, index); + else + RESOLVE_FUNC(const GLubyte *, 0, GetStringi)(name, index); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) +{ + if (isES3(0)) + qgles3Helper()->GetSynciv(sync, pname, bufSize, length, values); + else + RESOLVE_FUNC_VOID(0, GetSynciv)(sync, pname, bufSize, length, values); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) +{ + if (isES3(0)) + qgles3Helper()->GetTransformFeedbackVarying(program, index, bufSize, length, size, type, name); + else + RESOLVE_FUNC_VOID(0, GetTransformFeedbackVarying)(program, index, bufSize, length, size, type, name); +} + +static GLuint QOPENGLF_APIENTRY qopenglfResolveGetUniformBlockIndex(GLuint program, const GLchar * uniformBlockName) +{ + if (isES3(0)) + return qgles3Helper()->GetUniformBlockIndex(program, uniformBlockName); + else + RESOLVE_FUNC(GLuint, 0, GetUniformBlockIndex)(program, uniformBlockName); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint* uniformIndices) +{ + if (isES3(0)) + qgles3Helper()->GetUniformIndices(program, uniformCount, uniformNames, uniformIndices); + else + RESOLVE_FUNC_VOID(0, GetUniformIndices)(program, uniformCount, uniformNames, uniformIndices); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetUniformuiv(GLuint program, GLint location, GLuint* params) +{ + if (isES3(0)) + qgles3Helper()->GetUniformuiv(program, location, params); + else + RESOLVE_FUNC_VOID(0, GetUniformuiv)(program, location, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) +{ + if (isES3(0)) + qgles3Helper()->GetVertexAttribIiv(index, pname, params); + else + RESOLVE_FUNC_VOID(0, GetVertexAttribIiv)(index, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) +{ + if (isES3(0)) + qgles3Helper()->GetVertexAttribIuiv(index, pname, params); + else + RESOLVE_FUNC_VOID(0, GetVertexAttribIuiv)(index, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments) +{ + if (isES3(0)) + qgles3Helper()->InvalidateFramebuffer(target, numAttachments, attachments); + else + RESOLVE_FUNC_VOID(0, InvalidateFramebuffer)(target, numAttachments, attachments); +} + +static void QOPENGLF_APIENTRY qopenglfResolveInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height) +{ + if (isES3(0)) + qgles3Helper()->InvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height); + else + RESOLVE_FUNC_VOID(0, InvalidateSubFramebuffer)(target, numAttachments, attachments, x, y, width, height); +} + +static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsQuery(GLuint id) +{ + if (isES3(0)) + return qgles3Helper()->IsQuery(id); + else + RESOLVE_FUNC(GLboolean, 0, IsQuery)(id); +} + +static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsSampler(GLuint sampler) +{ + if (isES3(0)) + return qgles3Helper()->IsSampler(sampler); + else + RESOLVE_FUNC(GLboolean, 0, IsSampler)(sampler); +} + +static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsSync(GLsync sync) +{ + if (isES3(0)) + return qgles3Helper()->IsSync(sync); + else + RESOLVE_FUNC(GLboolean, 0, IsSync)(sync); +} + +static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsTransformFeedback(GLuint id) +{ + if (isES3(0)) + return qgles3Helper()->IsTransformFeedback(id); + else + RESOLVE_FUNC(GLboolean, 0, IsTransformFeedback)(id); +} + +static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsVertexArray(GLuint array) +{ + if (isES3(0)) + return qgles3Helper()->IsVertexArray(array); + else + RESOLVE_FUNC(GLboolean, 0, IsVertexArray)(array); +} + +static void * QOPENGLF_APIENTRY qopenglfResolveMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +{ + if (isES3(0)) + return qgles3Helper()->MapBufferRange(target, offset, length, access); + else + RESOLVE_FUNC(void *, 0, MapBufferRange)(target, offset, length, access); +} + +static void QOPENGLF_APIENTRY qopenglfResolvePauseTransformFeedback() +{ + if (isES3(0)) + qgles3Helper()->PauseTransformFeedback(); + else + RESOLVE_FUNC_VOID(0, PauseTransformFeedback)(); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramBinary(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length) +{ + if (isES3(0)) + qgles3Helper()->ProgramBinary(program, binaryFormat, binary, length); + else + RESOLVE_FUNC_VOID(0, ProgramBinary)(program, binaryFormat, binary, length); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramParameteri(GLuint program, GLenum pname, GLint value) +{ + if (isES3(0)) + qgles3Helper()->ProgramParameteri(program, pname, value); + else + RESOLVE_FUNC_VOID(0, ProgramParameteri)(program, pname, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveReadBuffer(GLenum src) +{ + if (isES3(0)) + qgles3Helper()->ReadBuffer(src); + else + RESOLVE_FUNC_VOID(0, ReadBuffer)(src); +} + +static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +{ + if (isES3(0)) + qgles3Helper()->RenderbufferStorageMultisample(target, samples, internalformat, width, height); + else + RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, RenderbufferStorageMultisample) + (target, samples, internalformat, width, height); +} + +static void QOPENGLF_APIENTRY qopenglfResolveResumeTransformFeedback() +{ + if (isES3(0)) + qgles3Helper()->ResumeTransformFeedback(); + else + RESOLVE_FUNC_VOID(0, ResumeTransformFeedback)(); +} + +static void QOPENGLF_APIENTRY qopenglfResolveSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) +{ + if (isES3(0)) + qgles3Helper()->SamplerParameterf(sampler, pname, param); + else + RESOLVE_FUNC_VOID(0, SamplerParameterf)(sampler, pname, param); +} + +static void QOPENGLF_APIENTRY qopenglfResolveSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat * param) +{ + if (isES3(0)) + qgles3Helper()->SamplerParameterfv(sampler, pname, param); + else + RESOLVE_FUNC_VOID(0, SamplerParameterfv)(sampler, pname, param); +} + +static void QOPENGLF_APIENTRY qopenglfResolveSamplerParameteri(GLuint sampler, GLenum pname, GLint param) +{ + if (isES3(0)) + qgles3Helper()->SamplerParameteri(sampler, pname, param); + else + RESOLVE_FUNC_VOID(0, SamplerParameteri)(sampler, pname, param); +} + +static void QOPENGLF_APIENTRY qopenglfResolveSamplerParameteriv(GLuint sampler, GLenum pname, const GLint * param) +{ + if (isES3(0)) + qgles3Helper()->SamplerParameteriv(sampler, pname, param); + else + RESOLVE_FUNC_VOID(0, SamplerParameteriv)(sampler, pname, param); +} + +static void QOPENGLF_APIENTRY qopenglfResolveTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels) +{ + if (isES3(0)) + qgles3Helper()->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels); + else + RESOLVE_FUNC_VOID(0, TexImage3D)(target, level, internalformat, width, height, depth, border, format, type, pixels); +} + +static void QOPENGLF_APIENTRY qopenglfResolveTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +{ + if (isES3(0)) + qgles3Helper()->TexStorage2D(target, levels, internalformat, width, height); + else + RESOLVE_FUNC_VOID(0, TexStorage2D)(target, levels, internalformat, width, height); +} + +static void QOPENGLF_APIENTRY qopenglfResolveTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +{ + if (isES3(0)) + qgles3Helper()->TexStorage3D(target, levels, internalformat, width, height, depth); + else + RESOLVE_FUNC_VOID(0, TexStorage3D)(target, levels, internalformat, width, height, depth); +} + +static void QOPENGLF_APIENTRY qopenglfResolveTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels) +{ + if (isES3(0)) + qgles3Helper()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + else + RESOLVE_FUNC_VOID(0, TexSubImage3D)(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); +} + +static void QOPENGLF_APIENTRY qopenglfResolveTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode) +{ + if (isES3(0)) + qgles3Helper()->TransformFeedbackVaryings(program, count, varyings, bufferMode); + else + RESOLVE_FUNC_VOID(0, TransformFeedbackVaryings)(program, count, varyings, bufferMode); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform1ui(GLint location, GLuint v0) +{ + if (isES3(0)) + qgles3Helper()->Uniform1ui(location, v0); + else + RESOLVE_FUNC_VOID(0, Uniform1ui)(location, v0); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform1uiv(GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(0)) + qgles3Helper()->Uniform1uiv(location, count, value); + else + RESOLVE_FUNC_VOID(0, Uniform1uiv)(location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform2ui(GLint location, GLuint v0, GLuint v1) +{ + if (isES3(0)) + qgles3Helper()->Uniform2ui(location, v0, v1); + else + RESOLVE_FUNC_VOID(0, Uniform2ui)(location, v0, v1); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform2uiv(GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(0)) + qgles3Helper()->Uniform2uiv(location, count, value); + else + RESOLVE_FUNC_VOID(0, Uniform2uiv)(location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + if (isES3(0)) + qgles3Helper()->Uniform3ui(location, v0, v1, v2); + else + RESOLVE_FUNC_VOID(0, Uniform3ui)(location, v0, v1, v2); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform3uiv(GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(0)) + qgles3Helper()->Uniform3uiv(location, count, value); + else + RESOLVE_FUNC_VOID(0, Uniform3uiv)(location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + if (isES3(0)) + qgles3Helper()->Uniform4ui(location, v0, v1, v2, v3); + else + RESOLVE_FUNC_VOID(0, Uniform4ui)(location, v0, v1, v2, v3); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform4uiv(GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(0)) + qgles3Helper()->Uniform4uiv(location, count, value); + else + RESOLVE_FUNC_VOID(0, Uniform4uiv)(location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) +{ + if (isES3(0)) + qgles3Helper()->UniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + else + RESOLVE_FUNC_VOID(0, UniformBlockBinding)(program, uniformBlockIndex, uniformBlockBinding); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(0)) + qgles3Helper()->UniformMatrix2x3fv(location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, UniformMatrix2x3fv)(location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(0)) + qgles3Helper()->UniformMatrix2x4fv(location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, UniformMatrix2x4fv)(location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(0)) + qgles3Helper()->UniformMatrix3x2fv(location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, UniformMatrix3x2fv)(location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(0)) + qgles3Helper()->UniformMatrix3x4fv(location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, UniformMatrix3x4fv)(location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(0)) + qgles3Helper()->UniformMatrix4x2fv(location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, UniformMatrix4x2fv)(location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(0)) + qgles3Helper()->UniformMatrix4x3fv(location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, UniformMatrix4x3fv)(location, count, transpose, value); +} + +static GLboolean QOPENGLF_APIENTRY qopenglfResolveUnmapBuffer(GLenum target) +{ + if (isES3(0)) + return qgles3Helper()->UnmapBuffer(target); + else + RESOLVE_FUNC(GLboolean, ResolveOES, UnmapBuffer)(target); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribDivisor(GLuint index, GLuint divisor) +{ + if (isES3(0)) + qgles3Helper()->VertexAttribDivisor(index, divisor); + else + RESOLVE_FUNC_VOID(0, VertexAttribDivisor)(index, divisor); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) +{ + if (isES3(0)) + qgles3Helper()->VertexAttribI4i(index, x, y, z, w); + else + RESOLVE_FUNC_VOID(0, VertexAttribI4i)(index, x, y, z, w); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribI4iv(GLuint index, const GLint * v) +{ + if (isES3(0)) + qgles3Helper()->VertexAttribI4iv(index, v); + else + RESOLVE_FUNC_VOID(0, VertexAttribI4iv)(index, v); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) +{ + if (isES3(0)) + qgles3Helper()->VertexAttribI4ui(index, x, y, z, w); + else + RESOLVE_FUNC_VOID(0, VertexAttribI4ui)(index, x, y, z, w); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribI4uiv(GLuint index, const GLuint * v) +{ + if (isES3(0)) + qgles3Helper()->VertexAttribI4uiv(index, v); + else + RESOLVE_FUNC_VOID(0, VertexAttribI4uiv)(index, v); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) +{ + if (isES3(0)) + qgles3Helper()->VertexAttribIPointer(index, size, type, stride, pointer); + else + RESOLVE_FUNC_VOID(0, VertexAttribIPointer)(index, size, type, stride, pointer); +} + +static void QOPENGLF_APIENTRY qopenglfResolveWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + if (isES3(0)) + qgles3Helper()->WaitSync(sync, flags, timeout); + else + RESOLVE_FUNC_VOID(0, WaitSync)(sync, flags, timeout); +} + +static void QOPENGLF_APIENTRY qopenglfResolveActiveShaderProgram(GLuint pipeline, GLuint program) +{ + if (isES3(1)) + qgles3Helper()->ActiveShaderProgram(pipeline, program); + else + RESOLVE_FUNC_VOID(0, ActiveShaderProgram)(pipeline, program); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) +{ + if (isES3(1)) + qgles3Helper()->BindImageTexture(unit, texture, level, layered, layer, access, format); + else + RESOLVE_FUNC_VOID(0, BindImageTexture)(unit, texture, level, layered, layer, access, format); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindProgramPipeline(GLuint pipeline) +{ + if (isES3(1)) + qgles3Helper()->BindProgramPipeline(pipeline); + else + RESOLVE_FUNC_VOID(0, BindProgramPipeline)(pipeline); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) +{ + if (isES3(1)) + qgles3Helper()->BindVertexBuffer(bindingindex, buffer, offset, stride); + else + RESOLVE_FUNC_VOID(0, BindVertexBuffer)(bindingindex, buffer, offset, stride); +} + +static GLuint QOPENGLF_APIENTRY qopenglfResolveCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const* strings) +{ + if (isES3(1)) + return qgles3Helper()->CreateShaderProgramv(type, count, strings); + else + RESOLVE_FUNC(GLuint, 0, CreateShaderProgramv)(type, count, strings); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDeleteProgramPipelines(GLsizei n, const GLuint * pipelines) +{ + if (isES3(1)) + qgles3Helper()->DeleteProgramPipelines(n, pipelines); + else + RESOLVE_FUNC_VOID(0, DeleteProgramPipelines)(n, pipelines); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) +{ + if (isES3(1)) + qgles3Helper()->DispatchCompute(num_groups_x, num_groups_y, num_groups_z); + else + RESOLVE_FUNC_VOID(0, DispatchCompute)(num_groups_x, num_groups_y, num_groups_z); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDispatchComputeIndirect(GLintptr indirect) +{ + if (isES3(1)) + qgles3Helper()->DispatchComputeIndirect(indirect); + else + RESOLVE_FUNC_VOID(0, DispatchComputeIndirect)(indirect); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDrawArraysIndirect(GLenum mode, const void * indirect) +{ + if (isES3(1)) + qgles3Helper()->DrawArraysIndirect(mode, indirect); + else + RESOLVE_FUNC_VOID(0, DrawArraysIndirect)(mode, indirect); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDrawElementsIndirect(GLenum mode, GLenum type, const void * indirect) +{ + if (isES3(1)) + qgles3Helper()->DrawElementsIndirect(mode, type, indirect); + else + RESOLVE_FUNC_VOID(0, DrawElementsIndirect)(mode, type, indirect); +} + +static void QOPENGLF_APIENTRY qopenglfResolveFramebufferParameteri(GLenum target, GLenum pname, GLint param) +{ + if (isES3(1)) + qgles3Helper()->FramebufferParameteri(target, pname, param); + else + RESOLVE_FUNC_VOID(0, FramebufferParameteri)(target, pname, param); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGenProgramPipelines(GLsizei n, GLuint* pipelines) +{ + if (isES3(1)) + qgles3Helper()->GenProgramPipelines(n, pipelines); + else + RESOLVE_FUNC_VOID(0, GenProgramPipelines)(n, pipelines); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetBooleani_v(GLenum target, GLuint index, GLboolean* data) +{ + if (isES3(1)) + qgles3Helper()->GetBooleani_v(target, index, data); + else + RESOLVE_FUNC_VOID(0, GetBooleani_v)(target, index, data); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetFramebufferParameteriv(GLenum target, GLenum pname, GLint* params) +{ + if (isES3(1)) + qgles3Helper()->GetFramebufferParameteriv(target, pname, params); + else + RESOLVE_FUNC_VOID(0, GetFramebufferParameteriv)(target, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetMultisamplefv(GLenum pname, GLuint index, GLfloat* val) +{ + if (isES3(1)) + qgles3Helper()->GetMultisamplefv(pname, index, val); + else + RESOLVE_FUNC_VOID(0, GetMultisamplefv)(pname, index, val); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params) +{ + if (isES3(1)) + qgles3Helper()->GetProgramInterfaceiv(program, programInterface, pname, params); + else + RESOLVE_FUNC_VOID(0, GetProgramInterfaceiv)(program, programInterface, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) +{ + if (isES3(1)) + qgles3Helper()->GetProgramPipelineInfoLog(pipeline, bufSize, length, infoLog); + else + RESOLVE_FUNC_VOID(0, GetProgramPipelineInfoLog)(pipeline, bufSize, length, infoLog); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint* params) +{ + if (isES3(1)) + qgles3Helper()->GetProgramPipelineiv(pipeline, pname, params); + else + RESOLVE_FUNC_VOID(0, GetProgramPipelineiv)(pipeline, pname, params); +} + +static GLuint QOPENGLF_APIENTRY qopenglfResolveGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar * name) +{ + if (isES3(1)) + return qgles3Helper()->GetProgramResourceIndex(program, programInterface, name); + else + RESOLVE_FUNC(GLuint, 0, GetProgramResourceIndex)(program, programInterface, name); +} + +static GLint QOPENGLF_APIENTRY qopenglfResolveGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar * name) +{ + if (isES3(1)) + return qgles3Helper()->GetProgramResourceLocation(program, programInterface, name); + else + RESOLVE_FUNC(GLint, 0, GetProgramResourceLocation)(program, programInterface, name); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name) +{ + if (isES3(1)) + qgles3Helper()->GetProgramResourceName(program, programInterface, index, bufSize, length, name); + else + RESOLVE_FUNC_VOID(0, GetProgramResourceName)(program, programInterface, index, bufSize, length, name); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei* length, GLint* params) +{ + if (isES3(1)) + qgles3Helper()->GetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, params); + else + RESOLVE_FUNC_VOID(0, GetProgramResourceiv)(program, programInterface, index, propCount, props, bufSize, length, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params) +{ + if (isES3(1)) + qgles3Helper()->GetTexLevelParameterfv(target, level, pname, params); + else + RESOLVE_FUNC_VOID(0, GetTexLevelParameterfv)(target, level, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params) +{ + if (isES3(1)) + qgles3Helper()->GetTexLevelParameteriv(target, level, pname, params); + else + RESOLVE_FUNC_VOID(0, GetTexLevelParameteriv)(target, level, pname, params); +} + +static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsProgramPipeline(GLuint pipeline) +{ + if (isES3(1)) + return qgles3Helper()->IsProgramPipeline(pipeline); + else + RESOLVE_FUNC(GLboolean, 0, IsProgramPipeline)(pipeline); +} + +static void QOPENGLF_APIENTRY qopenglfResolveMemoryBarrier(GLbitfield barriers) +{ + if (isES3(1)) + qgles3Helper()->MemoryBarrierFunc(barriers); + else + RESOLVE_FUNC_VOID(0, MemoryBarrierFunc)(barriers); +} + +static void QOPENGLF_APIENTRY qopenglfResolveMemoryBarrierByRegion(GLbitfield barriers) +{ + if (isES3(1)) + qgles3Helper()->MemoryBarrierByRegion(barriers); + else + RESOLVE_FUNC_VOID(0, MemoryBarrierByRegion)(barriers); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1f(GLuint program, GLint location, GLfloat v0) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform1f(program, location, v0); + else + RESOLVE_FUNC_VOID(0, ProgramUniform1f)(program, location, v0); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform1fv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform1fv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1i(GLuint program, GLint location, GLint v0) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform1i(program, location, v0); + else + RESOLVE_FUNC_VOID(0, ProgramUniform1i)(program, location, v0); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform1iv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform1iv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1ui(GLuint program, GLint location, GLuint v0) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform1ui(program, location, v0); + else + RESOLVE_FUNC_VOID(0, ProgramUniform1ui)(program, location, v0); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform1uiv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform1uiv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform2f(program, location, v0, v1); + else + RESOLVE_FUNC_VOID(0, ProgramUniform2f)(program, location, v0, v1); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform2fv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform2fv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform2i(program, location, v0, v1); + else + RESOLVE_FUNC_VOID(0, ProgramUniform2i)(program, location, v0, v1); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform2iv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform2iv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform2ui(program, location, v0, v1); + else + RESOLVE_FUNC_VOID(0, ProgramUniform2ui)(program, location, v0, v1); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform2uiv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform2uiv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform3f(program, location, v0, v1, v2); + else + RESOLVE_FUNC_VOID(0, ProgramUniform3f)(program, location, v0, v1, v2); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform3fv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform3fv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform3i(program, location, v0, v1, v2); + else + RESOLVE_FUNC_VOID(0, ProgramUniform3i)(program, location, v0, v1, v2); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform3iv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform3iv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform3ui(program, location, v0, v1, v2); + else + RESOLVE_FUNC_VOID(0, ProgramUniform3ui)(program, location, v0, v1, v2); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform3uiv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform3uiv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform4f(program, location, v0, v1, v2, v3); + else + RESOLVE_FUNC_VOID(0, ProgramUniform4f)(program, location, v0, v1, v2, v3); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform4fv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform4fv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform4i(program, location, v0, v1, v2, v3); + else + RESOLVE_FUNC_VOID(0, ProgramUniform4i)(program, location, v0, v1, v2, v3); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform4iv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform4iv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform4ui(program, location, v0, v1, v2, v3); + else + RESOLVE_FUNC_VOID(0, ProgramUniform4ui)(program, location, v0, v1, v2, v3); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform4uiv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform4uiv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix2fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix2fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix2x3fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix2x3fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix2x4fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix2x4fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix3fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix3fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix3x2fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix3x2fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix3x4fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix3x4fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix4fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix4fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix4x2fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix4x2fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix4x3fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix4x3fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveSampleMaski(GLuint maskNumber, GLbitfield mask) +{ + if (isES3(1)) + qgles3Helper()->SampleMaski(maskNumber, mask); + else + RESOLVE_FUNC_VOID(0, SampleMaski)(maskNumber, mask); +} + +static void QOPENGLF_APIENTRY qopenglfResolveTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) +{ + if (isES3(1)) + qgles3Helper()->TexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); + else + RESOLVE_FUNC_VOID(0, TexStorage2DMultisample)(target, samples, internalformat, width, height, fixedsamplelocations); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) +{ + if (isES3(1)) + qgles3Helper()->UseProgramStages(pipeline, stages, program); + else + RESOLVE_FUNC_VOID(0, UseProgramStages)(pipeline, stages, program); +} + +static void QOPENGLF_APIENTRY qopenglfResolveValidateProgramPipeline(GLuint pipeline) +{ + if (isES3(1)) + qgles3Helper()->ValidateProgramPipeline(pipeline); + else + RESOLVE_FUNC_VOID(0, ValidateProgramPipeline)(pipeline); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribBinding(GLuint attribindex, GLuint bindingindex) +{ + if (isES3(1)) + qgles3Helper()->VertexAttribBinding(attribindex, bindingindex); + else + RESOLVE_FUNC_VOID(0, VertexAttribBinding)(attribindex, bindingindex); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) +{ + if (isES3(1)) + qgles3Helper()->VertexAttribFormat(attribindex, size, type, normalized, relativeoffset); + else + RESOLVE_FUNC_VOID(0, VertexAttribFormat)(attribindex, size, type, normalized, relativeoffset); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) +{ + if (isES3(1)) + qgles3Helper()->VertexAttribIFormat(attribindex, size, type, relativeoffset); + else + RESOLVE_FUNC_VOID(0, VertexAttribIFormat)(attribindex, size, type, relativeoffset); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexBindingDivisor(GLuint bindingindex, GLuint divisor) +{ + if (isES3(1)) + qgles3Helper()->VertexBindingDivisor(bindingindex, divisor); + else + RESOLVE_FUNC_VOID(0, VertexBindingDivisor)(bindingindex, divisor); +} + +QOpenGLExtraFunctions::QOpenGLExtraFunctions() +{ +} + +QOpenGLExtraFunctions::QOpenGLExtraFunctions(QOpenGLContext *context) + : QOpenGLFunctions(context) +{ +} + +QOpenGLExtraFunctionsPrivate::QOpenGLExtraFunctionsPrivate(QOpenGLContext *ctx) + : QOpenGLFunctionsPrivate(ctx) +{ + ReadBuffer = qopenglfResolveReadBuffer; + DrawRangeElements = qopenglfResolveDrawRangeElements; + TexImage3D = qopenglfResolveTexImage3D; + TexSubImage3D = qopenglfResolveTexSubImage3D; + CopyTexSubImage3D = qopenglfResolveCopyTexSubImage3D; + CompressedTexImage3D = qopenglfResolveCompressedTexImage3D; + CompressedTexSubImage3D = qopenglfResolveCompressedTexSubImage3D; + GenQueries = qopenglfResolveGenQueries; + DeleteQueries = qopenglfResolveDeleteQueries; + IsQuery = qopenglfResolveIsQuery; + BeginQuery = qopenglfResolveBeginQuery; + EndQuery = qopenglfResolveEndQuery; + GetQueryiv = qopenglfResolveGetQueryiv; + GetQueryObjectuiv = qopenglfResolveGetQueryObjectuiv; + UnmapBuffer = qopenglfResolveUnmapBuffer; + GetBufferPointerv = qopenglfResolveGetBufferPointerv; + DrawBuffers = qopenglfResolveDrawBuffers; + UniformMatrix2x3fv = qopenglfResolveUniformMatrix2x3fv; + UniformMatrix3x2fv = qopenglfResolveUniformMatrix3x2fv; + UniformMatrix2x4fv = qopenglfResolveUniformMatrix2x4fv; + UniformMatrix4x2fv = qopenglfResolveUniformMatrix4x2fv; + UniformMatrix3x4fv = qopenglfResolveUniformMatrix3x4fv; + UniformMatrix4x3fv = qopenglfResolveUniformMatrix4x3fv; + BlitFramebuffer = qopenglfResolveBlitFramebuffer; + RenderbufferStorageMultisample = qopenglfResolveRenderbufferStorageMultisample; + FramebufferTextureLayer = qopenglfResolveFramebufferTextureLayer; + MapBufferRange = qopenglfResolveMapBufferRange; + FlushMappedBufferRange = qopenglfResolveFlushMappedBufferRange; + BindVertexArray = qopenglfResolveBindVertexArray; + DeleteVertexArrays = qopenglfResolveDeleteVertexArrays; + GenVertexArrays = qopenglfResolveGenVertexArrays; + IsVertexArray = qopenglfResolveIsVertexArray; + GetIntegeri_v = qopenglfResolveGetIntegeri_v; + BeginTransformFeedback = qopenglfResolveBeginTransformFeedback; + EndTransformFeedback = qopenglfResolveEndTransformFeedback; + BindBufferRange = qopenglfResolveBindBufferRange; + BindBufferBase = qopenglfResolveBindBufferBase; + TransformFeedbackVaryings = qopenglfResolveTransformFeedbackVaryings; + GetTransformFeedbackVarying = qopenglfResolveGetTransformFeedbackVarying; + VertexAttribIPointer = qopenglfResolveVertexAttribIPointer; + GetVertexAttribIiv = qopenglfResolveGetVertexAttribIiv; + GetVertexAttribIuiv = qopenglfResolveGetVertexAttribIuiv; + VertexAttribI4i = qopenglfResolveVertexAttribI4i; + VertexAttribI4ui = qopenglfResolveVertexAttribI4ui; + VertexAttribI4iv = qopenglfResolveVertexAttribI4iv; + VertexAttribI4uiv = qopenglfResolveVertexAttribI4uiv; + GetUniformuiv = qopenglfResolveGetUniformuiv; + GetFragDataLocation = qopenglfResolveGetFragDataLocation; + Uniform1ui = qopenglfResolveUniform1ui; + Uniform2ui = qopenglfResolveUniform2ui; + Uniform3ui = qopenglfResolveUniform3ui; + Uniform4ui = qopenglfResolveUniform4ui; + Uniform1uiv = qopenglfResolveUniform1uiv; + Uniform2uiv = qopenglfResolveUniform2uiv; + Uniform3uiv = qopenglfResolveUniform3uiv; + Uniform4uiv = qopenglfResolveUniform4uiv; + ClearBufferiv = qopenglfResolveClearBufferiv; + ClearBufferuiv = qopenglfResolveClearBufferuiv; + ClearBufferfv = qopenglfResolveClearBufferfv; + ClearBufferfi = qopenglfResolveClearBufferfi; + GetStringi = qopenglfResolveGetStringi; + CopyBufferSubData = qopenglfResolveCopyBufferSubData; + GetUniformIndices = qopenglfResolveGetUniformIndices; + GetActiveUniformsiv = qopenglfResolveGetActiveUniformsiv; + GetUniformBlockIndex = qopenglfResolveGetUniformBlockIndex; + GetActiveUniformBlockiv = qopenglfResolveGetActiveUniformBlockiv; + GetActiveUniformBlockName = qopenglfResolveGetActiveUniformBlockName; + UniformBlockBinding = qopenglfResolveUniformBlockBinding; + DrawArraysInstanced = qopenglfResolveDrawArraysInstanced; + DrawElementsInstanced = qopenglfResolveDrawElementsInstanced; + FenceSync = qopenglfResolveFenceSync; + IsSync = qopenglfResolveIsSync; + DeleteSync = qopenglfResolveDeleteSync; + ClientWaitSync = qopenglfResolveClientWaitSync; + WaitSync = qopenglfResolveWaitSync; + GetInteger64v = qopenglfResolveGetInteger64v; + GetSynciv = qopenglfResolveGetSynciv; + GetInteger64i_v = qopenglfResolveGetInteger64i_v; + GetBufferParameteri64v = qopenglfResolveGetBufferParameteri64v; + GenSamplers = qopenglfResolveGenSamplers; + DeleteSamplers = qopenglfResolveDeleteSamplers; + IsSampler = qopenglfResolveIsSampler; + BindSampler = qopenglfResolveBindSampler; + SamplerParameteri = qopenglfResolveSamplerParameteri; + SamplerParameteriv = qopenglfResolveSamplerParameteriv; + SamplerParameterf = qopenglfResolveSamplerParameterf; + SamplerParameterfv = qopenglfResolveSamplerParameterfv; + GetSamplerParameteriv = qopenglfResolveGetSamplerParameteriv; + GetSamplerParameterfv = qopenglfResolveGetSamplerParameterfv; + VertexAttribDivisor = qopenglfResolveVertexAttribDivisor; + BindTransformFeedback = qopenglfResolveBindTransformFeedback; + DeleteTransformFeedbacks = qopenglfResolveDeleteTransformFeedbacks; + GenTransformFeedbacks = qopenglfResolveGenTransformFeedbacks; + IsTransformFeedback = qopenglfResolveIsTransformFeedback; + PauseTransformFeedback = qopenglfResolvePauseTransformFeedback; + ResumeTransformFeedback = qopenglfResolveResumeTransformFeedback; + GetProgramBinary = qopenglfResolveGetProgramBinary; + ProgramBinary = qopenglfResolveProgramBinary; + ProgramParameteri = qopenglfResolveProgramParameteri; + InvalidateFramebuffer = qopenglfResolveInvalidateFramebuffer; + InvalidateSubFramebuffer = qopenglfResolveInvalidateSubFramebuffer; + TexStorage2D = qopenglfResolveTexStorage2D; + TexStorage3D = qopenglfResolveTexStorage3D; + GetInternalformativ = qopenglfResolveGetInternalformativ; + + DispatchCompute = qopenglfResolveDispatchCompute; + DispatchComputeIndirect = qopenglfResolveDispatchComputeIndirect; + DrawArraysIndirect = qopenglfResolveDrawArraysIndirect; + DrawElementsIndirect = qopenglfResolveDrawElementsIndirect; + FramebufferParameteri = qopenglfResolveFramebufferParameteri; + GetFramebufferParameteriv = qopenglfResolveGetFramebufferParameteriv; + GetProgramInterfaceiv = qopenglfResolveGetProgramInterfaceiv; + GetProgramResourceIndex = qopenglfResolveGetProgramResourceIndex; + GetProgramResourceName = qopenglfResolveGetProgramResourceName; + GetProgramResourceiv = qopenglfResolveGetProgramResourceiv; + GetProgramResourceLocation = qopenglfResolveGetProgramResourceLocation; + UseProgramStages = qopenglfResolveUseProgramStages; + ActiveShaderProgram = qopenglfResolveActiveShaderProgram; + CreateShaderProgramv = qopenglfResolveCreateShaderProgramv; + BindProgramPipeline = qopenglfResolveBindProgramPipeline; + DeleteProgramPipelines = qopenglfResolveDeleteProgramPipelines; + GenProgramPipelines = qopenglfResolveGenProgramPipelines; + IsProgramPipeline = qopenglfResolveIsProgramPipeline; + GetProgramPipelineiv = qopenglfResolveGetProgramPipelineiv; + ProgramUniform1i = qopenglfResolveProgramUniform1i; + ProgramUniform2i = qopenglfResolveProgramUniform2i; + ProgramUniform3i = qopenglfResolveProgramUniform3i; + ProgramUniform4i = qopenglfResolveProgramUniform4i; + ProgramUniform1ui = qopenglfResolveProgramUniform1ui; + ProgramUniform2ui = qopenglfResolveProgramUniform2ui; + ProgramUniform3ui = qopenglfResolveProgramUniform3ui; + ProgramUniform4ui = qopenglfResolveProgramUniform4ui; + ProgramUniform1f = qopenglfResolveProgramUniform1f; + ProgramUniform2f = qopenglfResolveProgramUniform2f; + ProgramUniform3f = qopenglfResolveProgramUniform3f; + ProgramUniform4f = qopenglfResolveProgramUniform4f; + ProgramUniform1iv = qopenglfResolveProgramUniform1iv; + ProgramUniform2iv = qopenglfResolveProgramUniform2iv; + ProgramUniform3iv = qopenglfResolveProgramUniform3iv; + ProgramUniform4iv = qopenglfResolveProgramUniform4iv; + ProgramUniform1uiv = qopenglfResolveProgramUniform1uiv; + ProgramUniform2uiv = qopenglfResolveProgramUniform2uiv; + ProgramUniform3uiv = qopenglfResolveProgramUniform3uiv; + ProgramUniform4uiv = qopenglfResolveProgramUniform4uiv; + ProgramUniform1fv = qopenglfResolveProgramUniform1fv; + ProgramUniform2fv = qopenglfResolveProgramUniform2fv; + ProgramUniform3fv = qopenglfResolveProgramUniform3fv; + ProgramUniform4fv = qopenglfResolveProgramUniform4fv; + ProgramUniformMatrix2fv = qopenglfResolveProgramUniformMatrix2fv; + ProgramUniformMatrix3fv = qopenglfResolveProgramUniformMatrix3fv; + ProgramUniformMatrix4fv = qopenglfResolveProgramUniformMatrix4fv; + ProgramUniformMatrix2x3fv = qopenglfResolveProgramUniformMatrix2x3fv; + ProgramUniformMatrix3x2fv = qopenglfResolveProgramUniformMatrix3x2fv; + ProgramUniformMatrix2x4fv = qopenglfResolveProgramUniformMatrix2x4fv; + ProgramUniformMatrix4x2fv = qopenglfResolveProgramUniformMatrix4x2fv; + ProgramUniformMatrix3x4fv = qopenglfResolveProgramUniformMatrix3x4fv; + ProgramUniformMatrix4x3fv = qopenglfResolveProgramUniformMatrix4x3fv; + ValidateProgramPipeline = qopenglfResolveValidateProgramPipeline; + GetProgramPipelineInfoLog = qopenglfResolveGetProgramPipelineInfoLog; + BindImageTexture = qopenglfResolveBindImageTexture; + GetBooleani_v = qopenglfResolveGetBooleani_v; + MemoryBarrierFunc = qopenglfResolveMemoryBarrier; + MemoryBarrierByRegion = qopenglfResolveMemoryBarrierByRegion; + TexStorage2DMultisample = qopenglfResolveTexStorage2DMultisample; + GetMultisamplefv = qopenglfResolveGetMultisamplefv; + SampleMaski = qopenglfResolveSampleMaski; + GetTexLevelParameteriv = qopenglfResolveGetTexLevelParameteriv; + GetTexLevelParameterfv = qopenglfResolveGetTexLevelParameterfv; + BindVertexBuffer = qopenglfResolveBindVertexBuffer; + VertexAttribFormat = qopenglfResolveVertexAttribFormat; + VertexAttribIFormat = qopenglfResolveVertexAttribIFormat; + VertexAttribBinding = qopenglfResolveVertexAttribBinding; + VertexBindingDivisor = qopenglfResolveVertexBindingDivisor; +} + +QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx) + : QOpenGLExtraFunctionsPrivate(ctx), + flushVendorChecked(false) +{ + MapBuffer = qopenglfResolveMapBuffer; GetBufferSubData = qopenglfResolveGetBufferSubData; DiscardFramebuffer = qopenglfResolveDiscardFramebuffer; } diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h index 4a3490b9f8585795bd13bd095e8a750b14f40a3a..ca002642d84cdd241a5a5b5c1fddeae4b3e1ad92 100644 --- a/src/gui/opengl/qopenglfunctions.h +++ b/src/gui/opengl/qopenglfunctions.h @@ -241,7 +241,8 @@ public: NPOTTextures = 0x1000, NPOTTextureRepeat = 0x2000, FixedFunctionPipeline = 0x4000, - TextureRGFormats = 0x8000 + TextureRGFormats = 0x8000, + MultipleRenderTargets = 0x10000 }; Q_DECLARE_FLAGS(OpenGLFeatures, OpenGLFeature) @@ -402,7 +403,7 @@ public: protected: QOpenGLFunctionsPrivate *d_ptr; - static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; } + static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != Q_NULLPTR; } }; Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLFunctions::OpenGLFeatures) diff --git a/src/gui/opengl/qopenglgradientcache.cpp b/src/gui/opengl/qopenglgradientcache.cpp index 6622d4805f7de657cf431b66d176bc2812890797..13bad9aabb504c9924dc98f09bd9287ec44d43d0 100644 --- a/src/gui/opengl/qopenglgradientcache.cpp +++ b/src/gui/opengl/qopenglgradientcache.cpp @@ -39,10 +39,6 @@ #include "qopenglfunctions.h" #include "qopenglextensions_p.h" -#ifndef GL_RGBA8 -#define GL_RGBA8 0x8058 -#endif - #ifndef GL_RGBA16 #define GL_RGBA16 0x805B #endif @@ -147,19 +143,19 @@ GLuint QOpenGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient } CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode()); - QRgba64 buffer[1024]; - generateGradientColorTable(gradient, buffer, paletteSize(), opacity); funcs->glGenTextures(1, &cache_entry.texId); funcs->glBindTexture(GL_TEXTURE_2D, cache_entry.texId); - GLenum internalFormat = GL_RGBA16; - if (QOpenGLContext::currentContext()->isOpenGLES()) { - if (static_cast<QOpenGLExtensions*>(funcs)->hasOpenGLExtension(QOpenGLExtensions::Sized8Formats)) - internalFormat = GL_RGBA8; - else - internalFormat = GL_RGBA; // Let OpenGLES use whatever it prefers. + if (static_cast<QOpenGLExtensions *>(funcs)->hasOpenGLExtension(QOpenGLExtensions::Sized16Formats)) { + QRgba64 buffer[1024]; + generateGradientColorTable(gradient, buffer, paletteSize(), opacity); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, paletteSize(), 1, + 0, GL_RGBA, GL_UNSIGNED_SHORT, buffer); + } else { + uint buffer[1024]; + generateGradientColorTable(gradient, buffer, paletteSize(), opacity); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1, + 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); } - funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, paletteSize(), 1, - 0, GL_RGBA, GL_UNSIGNED_SHORT, buffer); return cache.insert(hash_val, cache_entry).value().texId; } @@ -220,4 +216,59 @@ void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient colorTable[size-1] = last_color; } +void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const +{ + int pos = 0; + QGradientStops s = gradient.stops(); + QVector<uint> colors(s.size()); + + for (int i = 0; i < s.size(); ++i) + colors[i] = s[i].second.rgba(); // Qt LIES! It returns ARGB (on little-endian AND on big-endian) + + bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation); + + uint alpha = qRound(opacity * 256); + uint current_color = ARGB_COMBINE_ALPHA(colors[0], alpha); + qreal incr = 1.0 / qreal(size); + qreal fpos = 1.5 * incr; + colorTable[pos++] = ARGB2RGBA(qPremultiply(current_color)); + + while (fpos <= s.first().first) { + colorTable[pos] = colorTable[pos - 1]; + pos++; + fpos += incr; + } + + if (colorInterpolation) + current_color = qPremultiply(current_color); + + for (int i = 0; i < s.size() - 1; ++i) { + qreal delta = 1/(s[i+1].first - s[i].first); + uint next_color = ARGB_COMBINE_ALPHA(colors[i+1], alpha); + if (colorInterpolation) + next_color = qPremultiply(next_color); + + while (fpos < s[i+1].first && pos < size) { + int dist = int(256 * ((fpos - s[i].first) * delta)); + int idist = 256 - dist; + if (colorInterpolation) + colorTable[pos] = ARGB2RGBA(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)); + else + colorTable[pos] = ARGB2RGBA(qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist))); + ++pos; + fpos += incr; + } + current_color = next_color; + } + + Q_ASSERT(s.size() > 0); + + uint last_color = ARGB2RGBA(qPremultiply(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha))); + for (;pos < size; ++pos) + colorTable[pos] = last_color; + + // Make sure the last color stop is represented at the end of the table + colorTable[size-1] = last_color; +} + QT_END_NAMESPACE diff --git a/src/gui/opengl/qopenglgradientcache_p.h b/src/gui/opengl/qopenglgradientcache_p.h index d368f4bcfc2afcf8cbaac85502e6f924f7a72bdd..f2cc082250c9080419e408abe70d0a18ac8ecf2d 100644 --- a/src/gui/opengl/qopenglgradientcache_p.h +++ b/src/gui/opengl/qopenglgradientcache_p.h @@ -59,7 +59,7 @@ class QOpenGL2GradientCache : public QOpenGLSharedResource struct CacheInfo { inline CacheInfo(QGradientStops s, qreal op, QGradient::InterpolationMode mode) : - stops(s), opacity(op), interpolationMode(mode) {} + stops(qMove(s)), opacity(op), interpolationMode(mode) {} GLuint texId; QGradientStops stops; @@ -86,6 +86,9 @@ private: inline void generateGradientColorTable(const QGradient& gradient, QRgba64 *colorTable, int size, qreal opacity) const; + inline void generateGradientColorTable(const QGradient& gradient, + uint *colorTable, + int size, qreal opacity) const; GLuint addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity); void cleanCache(); diff --git a/src/gui/opengl/qopenglpaintdevice.cpp b/src/gui/opengl/qopenglpaintdevice.cpp index e509b26a95559dde359c62c115dc80a58d086c3f..17a32774d823dab0bb3770b3209b1ec4585adcbe 100644 --- a/src/gui/opengl/qopenglpaintdevice.cpp +++ b/src/gui/opengl/qopenglpaintdevice.cpp @@ -275,6 +275,9 @@ int QOpenGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const return qRound(d_ptr->dpmy * 0.0254); case PdmDevicePixelRatio: return d_ptr->devicePixelRatio; + case PdmDevicePixelRatioScaled: + return d_ptr->devicePixelRatio * QPaintDevice::devicePixelRatioFScale(); + default: qWarning("QOpenGLPaintDevice::metric() - metric %d not known", metric); return 0; diff --git a/src/gui/opengl/qopenglpixeltransferoptions.h b/src/gui/opengl/qopenglpixeltransferoptions.h index bf726813bd823aa58eb81a18a0009615605b1843..cb4697ec7c3cb46264ab69daf948c279a9a97389 100644 --- a/src/gui/opengl/qopenglpixeltransferoptions.h +++ b/src/gui/opengl/qopenglpixeltransferoptions.h @@ -49,15 +49,14 @@ class Q_GUI_EXPORT QOpenGLPixelTransferOptions public: QOpenGLPixelTransferOptions(); QOpenGLPixelTransferOptions(const QOpenGLPixelTransferOptions &); - QOpenGLPixelTransferOptions &operator=(const QOpenGLPixelTransferOptions &); - ~QOpenGLPixelTransferOptions(); - #ifdef Q_COMPILER_RVALUE_REFS - QOpenGLPixelTransferOptions &operator=(QOpenGLPixelTransferOptions &&other) + QOpenGLPixelTransferOptions &operator=(QOpenGLPixelTransferOptions &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif + QOpenGLPixelTransferOptions &operator=(const QOpenGLPixelTransferOptions &); + ~QOpenGLPixelTransferOptions(); - void swap(QOpenGLPixelTransferOptions &other) + void swap(QOpenGLPixelTransferOptions &other) Q_DECL_NOTHROW { data.swap(other.data); } void setAlignment(int alignment); diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp index 5de79c9e1eef36ac412c70f10ef270f9d809e2d2..41d53be31e74b3a6fb5d66371d97cac1f1fc4a10 100644 --- a/src/gui/opengl/qopenglshaderprogram.cpp +++ b/src/gui/opengl/qopenglshaderprogram.cpp @@ -1776,7 +1776,7 @@ void QOpenGLShaderProgram::setAttributeBuffer Q_UNUSED(d); if (location != -1) { d->glfuncs->glVertexAttribPointer(location, tupleSize, type, GL_TRUE, stride, - reinterpret_cast<const void *>(offset)); + reinterpret_cast<const void *>(qintptr(offset))); } } diff --git a/src/gui/opengl/qopenglshaderprogram.h b/src/gui/opengl/qopenglshaderprogram.h index 9f5957e61250b9fad6352ceccfca39a00d9971dc..b9599547189607956fe2feff50758da84d0c19ee 100644 --- a/src/gui/opengl/qopenglshaderprogram.h +++ b/src/gui/opengl/qopenglshaderprogram.h @@ -66,7 +66,7 @@ public: }; Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit) - explicit QOpenGLShader(QOpenGLShader::ShaderType type, QObject *parent = 0); + explicit QOpenGLShader(QOpenGLShader::ShaderType type, QObject *parent = Q_NULLPTR); virtual ~QOpenGLShader(); QOpenGLShader::ShaderType shaderType() const; @@ -83,7 +83,7 @@ public: GLuint shaderId() const; - static bool hasOpenGLShaders(ShaderType type, QOpenGLContext *context = 0); + static bool hasOpenGLShaders(ShaderType type, QOpenGLContext *context = Q_NULLPTR); private: friend class QOpenGLShaderProgram; @@ -101,7 +101,7 @@ class Q_GUI_EXPORT QOpenGLShaderProgram : public QObject { Q_OBJECT public: - explicit QOpenGLShaderProgram(QObject *parent = 0); + explicit QOpenGLShaderProgram(QObject *parent = Q_NULLPTR); virtual ~QOpenGLShaderProgram(); bool addShader(QOpenGLShader *shader); @@ -288,7 +288,7 @@ public: void setUniformValueArray(const char *name, const QMatrix4x3 *values, int count); void setUniformValueArray(const char *name, const QMatrix4x4 *values, int count); - static bool hasOpenGLShaderPrograms(QOpenGLContext *context = 0); + static bool hasOpenGLShaderPrograms(QOpenGLContext *context = Q_NULLPTR); private Q_SLOTS: void shaderDestroyed(); diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index baa702a98205326aca212c25849b602f06eb499c..5edaddcd6ae737ff9ffa189139532e85147f078d 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -1112,6 +1112,7 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub mipLevelSize(mipLevel, dimensions[0]), 1, sourceFormat, sourceType, data, options); + break; case QOpenGLTexture::Target2D: Q_UNUSED(layer); @@ -1210,6 +1211,7 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe mipLevelSize(mipLevel, dimensions[0]), 1, format, dataSize, data, options); + break; case QOpenGLTexture::Target2D: Q_UNUSED(layer); diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h index 3017aac737f77a6ed017bf0f886470e95ed680c1..baab2d634fcfa3875e0571ca7a497dff145ce167 100644 --- a/src/gui/opengl/qopengltexture.h +++ b/src/gui/opengl/qopengltexture.h @@ -409,54 +409,54 @@ public: #if QT_DEPRECATED_SINCE(5, 3) QT_DEPRECATED void setData(int mipLevel, int layer, CubeMapFace cubeFace, PixelFormat sourceFormat, PixelType sourceType, - void *data, const QOpenGLPixelTransferOptions * const options = 0); + void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); QT_DEPRECATED void setData(int mipLevel, int layer, PixelFormat sourceFormat, PixelType sourceType, - void *data, const QOpenGLPixelTransferOptions * const options = 0); + void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); QT_DEPRECATED void setData(int mipLevel, PixelFormat sourceFormat, PixelType sourceType, - void *data, const QOpenGLPixelTransferOptions * const options = 0); + void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); QT_DEPRECATED void setData(PixelFormat sourceFormat, PixelType sourceType, - void *data, const QOpenGLPixelTransferOptions * const options = 0); + void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); #endif // QT_DEPRECATED_SINCE(5, 3) void setData(int mipLevel, int layer, CubeMapFace cubeFace, PixelFormat sourceFormat, PixelType sourceType, - const void *data, const QOpenGLPixelTransferOptions * const options = 0); + const void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); void setData(int mipLevel, int layer, PixelFormat sourceFormat, PixelType sourceType, - const void *data, const QOpenGLPixelTransferOptions * const options = 0); + const void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); void setData(int mipLevel, PixelFormat sourceFormat, PixelType sourceType, - const void *data, const QOpenGLPixelTransferOptions * const options = 0); + const void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); void setData(PixelFormat sourceFormat, PixelType sourceType, - const void *data, const QOpenGLPixelTransferOptions * const options = 0); + const void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); // Compressed data upload // ### Qt 6: remove the non-const void * overloads #if QT_DEPRECATED_SINCE(5, 3) QT_DEPRECATED void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace, int dataSize, void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); QT_DEPRECATED void setCompressedData(int mipLevel, int layer, int dataSize, void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); QT_DEPRECATED void setCompressedData(int mipLevel, int dataSize, void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); QT_DEPRECATED void setCompressedData(int dataSize, void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); #endif // QT_DEPRECATED_SINCE(5, 3) void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace, int dataSize, const void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); void setCompressedData(int mipLevel, int layer, int dataSize, const void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); void setCompressedData(int mipLevel, int dataSize, const void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); void setCompressedData(int dataSize, const void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); // Helpful overloads for setData void setData(const QImage& image, MipMapGeneration genMipMaps = GenerateMipMaps); diff --git a/src/gui/opengl/qopengltexturehelper.cpp b/src/gui/opengl/qopengltexturehelper.cpp index 5276e5800f8e6db128852a483473030f9f041720..c5fa2163b3f7c5f7c9bca53f80e5aae916954917 100644 --- a/src/gui/opengl/qopengltexturehelper.cpp +++ b/src/gui/opengl/qopengltexturehelper.cpp @@ -101,6 +101,8 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context) // Use our own DSA emulation TextureParameteri = &QOpenGLTextureHelper::qt_TextureParameteri; TextureParameteriv = &QOpenGLTextureHelper::qt_TextureParameteriv; + TextureParameterf = &QOpenGLTextureHelper::qt_TextureParameterf; + TextureParameterfv = &QOpenGLTextureHelper::qt_TextureParameterfv; GenerateTextureMipmap = &QOpenGLTextureHelper::qt_GenerateTextureMipmap; TextureStorage3D = &QOpenGLTextureHelper::qt_TextureStorage3D; TextureStorage2D = &QOpenGLTextureHelper::qt_TextureStorage2D; diff --git a/src/gui/opengl/qopengltimerquery.h b/src/gui/opengl/qopengltimerquery.h index 7e46250546d8c044747b80c253da7a1e1479d763..ad111dc03c15605530c777b1f86c2a7028882889 100644 --- a/src/gui/opengl/qopengltimerquery.h +++ b/src/gui/opengl/qopengltimerquery.h @@ -50,7 +50,7 @@ class Q_GUI_EXPORT QOpenGLTimerQuery : public QObject Q_OBJECT public: - explicit QOpenGLTimerQuery(QObject *parent = 0); + explicit QOpenGLTimerQuery(QObject *parent = Q_NULLPTR); ~QOpenGLTimerQuery(); bool create(); @@ -78,7 +78,7 @@ class Q_GUI_EXPORT QOpenGLTimeMonitor : public QObject Q_OBJECT public: - explicit QOpenGLTimeMonitor(QObject *parent = 0); + explicit QOpenGLTimeMonitor(QObject *parent = Q_NULLPTR); ~QOpenGLTimeMonitor(); void setSampleCount(int sampleCount); diff --git a/src/gui/opengl/qopenglversionfunctions.h b/src/gui/opengl/qopenglversionfunctions.h index 2fd3b9dab9bf3277ca45c57d235144ac00d4d75c..a5d5677938e9e8de3f37385c5e6f7982f70caddb 100644 --- a/src/gui/opengl/qopenglversionfunctions.h +++ b/src/gui/opengl/qopenglversionfunctions.h @@ -123,7 +123,7 @@ class QAbstractOpenGLFunctionsPrivate { public: QAbstractOpenGLFunctionsPrivate() - : owningContext(0), + : owningContext(Q_NULLPTR), initialized(false) {} diff --git a/src/gui/opengl/qopenglvertexarrayobject.h b/src/gui/opengl/qopenglvertexarrayobject.h index 3e01d31202660c9621ac806e53a98e796459ec44..e8ebf41071c8db37fdeb6b031bba79f3c7537ffd 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.h +++ b/src/gui/opengl/qopenglvertexarrayobject.h @@ -50,7 +50,7 @@ class Q_GUI_EXPORT QOpenGLVertexArrayObject : public QObject Q_OBJECT public: - explicit QOpenGLVertexArrayObject(QObject* parent = 0); + explicit QOpenGLVertexArrayObject(QObject* parent = Q_NULLPTR); ~QOpenGLVertexArrayObject(); bool create(); diff --git a/src/gui/opengl/qtriangulatingstroker.cpp b/src/gui/opengl/qtriangulatingstroker.cpp index cfbf8a75c547fa52806721f94d11676793616f5b..5967bd6e89b9e80e6198b5421378656a33749898 100644 --- a/src/gui/opengl/qtriangulatingstroker.cpp +++ b/src/gui/opengl/qtriangulatingstroker.cpp @@ -127,7 +127,7 @@ void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, co m_roundness = 1; } else if (cosmetic) { m_curvyness_add = realWidth / 2; - m_curvyness_mul = CURVE_FLATNESS; + m_curvyness_mul = float(CURVE_FLATNESS); m_roundness = qMax<int>(4, realWidth * CURVE_FLATNESS); } else { m_curvyness_add = m_width; @@ -543,7 +543,7 @@ void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, c curvynessMul = CURVE_FLATNESS / m_inv_scale; } else if (cosmetic) { curvynessAdd= width / 2; - curvynessMul= CURVE_FLATNESS; + curvynessMul= float(CURVE_FLATNESS); } else { curvynessAdd = width * m_inv_scale; curvynessMul = CURVE_FLATNESS / m_inv_scale; diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 19074e4c47c4831a79d3256c67b2372e6254932c..4136c29d4e004f370003925027a1712723c45163 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -38,10 +38,13 @@ #include <qpa/qplatformintegration.h> #include <qscreen.h> #include <qdebug.h> +#include <qscopedpointer.h> #include <private/qguiapplication_p.h> #include <private/qwindow_p.h> +#include <private/qhighdpiscaling_p.h> + QT_BEGIN_NAMESPACE class QBackingStorePrivate @@ -54,6 +57,7 @@ public: QWindow *window; QPlatformBackingStore *platformBackingStore; + QScopedPointer<QImage> highDpiBackingstore; QRegion staticContents; QSize size; }; @@ -102,7 +106,7 @@ void QBackingStore::flush(const QRegion ®ion, QWindow *win, const QPoint &off } #endif - d_ptr->platformBackingStore->flush(win, region, offset); + d_ptr->platformBackingStore->flush(win, QHighDpi::toNativeLocalRegion(region, d_ptr->window), offset); } /*! @@ -112,7 +116,12 @@ void QBackingStore::flush(const QRegion ®ion, QWindow *win, const QPoint &off */ QPaintDevice *QBackingStore::paintDevice() { - return d_ptr->platformBackingStore->paintDevice(); + QPaintDevice *device = d_ptr->platformBackingStore->paintDevice(); + + if (QHighDpiScaling::isActive() && device->devType() == QInternal::Image) + return d_ptr->highDpiBackingstore.data(); + + return device; } /*! @@ -150,7 +159,36 @@ QWindow* QBackingStore::window() const void QBackingStore::beginPaint(const QRegion ®ion) { - d_ptr->platformBackingStore->beginPaint(region); + if (d_ptr->highDpiBackingstore && + d_ptr->highDpiBackingstore->devicePixelRatio() != d_ptr->window->devicePixelRatio()) + resize(size()); + + d_ptr->platformBackingStore->beginPaint(QHighDpi::toNativeLocalRegion(region, d_ptr->window)); + + // When QtGui is applying a high-dpi scale factor the backing store + // creates a "large" backing store image. This image needs to be + // painted on as a high-dpi image, which is done by setting + // devicePixelRatio. Do this on a separate image instance that shares + // the image data to avoid having the new devicePixelRatio be propagated + // back to the platform plugin. + QPaintDevice *device = d_ptr->platformBackingStore->paintDevice(); + if (QHighDpiScaling::isActive() && device->devType() == QInternal::Image) { + QImage *source = static_cast<QImage *>(device); + const bool needsNewImage = d_ptr->highDpiBackingstore.isNull() + || source->data_ptr() != d_ptr->highDpiBackingstore->data_ptr() + || source->size() != d_ptr->highDpiBackingstore->size() + || source->devicePixelRatio() != d_ptr->highDpiBackingstore->devicePixelRatio(); + if (needsNewImage) { + qCDebug(lcScaling) << "QBackingStore::beginPaint new backingstore for" << d_ptr->window; + qCDebug(lcScaling) << " source size" << source->size() << "dpr" << source->devicePixelRatio(); + d_ptr->highDpiBackingstore.reset( + new QImage(source->bits(), source->width(), source->height(), source->format())); + qreal targetDevicePixelRatio = d_ptr->window->devicePixelRatio(); + d_ptr->highDpiBackingstore->setDevicePixelRatio(targetDevicePixelRatio); + qCDebug(lcScaling) <<" destination size" << d_ptr->highDpiBackingstore->size() + << "dpr" << targetDevicePixelRatio; + } + } } /*! @@ -171,7 +209,7 @@ void QBackingStore::endPaint() void QBackingStore::resize(const QSize &size) { d_ptr->size = size; - d_ptr->platformBackingStore->resize(size, d_ptr->staticContents); + d_ptr->platformBackingStore->resize(QHighDpi::toNativePixels(size, d_ptr->window), d_ptr->staticContents); } /*! @@ -194,7 +232,7 @@ bool QBackingStore::scroll(const QRegion &area, int dx, int dy) Q_UNUSED(dx); Q_UNUSED(dy); - return d_ptr->platformBackingStore->scroll(area, dx, dy); + return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window), QHighDpi::toNativePixels(dx, d_ptr->window), QHighDpi::toNativePixels(dy, d_ptr->window)); } void QBackingStore::setStaticContents(const QRegion ®ion) diff --git a/src/gui/painting/qbackingstore.h b/src/gui/painting/qbackingstore.h index ee3c05f7a928ea022ae847b93c9dd3ac36cf50a5..331fa8c53489ecbd128b5d4036c2572612c0bcdf 100644 --- a/src/gui/painting/qbackingstore.h +++ b/src/gui/painting/qbackingstore.h @@ -61,7 +61,7 @@ public: // 'window' can be a child window, in which case 'region' is in child window coordinates and // offset is the (child) window's offset in relation to the window surface. - void flush(const QRegion ®ion, QWindow *window = 0, const QPoint &offset = QPoint()); + void flush(const QRegion ®ion, QWindow *window = Q_NULLPTR, const QPoint &offset = QPoint()); void resize(const QSize &size); QSize size() const; diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index b3710411c9fa26244c6e7849b012ddfc43ae44a1..dbdd82e432eda01926d6aee0b50b5b2eb88c3198 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -422,8 +422,8 @@ static void qt_blend_argb32pm_on_a2rgb30pm(uchar *destPixels, int dbpl, const_alpha = (const_alpha * 255) >> 8; for (int y=0; y<h; ++y) { for (int x=0; x<w; ++x) { - uint s = BYTE_MUL(src[x], const_alpha); - dst[x] = qConvertArgb32ToA2rgb30<PixelOrder>(s) + BYTE_MUL_RGB30(dst[x], 255 - qAlpha(s)); + uint s = src[x]; + dst[x] = BYTE_MUL_RGB30(qConvertArgb32ToA2rgb30<PixelOrder>(s), const_alpha) + BYTE_MUL_RGB30(dst[x], 255 - qt_div_255(qAlpha(s) * const_alpha)); } dst = (quint32 *)(((uchar *) dst) + dbpl); src = (const quint32 *)(((const uchar *) src) + sbpl); diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index 670717c5f186513355e6d34c410c4917d1a8aa2b..d6eb8d8a48c12a3b878559cc3b08099670dc0618 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -1163,6 +1163,7 @@ QDataStream &operator>>(QDataStream &s, QBrush &b) QColor c; s >> numStops; + stops.reserve(numStops); for (quint32 i = 0; i < numStops; ++i) { s >> n >> c; stops << QPair<qreal, QColor>(n, c); diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index f1ceb464c8c557b1272d3d7889347072737b9e73..1012ed7c6de7164608d4883ea20d9809379f914d 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -481,6 +481,7 @@ QColor::QColor(Spec spec) \sa setNamedColor(), name(), isValid() */ +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) /*! \fn QColor::QColor(const QColor &color) @@ -488,6 +489,7 @@ QColor::QColor(Spec spec) \sa isValid() */ +#endif /*! \fn bool QColor::isValid() const @@ -2385,6 +2387,7 @@ QColor QColor::dark(int factor) const return hsv.convertTo(cspec); } +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) /*! Assigns a copy of \a color to this color, and returns a reference to it. */ @@ -2394,6 +2397,7 @@ QColor &QColor::operator=(const QColor &color) ct.argb = color.ct.argb; return *this; } +#endif /*! \overload Assigns a copy of \a color and returns a reference to this color. diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h index 917587531026560893af0879773ab73c123dd75d..b0192662cc266fab04050705b5f3f21f219d19d7 100644 --- a/src/gui/painting/qcolor.h +++ b/src/gui/painting/qcolor.h @@ -67,9 +67,20 @@ public: QColor(QRgba64 rgba64); QColor(const QString& name); QColor(const char *name); - QColor(const QColor &color); // ### Qt 6: remove, the trivial one is fine. QColor(Spec spec); +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) + QColor(const QColor &color); // ### Qt 6: remove all of these, the trivial ones are fine. +# ifdef Q_COMPILER_RVALUE_REFS + QColor(QColor &&other) Q_DECL_NOTHROW : cspec(other.cspec), ct(other.ct) {} + QColor &operator=(QColor &&other) Q_DECL_NOTHROW + { cspec = other.cspec; ct = other.ct; return *this; } +# endif + QColor &operator=(const QColor &); +#endif // Qt < 6 + + QColor &operator=(Qt::GlobalColor color); + bool isValid() const; // ### Qt 6: merge overloads @@ -102,10 +113,10 @@ public: void setGreenF(qreal green); void setBlueF(qreal blue); - void getRgb(int *r, int *g, int *b, int *a = 0) const; + void getRgb(int *r, int *g, int *b, int *a = Q_NULLPTR) const; void setRgb(int r, int g, int b, int a = 255); - void getRgbF(qreal *r, qreal *g, qreal *b, qreal *a = 0) const; + void getRgbF(qreal *r, qreal *g, qreal *b, qreal *a = Q_NULLPTR) const; void setRgbF(qreal r, qreal g, qreal b, qreal a = 1.0); QRgb rgba() const; @@ -129,10 +140,10 @@ public: qreal hsvSaturationF() const; qreal valueF() const; - void getHsv(int *h, int *s, int *v, int *a = 0) const; + void getHsv(int *h, int *s, int *v, int *a = Q_NULLPTR) const; void setHsv(int h, int s, int v, int a = 255); - void getHsvF(qreal *h, qreal *s, qreal *v, qreal *a = 0) const; + void getHsvF(qreal *h, qreal *s, qreal *v, qreal *a = Q_NULLPTR) const; void setHsvF(qreal h, qreal s, qreal v, qreal a = 1.0); int cyan() const; @@ -145,10 +156,10 @@ public: qreal yellowF() const; qreal blackF() const; - void getCmyk(int *c, int *m, int *y, int *k, int *a = 0); + void getCmyk(int *c, int *m, int *y, int *k, int *a = Q_NULLPTR); void setCmyk(int c, int m, int y, int k, int a = 255); - void getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a = 0); + void getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a = Q_NULLPTR); void setCmykF(qreal c, qreal m, qreal y, qreal k, qreal a = 1.0); int hslHue() const; // 0 <= hue < 360 @@ -159,10 +170,10 @@ public: qreal hslSaturationF() const; qreal lightnessF() const; - void getHsl(int *h, int *s, int *l, int *a = 0) const; + void getHsl(int *h, int *s, int *l, int *a = Q_NULLPTR) const; void setHsl(int h, int s, int l, int a = 255); - void getHslF(qreal *h, qreal *s, qreal *l, qreal *a = 0) const; + void getHslF(qreal *h, qreal *s, qreal *l, qreal *a = Q_NULLPTR) const; void setHslF(qreal h, qreal s, qreal l, qreal a = 1.0); QColor toRgb() const; @@ -195,9 +206,6 @@ public: QColor dark(int f = 200) const Q_REQUIRED_RESULT; QColor darker(int f = 200) const Q_REQUIRED_RESULT; - QColor &operator=(const QColor &); - QColor &operator=(Qt::GlobalColor color); - bool operator==(const QColor &c) const; bool operator!=(const QColor &c) const; @@ -262,9 +270,11 @@ inline QColor::QColor(const char *aname) inline QColor::QColor(const QString& aname) { setNamedColor(aname); } +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) inline QColor::QColor(const QColor &acolor) : cspec(acolor.cspec) { ct.argb = acolor.ct.argb; } +#endif inline bool QColor::isValid() const { return cspec != Invalid; } diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 7b03cc00fff4c7b6a00d8a469faa422ad625d601..07e5a3d19b4d508e1c747bc246625c878a9b9ec3 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6291,6 +6291,10 @@ void qt_memfill32(quint32 *dest, quint32 color, int count) } #endif +#ifdef QT_COMPILER_SUPPORTS_SSE4_1 +template<QtPixelOrder> const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); +#endif + void qInitDrawhelperAsm() { const uint features = qCpuFeatures(); @@ -6352,7 +6356,7 @@ void qInitDrawhelperAsm() } #endif // SSSE3 -#if QT_COMPILER_SUPPORTS_SSE4_1 +#if defined(QT_COMPILER_SUPPORTS_SSE4_1) if (qCpuHasFeature(SSE4_1)) { #if !defined(__SSE4_1__) extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); @@ -6366,10 +6370,12 @@ void qInitDrawhelperAsm() qPixelLayouts[QImage::Format_ARGB32].convertFromARGB32PM = convertARGB32FromARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBA8888].convertFromARGB32PM = convertRGBA8888FromARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBX8888].convertFromARGB32PM = convertRGBXFromARGB32PM_sse4; + qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].convertFromARGB32PM = convertA2RGB30PMFromARGB32PM_sse4<PixelOrderBGR>; + qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].convertFromARGB32PM = convertA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>; } #endif -#if QT_COMPILER_SUPPORTS_AVX2 && !defined(__AVX2__) +#if defined(QT_COMPILER_SUPPORTS_AVX2) && !defined(__AVX2__) if (qCpuHasFeature(AVX2)) { extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); extern const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 179900ddd2efc2a757678e160e313e44be278118..2c222b97c2baeab564dbb7076832d14d1a0cf154 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -882,9 +882,25 @@ template<enum QtPixelOrder> inline uint qConvertRgb32ToRgb30(QRgb); template<enum QtPixelOrder> inline QRgb qConvertA2rgb30ToArgb32(uint c); +// A combined unpremultiply and premultiply with new simplified alpha. +// Needed when alpha loses precision relative to other colors during conversion (ARGB32 -> A2RGB30). +template<unsigned int Shift> +inline QRgb qRepremultiply(QRgb p) +{ + const uint alpha = qAlpha(p); + if (alpha == 255 || alpha == 0) + return p; + p = qUnpremultiply(p); + Q_CONSTEXPR uint mult = 255 / (255 >> Shift); + const uint newAlpha = mult * (alpha >> Shift); + p = (p & ~0xff000000) | (newAlpha<<24); + return qPremultiply(p); +} + template<> inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c) { + c = qRepremultiply<6>(c); return (c & 0xc0000000) | (((c << 22) & 0x3fc00000) | ((c << 14) & 0x00300000)) | (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00)) @@ -894,6 +910,7 @@ inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c) template<> inline uint qConvertArgb32ToA2rgb30<PixelOrderRGB>(QRgb c) { + c = qRepremultiply<6>(c); return (c & 0xc0000000) | (((c << 6) & 0x3fc00000) | ((c >> 2) & 0x00300000)) | (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00)) diff --git a/src/gui/painting/qdrawhelper_sse4.cpp b/src/gui/painting/qdrawhelper_sse4.cpp index 43a39589977a588697ed087e4a4b3c8bf07424b8..7cc498eefcdcc6f8ff47e93379fc51dd69370787 100644 --- a/src/gui/painting/qdrawhelper_sse4.cpp +++ b/src/gui/painting/qdrawhelper_sse4.cpp @@ -74,6 +74,22 @@ const uint *QT_FASTCALL convertRGBXFromARGB32PM_sse4(uint *buffer, const uint *s return buffer; } +template<QtPixelOrder PixelOrder> +const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = qConvertArgb32ToA2rgb30_sse4<PixelOrder>(src[i]); + return buffer; +} + +template +const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4<PixelOrderBGR>(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *); +template +const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *); + QT_END_NAMESPACE #endif diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h index 1a7dddf0d5c12631d2b9ad41fcb45b0108b019e9..c74055e4404134fd5252483484a143345fac09f7 100644 --- a/src/gui/painting/qdrawingprimitive_sse2_p.h +++ b/src/gui/painting/qdrawingprimitive_sse2_p.h @@ -35,6 +35,7 @@ #define QDRAWINGPRIMITIVE_SSE2_P_H #include <private/qsimd_p.h> +#include "qdrawhelper_p.h" #ifdef __SSE2__ @@ -256,6 +257,43 @@ inline QRgb qUnpremultiply_sse4(QRgb p) vl = _mm_packus_epi16(vl, vl); return _mm_cvtsi128_si32(vl); } + +template<enum QtPixelOrder PixelOrder> +QT_FUNCTION_TARGET(SSE4_1) +inline uint qConvertArgb32ToA2rgb30_sse4(QRgb p) +{ + const uint alpha = qAlpha(p); + if (alpha == 255) + return qConvertRgb32ToRgb30<PixelOrder>(p); + if (alpha == 0) + return 0; + Q_CONSTEXPR uint mult = 255 / (255 >> 6); + const uint invAlpha = qt_inv_premul_factor[alpha]; + const uint newalpha = (alpha >> 6); + const __m128i via = _mm_set1_epi32(invAlpha); + const __m128i vna = _mm_set1_epi32(mult * newalpha); + const __m128i vr1 = _mm_set1_epi32(0x1000); + const __m128i vr2 = _mm_set1_epi32(0x80); + __m128i vl = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(p)); + vl = _mm_mullo_epi32(vl, via); + vl = _mm_add_epi32(vl, vr1); + vl = _mm_srli_epi32(vl, 14); + vl = _mm_mullo_epi32(vl, vna); + vl = _mm_add_epi32(vl, _mm_srli_epi32(vl, 8)); + vl = _mm_add_epi32(vl, vr2); + vl = _mm_srli_epi32(vl, 8); + vl = _mm_packus_epi32(vl, vl); + uint rgb30 = (newalpha << 30); + rgb30 |= ((uint)_mm_extract_epi16(vl, 1)) << 10; + if (PixelOrder == PixelOrderRGB) { + rgb30 |= ((uint)_mm_extract_epi16(vl, 2)) << 20; + rgb30 |= ((uint)_mm_extract_epi16(vl, 0)); + } else { + rgb30 |= ((uint)_mm_extract_epi16(vl, 0)) << 20; + rgb30 |= ((uint)_mm_extract_epi16(vl, 2)); + } + return rgb30; +} #endif QT_END_NAMESPACE diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h index c036e4df93a32b44d099b77901c716699c481327..809a19a0b84e46d80e942ad5e777be85ebdf6e30 100644 --- a/src/gui/painting/qmatrix.h +++ b/src/gui/painting/qmatrix.h @@ -92,7 +92,7 @@ public: bool isInvertible() const { return !qFuzzyIsNull(_m11*_m22 - _m12*_m21); } qreal determinant() const { return _m11*_m22 - _m12*_m21; } - QMatrix inverted(bool *invertible = 0) const Q_REQUIRED_RESULT; + QMatrix inverted(bool *invertible = Q_NULLPTR) const Q_REQUIRED_RESULT; bool operator==(const QMatrix &) const; bool operator!=(const QMatrix &) const; diff --git a/src/gui/painting/qpagelayout.h b/src/gui/painting/qpagelayout.h index 17e5eeece2797ae77c5bbee2598ec1004f0b8db2..7eac348c431863f68cdfdc9239e8c7412bae92c7 100644 --- a/src/gui/painting/qpagelayout.h +++ b/src/gui/painting/qpagelayout.h @@ -75,14 +75,13 @@ public: const QMarginsF &margins, Unit units = Point, const QMarginsF &minMargins = QMarginsF(0, 0, 0, 0)); QPageLayout(const QPageLayout &other); - ~QPageLayout(); - - QPageLayout &operator=(const QPageLayout &other); - #ifdef Q_COMPILER_RVALUE_REFS - QPageLayout &operator=(QPageLayout &&other) { swap(other); return *this; } +#ifdef Q_COMPILER_RVALUE_REFS + QPageLayout &operator=(QPageLayout &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif + QPageLayout &operator=(const QPageLayout &other); + ~QPageLayout(); - void swap(QPageLayout &other) { d.swap(other.d); } + void swap(QPageLayout &other) Q_DECL_NOTHROW { qSwap(d, other.d); } friend Q_GUI_EXPORT bool operator==(const QPageLayout &lhs, const QPageLayout &rhs); bool isEquivalentTo(const QPageLayout &other) const; diff --git a/src/gui/painting/qpagesize.h b/src/gui/painting/qpagesize.h index 00e22a243fd2ddbe1c696b771987b1143cfad511..9119a582ace4f46c48830aad6393ebbd07856d2a 100644 --- a/src/gui/painting/qpagesize.h +++ b/src/gui/painting/qpagesize.h @@ -229,14 +229,14 @@ public: const QString &name = QString(), SizeMatchPolicy matchPolicy = FuzzyMatch); QPageSize(const QPageSize &other); - ~QPageSize(); - - QPageSize &operator=(const QPageSize &other); #ifdef Q_COMPILER_RVALUE_REFS - QPageSize &operator=(QPageSize &&other) { swap(other); return *this; } + QPageSize &operator=(QPageSize &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif + QPageSize &operator=(const QPageSize &other); + ~QPageSize(); + - void swap(QPageSize &other) { d.swap(other.d); } + void swap(QPageSize &other) Q_DECL_NOTHROW { qSwap(d, other.d); } friend Q_GUI_EXPORT bool operator==(const QPageSize &lhs, const QPageSize &rhs); bool isEquivalentTo(const QPageSize &other) const; diff --git a/src/gui/painting/qpaintdevice.cpp b/src/gui/painting/qpaintdevice.cpp index bbf8e8f17005b025a8e06a91abbad3de5056b49d..2332d11a0344a3af7ab2ce59c35fa132e1e0dee0 100644 --- a/src/gui/painting/qpaintdevice.cpp +++ b/src/gui/painting/qpaintdevice.cpp @@ -79,7 +79,13 @@ Q_GUI_EXPORT int qt_paint_device_metric(const QPaintDevice *device, QPaintDevice int QPaintDevice::metric(PaintDeviceMetric m) const { + // Fallback: A subclass has not implemented PdmDevicePixelRatioScaled but might + // have implemented PdmDevicePixelRatio. + if (m == PdmDevicePixelRatioScaled) + return this->metric(PdmDevicePixelRatio) * devicePixelRatioFScale(); + qWarning("QPaintDevice::metrics: Device has no metric information"); + if (m == PdmDpiX) { return 72; } else if (m == PdmDpiY) { diff --git a/src/gui/painting/qpaintdevice.h b/src/gui/painting/qpaintdevice.h index 4eb972786b7ba2026e6397bf049cb7a86abb7b91..c360573e78e850d575604d38e231b482f1fa38b2 100644 --- a/src/gui/painting/qpaintdevice.h +++ b/src/gui/painting/qpaintdevice.h @@ -58,7 +58,8 @@ public: PdmDpiY, PdmPhysicalDpiX, PdmPhysicalDpiY, - PdmDevicePixelRatio + PdmDevicePixelRatio, + PdmDevicePixelRatioScaled }; virtual ~QPaintDevice(); @@ -76,9 +77,11 @@ public: int physicalDpiX() const { return metric(PdmPhysicalDpiX); } int physicalDpiY() const { return metric(PdmPhysicalDpiY); } int devicePixelRatio() const { return metric(PdmDevicePixelRatio); } + qreal devicePixelRatioF() const { return metric(PdmDevicePixelRatioScaled) / devicePixelRatioFScale(); } int colorCount() const { return metric(PdmNumColors); } int depth() const { return metric(PdmDepth); } + static inline qreal devicePixelRatioFScale() {return 10000000.0; } protected: QPaintDevice() Q_DECL_NOEXCEPT; virtual int metric(PaintDeviceMetric metric) const; @@ -87,7 +90,6 @@ protected: virtual QPainter *sharedPainter() const; ushort painters; // refcount - private: Q_DISABLE_COPY(QPaintDevice) diff --git a/src/gui/painting/qpaintdevice.qdoc b/src/gui/painting/qpaintdevice.qdoc index 8db65af18e6d46674663e47ba878eb2b6da11ffb..a83acdd21ad8398606c9870a7b9e2050bf4195a0 100644 --- a/src/gui/painting/qpaintdevice.qdoc +++ b/src/gui/painting/qpaintdevice.qdoc @@ -286,3 +286,24 @@ Common values are 1 for normal-dpi displays and 2 for high-dpi "retina" displays. */ + +/*! + \fn qreal QPaintDevice::devicePixelRatioF() const + + Returns the device pixel ratio for the device as a floating point number. + + \since 5.6 +*/ + +/*! + \fn qreal QPaintDevice::devicePixelRatioFScale() + + \internal + + Returns the scaling factor used for \c PdmDevicePixelRatioScaled. Classes + that are not QPaintDevice subclasses are implementing metric(), and need to + access this constant. Since it's a qreal, it cannot be an enum, and an inline + function is more efficient than a static member variable. + + \since 5.6 +*/ diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index bf1f31a85bc997377d7d3d7304d62f0498294735..ef9309438734c76aed8cdeede113539f896331c9 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -149,7 +149,7 @@ QFont QTextItem::font() const provided is the raster paint engine, which contains a software rasterizer which supports the full feature set on all supported platforms. This is the default for painting on QWidget-based classes in e.g. on Windows, - X11 and Mac OS X, it is the backend for painting on QImage and it is + X11 and OS X, it is the backend for painting on QImage and it is used as a fallback for paint engines that do not support a certain capability. In addition we provide QPaintEngine implementations for OpenGL (accessible through QGLWidget) and printing (which allows using @@ -363,8 +363,8 @@ void QPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDraw \value X11 \value Windows \value MacPrinter - \value CoreGraphics Mac OS X's Quartz2D (CoreGraphics) - \value QuickDraw Mac OS X's QuickDraw + \value CoreGraphics OS X's Quartz2D (CoreGraphics) + \value QuickDraw OS X's QuickDraw \value QWindowSystem Qt for Embedded Linux \value PostScript (No longer supported) \value OpenGL diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h index eeca87ce16020cf6ce1f29a50a24fb9004cf428d..fa3fad1caa26ddb44765ff15443b962f8f35bc56 100644 --- a/src/gui/painting/qpaintengine.h +++ b/src/gui/painting/qpaintengine.h @@ -137,7 +137,7 @@ public: PolylineMode }; - explicit QPaintEngine(PaintEngineFeatures features=0); + explicit QPaintEngine(PaintEngineFeatures features=PaintEngineFeatures()); virtual ~QPaintEngine(); bool isActive() const { return active; } @@ -220,7 +220,7 @@ public: inline bool isExtended() const { return extended; } protected: - QPaintEngine(QPaintEnginePrivate &data, PaintEngineFeatures devcaps=0); + QPaintEngine(QPaintEnginePrivate &data, PaintEngineFeatures devcaps=PaintEngineFeatures()); QPaintEngineState *state; PaintEngineFeatures gccaps; diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 882a088d5c59e49c487b3d6c0ecbe4d8ce31a08f..28a62767465edf53b935558da958da2c591c5548 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -2752,12 +2752,12 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, QFixed spp = fontEngine->subPixelPositionForX(positions[i].x); QPoint offset; - QImage *alphaMap = fontEngine->lockedAlphaMapForGlyph(glyphs[i], spp, neededFormat, s->matrix, - &offset); + const QImage *alphaMap = fontEngine->lockedAlphaMapForGlyph(glyphs[i], spp, neededFormat, s->matrix, + &offset); if (alphaMap == 0 || alphaMap->isNull()) continue; - alphaPenBlt(alphaMap->bits(), alphaMap->bytesPerLine(), alphaMap->depth(), + alphaPenBlt(alphaMap->constBits(), alphaMap->bytesPerLine(), alphaMap->depth(), qFloor(positions[i].x) + offset.x(), qRound(positions[i].y) + offset.y(), alphaMap->width(), alphaMap->height()); @@ -4132,7 +4132,7 @@ class QGradientCache struct CacheInfo { inline CacheInfo(QGradientStops s, int op, QGradient::InterpolationMode mode) : - stops(s), opacity(op), interpolationMode(mode) {} + stops(qMove(s)), opacity(op), interpolationMode(mode) {} QRgba64 buffer[GRADIENT_STOPTABLE_SIZE]; QGradientStops stops; int opacity; diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index c17ea9c87887d023f1d783c6a9fa927f0d755aaf..e80c0130c3ff1714b2df5c3847a7c651a67e66e1 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -219,18 +219,18 @@ QTransform QPainterPrivate::viewTransform() const return QTransform(); } -int QPainterPrivate::effectiveDevicePixelRatio() const +qreal QPainterPrivate::effectiveDevicePixelRatio() const { // Special cases for devices that does not support PdmDevicePixelRatio go here: if (device->devType() == QInternal::Printer) - return 1; + return qreal(1); - return qMax(1, device->metric(QPaintDevice::PdmDevicePixelRatio)); + return qMax(qreal(1), device->devicePixelRatioF()); } QTransform QPainterPrivate::hidpiScaleTransform() const { - int devicePixelRatio = effectiveDevicePixelRatio(); + const qreal devicePixelRatio = effectiveDevicePixelRatio(); return QTransform::fromScale(devicePixelRatio, devicePixelRatio); } @@ -5110,7 +5110,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm) x += d->state->matrix.dx(); y += d->state->matrix.dy(); } - int scale = pm.devicePixelRatio(); + qreal scale = pm.devicePixelRatio(); d->engine->drawPixmap(QRectF(x, y, w / scale, h / scale), pm, QRectF(0, 0, w, h)); } } @@ -5966,8 +5966,17 @@ void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br \endtable The \a boundingRect (if not null) is set to the what the bounding rectangle - should be in order to enclose the whole text. The \a flags argument is a bitwise - OR of the following flags: + should be in order to enclose the whole text. For example, in the following + image, the dotted line represents \a boundingRect as calculated by the + function, and the dashed line represents \a rectangle: + + \table 100% + \row + \li \inlineimage qpainter-text-bounds.png + \li \snippet code/src_gui_painting_qpainter.cpp drawText + \endtable + + The \a flags argument is a bitwise OR of the following flags: \list \li Qt::AlignLeft @@ -6016,8 +6025,18 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF * \overload Draws the given \a text within the provided \a rectangle according - to the specified \a flags. The \a boundingRect (if not null) is set to - the what the bounding rectangle should be in order to enclose the whole text. + to the specified \a flags. + + The \a boundingRect (if not null) is set to the what the bounding rectangle + should be in order to enclose the whole text. For example, in the following + image, the dotted line represents \a boundingRect as calculated by the + function, and the dashed line represents \a rectangle: + + \table 100% + \row + \li \inlineimage qpainter-text-bounds.png + \li \snippet code/src_gui_painting_qpainter.cpp drawText + \endtable By default, QPainter draws text anti-aliased. @@ -6050,9 +6069,19 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF * Draws the given \a text within the rectangle with origin (\a{x}, \a{y}), \a width and \a height. - The \a boundingRect (if not null) is set to the actual bounding - rectangle of the output. The \a flags argument is a bitwise OR of - the following flags: + The \a boundingRect (if not null) is set to the what the bounding rectangle + should be in order to enclose the whole text. For example, in the following + image, the dotted line represents \a boundingRect as calculated by the + function, and the dashed line represents the rectangle defined by + \a x, \a y, \a width and \a height: + + \table 100% + \row + \li \inlineimage qpainter-text-bounds.png + \li \snippet code/src_gui_painting_qpainter.cpp drawText + \endtable + + The \a flags argument is a bitwise OR of the following flags: \list \li Qt::AlignLeft @@ -6177,7 +6206,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) QPen wavePen = pen; wavePen.setCapStyle(Qt::SquareCap); - // This is to protect against making the line too fat, as happens on Mac OS X + // This is to protect against making the line too fat, as happens on OS X // due to it having a rather thick width for the regular underline. const qreal maxPenWidth = .8 * radius; if (wavePen.widthF() > maxPenWidth) @@ -7497,6 +7526,7 @@ start_lengthVariant: if (engine.option.tabs().isEmpty() && ta) { QList<qreal> tabs; + tabs.reserve(tabarraylen); for (int i = 0; i < tabarraylen; i++) tabs.append(qreal(ta[i])); engine.option.setTabArray(tabs); diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index 51776a964219f10ef50ba76d3488e02107b5e367..8e2d17d3a52ae6a7dd48322c4ff29787fc7533ad 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -374,7 +374,7 @@ public: inline void drawPixmap(int x, int y, int w, int h, const QPixmap &pm); void drawPixmapFragments(const PixmapFragment *fragments, int fragmentCount, - const QPixmap &pixmap, PixmapFragmentHints hints = 0); + const QPixmap &pixmap, PixmapFragmentHints hints = PixmapFragmentHints()); void drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect, Qt::ImageConversionFlags flags = Qt::AutoColor); @@ -408,9 +408,9 @@ public: void drawText(const QPointF &p, const QString &str, int tf, int justificationPadding); - void drawText(const QRectF &r, int flags, const QString &text, QRectF *br=0); - void drawText(const QRect &r, int flags, const QString &text, QRect *br=0); - inline void drawText(int x, int y, int w, int h, int flags, const QString &text, QRect *br=0); + void drawText(const QRectF &r, int flags, const QString &text, QRectF *br = Q_NULLPTR); + void drawText(const QRect &r, int flags, const QString &text, QRect *br = Q_NULLPTR); + inline void drawText(int x, int y, int w, int h, int flags, const QString &text, QRect *br = Q_NULLPTR); void drawText(const QRectF &r, const QString &text, const QTextOption &o = QTextOption()); @@ -453,7 +453,7 @@ public: static void setRedirected(const QPaintDevice *device, QPaintDevice *replacement, const QPoint& offset = QPoint()); - static QPaintDevice *redirected(const QPaintDevice *device, QPoint *offset = 0); + static QPaintDevice *redirected(const QPaintDevice *device, QPoint *offset = Q_NULLPTR); static void restoreRedirected(const QPaintDevice *device); void beginNativePainting(); diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h index 3ea4e35b8d790eeb9dfc5005e83b7c90f181606c..e8b675365f88095a4340812797997bc9748a85ce 100644 --- a/src/gui/painting/qpainter_p.h +++ b/src/gui/painting/qpainter_p.h @@ -240,7 +240,7 @@ public: } QTransform viewTransform() const; - int effectiveDevicePixelRatio() const; + qreal effectiveDevicePixelRatio() const; QTransform hidpiScaleTransform() const; static bool attachPainterPrivate(QPainter *q, QPaintDevice *pdev); void detachPainterPrivate(QPainter *q); diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index e2f267d7eee444d09cc7e001d33db4d35729bd5b..48010c0a71dc9c51558fd2d1870d787977c6b541 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -218,7 +218,7 @@ static void qt_debug_path(const QPainterPath &path) Below is a code snippet that shows how a QPainterPath object can be used: - \table 100% + \table 70% \row \li \inlineimage qpainterpath-construction.png \li diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp index 0798418c1740746e227cc686c5784e20b086e8ee..513fdfa2b60c48e200ef8a092994a6199b667d0a 100644 --- a/src/gui/painting/qpathclipper.cpp +++ b/src/gui/painting/qpathclipper.cpp @@ -1889,10 +1889,10 @@ bool QPathClipper::handleCrossingEdges(QWingedEdge &list, qreal y, ClipperMode m namespace { -QList<QPainterPath> toSubpaths(const QPainterPath &path) +QVector<QPainterPath> toSubpaths(const QPainterPath &path) { - QList<QPainterPath> subpaths; + QVector<QPainterPath> subpaths; if (path.isEmpty()) return subpaths; @@ -2092,7 +2092,7 @@ QPainterPath clip(const QPainterPath &path, qreal t) QPainterPath intersectPath(const QPainterPath &path, const QRectF &rect) { - QList<QPainterPath> subpaths = toSubpaths(path); + QVector<QPainterPath> subpaths = toSubpaths(path); QPainterPath result; result.setFillRule(path.fillRule()); diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 6ea0800538bffb0a4b70fbd3f4a8f5bd4da847d2..7fa2e5bf09e6c8a6b02cb8e3c29fc42058c49e9d 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1318,6 +1318,9 @@ int QPdfEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const case QPaintDevice::PdmDevicePixelRatio: val = 1; break; + case QPaintDevice::PdmDevicePixelRatioScaled: + val = 1 * QPaintDevice::devicePixelRatioFScale(); + break; default: qWarning("QPdfWriter::metric: Invalid metric command"); return 0; @@ -1952,7 +1955,9 @@ int QPdfEnginePrivate::createShadingFunction(const QGradient *gradient, int from stops.append(QGradientStop(1, stops.at(stops.size() - 1).second)); QVector<int> functions; - for (int i = 0; i < stops.size() - 1; ++i) { + const int numStops = stops.size(); + functions.reserve(numStops - 1); + for (int i = 0; i < numStops - 1; ++i) { int f = addXrefEntry(-1); QByteArray data; QPdf::ByteStream s(&data); diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h index 94e74f30b9d8cc74fa6017b4be9eb0063c9b07dd..2b50cdc6f77b01711f03dc59a088dbaf6b2da9d3 100644 --- a/src/gui/painting/qpdf_p.h +++ b/src/gui/painting/qpdf_p.h @@ -243,7 +243,7 @@ public: QPointF brushOrigin; QBrush brush; QPen pen; - QList<QPainterPath> clips; + QVector<QPainterPath> clips; bool clipEnabled; bool allClipped; bool hasPen; diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp index 6263d18b01f429927d68c48564e1174dbd08446d..073d254b49e8754549a45f6c9c897e4b13317cc5 100644 --- a/src/gui/painting/qpen.cpp +++ b/src/gui/painting/qpen.cpp @@ -980,6 +980,7 @@ QDataStream &operator>>(QDataStream &s, QPen &p) quint32 numDashes; s >> numDashes; double dash; + dashPattern.reserve(numDashes); for (quint32 i = 0; i < numDashes; ++i) { s >> dash; dashPattern << dash; diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 62492980de3d9f2c4c8e5e96d426ded6ee37b130..e765a9e402484b4b8f02905676d85f043e612f76 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -100,7 +100,7 @@ public: { } - QList<QBackingstoreTextureInfo> textures; + QVector<QBackingstoreTextureInfo> textures; bool locked; }; @@ -220,7 +220,9 @@ static QRegion deviceRegion(const QRegion ®ion, QWindow *window) return region; QVector<QRect> rects; - foreach (QRect rect, region.rects()) + const QVector<QRect> regionRects = region.rects(); + rects.reserve(regionRects.count()); + foreach (const QRect &rect, regionRects) rects.append(deviceRect(rect, window)); QRegion deviceRegion; diff --git a/src/gui/painting/qpolygon.h b/src/gui/painting/qpolygon.h index 1549ebe2b5c918c83e56da72872fb4c81dd8748a..1e503c03b738be2262bb4dce02cee0f46dcb5145 100644 --- a/src/gui/painting/qpolygon.h +++ b/src/gui/painting/qpolygon.h @@ -52,11 +52,19 @@ public: inline QPolygon() {} inline ~QPolygon() {} inline explicit QPolygon(int size); - inline QPolygon(const QPolygon &a) : QVector<QPoint>(a) {} inline /*implicit*/ QPolygon(const QVector<QPoint> &v) : QVector<QPoint>(v) {} +#ifdef Q_COMPILER_RVALUE_REFS + /*implicit*/ QPolygon(QVector<QPoint> &&v) Q_DECL_NOTHROW : QVector<QPoint>(std::move(v)) {} +#endif QPolygon(const QRect &r, bool closed=false); QPolygon(int nPoints, const int *points); - inline void swap(QPolygon &other) { QVector<QPoint>::swap(other); } // prevent QVector<QPoint><->QPolygon swaps + QPolygon(const QPolygon &other) : QVector<QPoint>(other) {} +#ifdef Q_COMPILER_RVALUE_REFS + QPolygon(QPolygon &&other) Q_DECL_NOTHROW : QVector<QPoint>(std::move(other)) {} + QPolygon &operator=(QPolygon &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif + QPolygon &operator=(const QPolygon &other) { QVector<QPoint>::operator=(other); return *this; } + void swap(QPolygon &other) Q_DECL_NOTHROW { QVector<QPoint>::swap(other); } // prevent QVector<QPoint><->QPolygon swaps operator QVariant() const; @@ -126,10 +134,18 @@ public: inline QPolygonF() {} inline ~QPolygonF() {} inline explicit QPolygonF(int size); - inline QPolygonF(const QPolygonF &a) : QVector<QPointF>(a) {} inline /*implicit*/ QPolygonF(const QVector<QPointF> &v) : QVector<QPointF>(v) {} +#ifdef Q_COMPILER_RVALUE_REFS + /* implicit */ QPolygonF(QVector<QPointF> &&v) Q_DECL_NOTHROW : QVector<QPointF>(std::move(v)) {} +#endif QPolygonF(const QRectF &r); /*implicit*/ QPolygonF(const QPolygon &a); + inline QPolygonF(const QPolygonF &a) : QVector<QPointF>(a) {} +#ifdef Q_COMPILER_RVALUE_REFS + QPolygonF(QPolygonF &&other) Q_DECL_NOTHROW : QVector<QPointF>(std::move(other)) {} + QPolygonF &operator=(QPolygonF &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif + QPolygonF &operator=(const QPolygonF &other) { QVector<QPointF>::operator=(other); return *this; } inline void swap(QPolygonF &other) { QVector<QPointF>::swap(other); } // prevent QVector<QPointF><->QPolygonF swaps operator QVariant() const; diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index 19314ef84f305417fc8b9c52cd0ea1cba07d498c..e6b777a30ecc5026fa67b807468b7e34d4ab41d9 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -906,7 +906,7 @@ QRegion QRegion::intersect(const QRect &r) const sort key and X as the minor sort key. \endlist \omit - Only some platforms have these restrictions (Qt for Embedded Linux, X11 and Mac OS X). + Only some platforms have these restrictions (Qt for Embedded Linux, X11 and OS X). \endomit */ diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h index f967c091df2db942dc8ca32102ae8f40adfb1ca7..d3765bbd29be0e4b570c1f0df9ea85e71ae2a9cf 100644 --- a/src/gui/painting/qstroker_p.h +++ b/src/gui/painting/qstroker_p.h @@ -201,7 +201,7 @@ public: QStroker(); ~QStroker(); - void setStrokeWidth(qfixed width) { m_strokeWidth = width; m_curveThreshold = width >= 1 ? 1.0/width : 0.5;} + void setStrokeWidth(qfixed width) { m_strokeWidth = width; m_curveThreshold = qt_real_to_fixed(width > 4 ? 1.0/width : 0.25); } qfixed strokeWidth() const { return m_strokeWidth; } void setCapStyle(Qt::PenCapStyle capStyle) { m_capStyle = joinModeForCap(capStyle); } diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 056fd8b70164999c21da32ffdad332ae8ee8a77e..44e14f656d8aaf853f731dbd0269146fa104ee37 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -52,11 +52,14 @@ int QTextureGlyphCache::calculateSubPixelPositionCount(glyph_t glyph) const // Test 12 different subpixel positions since it factors into 3*4 so it gives // the coverage we need. - QList<QImage> images; - for (int i=0; i<12; ++i) { + const int NumSubpixelPositions = 12; + + QImage images[NumSubpixelPositions]; + int numImages = 0; + for (int i = 0; i < NumSubpixelPositions; ++i) { QImage img = textureMapForGlyph(glyph, QFixed::fromReal(i / 12.0)); - if (images.isEmpty()) { + if (numImages == 0) { QPainterPath path; QFixedPoint point; m_current_fontengine->addGlyphsToPath(&glyph, &point, 1, &path, QTextItem::RenderFlags()); @@ -65,21 +68,21 @@ int QTextureGlyphCache::calculateSubPixelPositionCount(glyph_t glyph) const if (path.isEmpty()) break; - images.append(img); + images[numImages++] = qMove(img); } else { bool found = false; - for (int j=0; j<images.size(); ++j) { - if (images.at(j) == img) { + for (int j = 0; j < numImages; ++j) { + if (images[j] == img) { found = true; break; } } if (!found) - images.append(img); + images[numImages++] = qMove(img); } } - return images.size(); + return numImages; } bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs, diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index fca2b72249c8ee88fbcb74c48b2fb97faa0a0e3d..a23aabe559fb3d71f58d11dd93cbe4cc3a2098de 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -1381,7 +1381,9 @@ static QPolygonF mapProjective(const QTransform &transform, const QPolygonF &pol path = transform.map(path); QPolygonF result; - for (int i = 0; i < path.elementCount(); ++i) + const int elementCount = path.elementCount(); + result.reserve(elementCount); + for (int i = 0; i < elementCount; ++i) result << path.elementAt(i); return result; } diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h index 65f543144d4c0904774ddaaaf3c8d7e971687b93..8874996e19e7a528d10851994adcf4d240c9fe22 100644 --- a/src/gui/painting/qtransform.h +++ b/src/gui/painting/qtransform.h @@ -96,7 +96,7 @@ public: qreal m21, qreal m22, qreal m23, qreal m31, qreal m32, qreal m33); - QTransform inverted(bool *invertible = 0) const Q_REQUIRED_RESULT; + QTransform inverted(bool *invertible = Q_NULLPTR) const Q_REQUIRED_RESULT; QTransform adjoint() const Q_REQUIRED_RESULT; QTransform transposed() const Q_REQUIRED_RESULT; diff --git a/src/gui/text/qabstracttextdocumentlayout.h b/src/gui/text/qabstracttextdocumentlayout.h index 68e7a0e4e9a3f50be2b2a7dc39d33796d762f313..cdcfed75359130294d3a4d28a29ceb26da425ee7 100644 --- a/src/gui/text/qabstracttextdocumentlayout.h +++ b/src/gui/text/qabstracttextdocumentlayout.h @@ -90,7 +90,7 @@ public: QTextDocument *document() const; void registerHandler(int objectType, QObject *component); - void unregisterHandler(int objectType, QObject *component = 0); + void unregisterHandler(int objectType, QObject *component = Q_NULLPTR); QTextObjectInterface *handlerForObject(int objectType) const; Q_SIGNALS: diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 3c98cb568d2ee648650b2be58b6250c6ddda55bf..adbb3df3bf346e08e7fafb75fa46f8dc1856b0a2 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -461,6 +461,7 @@ void ValueExtractor::lengthValues(const Declaration &decl, int *m) } QList<QVariant> v; + v.reserve(4); for (i = 0; i < 4; i++) { v += QVariant::fromValue<LengthData>(datas[i]); m[i] = lengthValueFromData(datas[i], f); diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index ce39645246fb41d158cfde5851913ac16eaaf457..796f22379741c3fea6110bfaf3e8ee72ee4a1cc6 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -725,7 +725,7 @@ void QFont::setFamily(const QString &family) Returns the requested font style name, it will be used to match the font with irregular styles (that can't be normalized in other style properties). It depends on system font support, thus only works for - Mac OS X and X11 so far. On Windows irregular styles will be added + OS X and X11 so far. On Windows irregular styles will be added as separate font families so there is no need for this. \sa setFamily(), setStyle() @@ -820,7 +820,7 @@ int QFont::pointSize() const \li Vertical hinting (light) \li Full hinting \row - \li Cocoa on Mac OS X + \li Cocoa on OS X \li No hinting \li No hinting \li No hinting @@ -1860,14 +1860,9 @@ void QFont::removeSubstitutions(const QString &familyName) */ QStringList QFont::substitutions() { - typedef QFontSubst::const_iterator QFontSubstConstIterator; - QFontSubst *fontSubst = globalFontSubst(); Q_ASSERT(fontSubst != 0); - QStringList ret; - const QFontSubstConstIterator cend = fontSubst->constEnd(); - for (QFontSubstConstIterator it = fontSubst->constBegin(); it != cend; ++it) - ret.append(it.key()); + QStringList ret = fontSubst->keys(); ret.sort(); return ret; diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index 3f8241a80ee9ed99d7130866e23f372c0413e580..25b5ef0b0e21f10de23c21199d82593ed20414c7 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -102,7 +102,7 @@ struct QFontDef && styleStrategy == other.styleStrategy && ignorePitch == other.ignorePitch && fixedPitch == other.fixedPitch && family == other.family - && (styleName.isEmpty() || other.styleName.isEmpty() || styleName == other.styleName) + && styleName == other.styleName && hintingPreference == other.hintingPreference ; } @@ -115,7 +115,7 @@ struct QFontDef if (styleHint != other.styleHint) return styleHint < other.styleHint; if (styleStrategy != other.styleStrategy) return styleStrategy < other.styleStrategy; if (family != other.family) return family < other.family; - if (!styleName.isEmpty() && !other.styleName.isEmpty() && styleName != other.styleName) + if (styleName != other.styleName) return styleName < other.styleName; if (hintingPreference != other.hintingPreference) return hintingPreference < other.hintingPreference; diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index dae4d560a8e522de00a66166a4c002a94b25bb01..0b0940855dca2dad28a39bc63eac2a98f6f72a33 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -1184,14 +1184,25 @@ static int match(int script, const QFontDef &request, static QString styleStringHelper(int weight, QFont::Style style) { QString result; - if (weight >= QFont::Black) - result = QCoreApplication::translate("QFontDatabase", "Black"); - else if (weight >= QFont::Bold) - result = QCoreApplication::translate("QFontDatabase", "Bold"); - else if (weight >= QFont::DemiBold) - result = QCoreApplication::translate("QFontDatabase", "Demi Bold"); - else if (weight < QFont::Normal) - result = QCoreApplication::translate("QFontDatabase", "Light"); + if (weight > QFont::Normal) { + if (weight >= QFont::Black) + result = QCoreApplication::translate("QFontDatabase", "Black"); + else if (weight >= QFont::ExtraBold) + result = QCoreApplication::translate("QFontDatabase", "Extra Bold"); + else if (weight >= QFont::Bold) + result = QCoreApplication::translate("QFontDatabase", "Bold"); + else if (weight >= QFont::DemiBold) + result = QCoreApplication::translate("QFontDatabase", "Demi Bold"); + else if (weight >= QFont::Medium) + result = QCoreApplication::translate("QFontDatabase", "Medium", "The Medium font weight"); + } else { + if (weight <= QFont::Thin) + result = QCoreApplication::translate("QFontDatabase", "Thin"); + else if (weight <= QFont::ExtraLight) + result = QCoreApplication::translate("QFontDatabase", "Extra Light"); + else if (weight <= QFont::Light) + result = QCoreApplication::translate("QFontDatabase", "Light"); + } if (style == QFont::StyleItalic) result += QLatin1Char(' ') + QCoreApplication::translate("QFontDatabase", "Italic"); @@ -1199,7 +1210,7 @@ static QString styleStringHelper(int weight, QFont::Style style) result += QLatin1Char(' ') + QCoreApplication::translate("QFontDatabase", "Oblique"); if (result.isEmpty()) - result = QCoreApplication::translate("QFontDatabase", "Normal"); + result = QCoreApplication::translate("QFontDatabase", "Normal", "The Normal or Regular font weight"); return result.simplified(); } @@ -1358,22 +1369,30 @@ QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems() const QT_PREPEND_NAMESPACE(load)(); - QList<WritingSystem> list; + quint64 writingSystemsFound = 0; + Q_STATIC_ASSERT(WritingSystemsCount < 64); + for (int i = 0; i < d->count; ++i) { QtFontFamily *family = d->families[i]; family->ensurePopulated(); if (family->count == 0) continue; - for (int x = Latin; x < WritingSystemsCount; ++x) { - const WritingSystem writingSystem = WritingSystem(x); - if (!(family->writingSystems[writingSystem] & QtFontFamily::Supported)) - continue; - if (!list.contains(writingSystem)) - list.append(writingSystem); + for (uint x = Latin; x < uint(WritingSystemsCount); ++x) { + if (family->writingSystems[x] & QtFontFamily::Supported) + writingSystemsFound |= quint64(1) << x; } } - std::sort(list.begin(), list.end()); + + // mutex protection no longer needed - just working on local data now: + locker.unlock(); + + QList<WritingSystem> list; + list.reserve(qPopulationCount(writingSystemsFound)); + for (uint x = Latin ; x < uint(WritingSystemsCount); ++x) { + if (writingSystemsFound & (quint64(1) << x)) + list.push_back(WritingSystem(x)); + } return list; } diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 87e6c30afe34ab29bc1e9a2b9cb61ce326c0c1e4..6f5d178655524493175c775f1176cd75fb563950 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1344,13 +1344,13 @@ QByteArray QFontEngine::convertToPostscriptFontFamilyName(const QByteArray &fami return f; } -/** - * Some font engines like the windows font engine - * can not reliable create outline paths - */ +// Allow font engines (e.g. Windows) that can not reliably create +// outline paths for distance-field rendering to switch the scene +// graph over to native text rendering. bool QFontEngine::hasUnreliableGlyphOutline() const { - return false; + // Color glyphs (Emoji) are generally not suited for outlining + return glyphFormat == QFontEngine::Format_ARGB; } QFixed QFontEngine::lastRightBearing(const QGlyphLayout &glyphs, bool round) diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 2076fa4d8025ca61cd714b76f53d2804cf88979e..5329a5f11af3aed4518b14ab710085f6d2029ec1 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -49,6 +49,7 @@ #include "QtCore/qatomic.h" #include <QtCore/qvarlengtharray.h> #include <QtCore/QLinkedList> +#include <QtCore/qhashfunctions.h> #include "private/qtextengine_p.h" #include "private/qfont_p.h" @@ -328,12 +329,18 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QFontEngine::ShaperFlags) inline bool operator ==(const QFontEngine::FaceId &f1, const QFontEngine::FaceId &f2) { - return (f1.index == f2.index) && (f1.encoding == f2.encoding) && (f1.filename == f2.filename); + return f1.index == f2.index && f1.encoding == f2.encoding && f1.filename == f2.filename && f1.uuid == f2.uuid; } -inline uint qHash(const QFontEngine::FaceId &f) +inline uint qHash(const QFontEngine::FaceId &f, uint seed = 0) + Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(f.filename))) { - return qHash((f.index << 16) + f.encoding) + qHash(f.filename + f.uuid); + QtPrivate::QHashCombine hash; + seed = hash(seed, f.filename); + seed = hash(seed, f.uuid); + seed = hash(seed, f.index); + seed = hash(seed, f.encoding); + return seed; } diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index c2d4b641527a7259963c5b8c3c9285e0fc3b06d8..e351d4d2c5907a83fdea0b4bcfe2196e1da388c5 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -582,6 +582,7 @@ int QFontMetrics::width(QChar ch) const return qRound(advance); } +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) /*! \obsolete Returns the width of the character at position \a pos in the @@ -634,6 +635,7 @@ int QFontMetrics::charWidth(const QString &text, int pos) const } return width; } +#endif /*! Returns the bounding rectangle of the characters in the string diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h index 65ec219a991c702c15ee47706cd92483d95bc410..4c2c6317baa1cf5db22653fbfe64aa0d31b4a87e 100644 --- a/src/gui/text/qfontmetrics.h +++ b/src/gui/text/qfontmetrics.h @@ -86,16 +86,18 @@ public: int width(const QString &, int len, int flags) const; int width(QChar) const; - int charWidth(const QString &str, int pos) const; +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) + QT_DEPRECATED int charWidth(const QString &str, int pos) const; +#endif QRect boundingRect(QChar) const; QRect boundingRect(const QString &text) const; - QRect boundingRect(const QRect &r, int flags, const QString &text, int tabstops=0, int *tabarray=0) const; + QRect boundingRect(const QRect &r, int flags, const QString &text, int tabstops = 0, int *tabarray = Q_NULLPTR) const; inline QRect boundingRect(int x, int y, int w, int h, int flags, const QString &text, - int tabstops=0, int *tabarray=0) const + int tabstops = 0, int *tabarray = Q_NULLPTR) const { return boundingRect(QRect(x, y, w, h), flags, text, tabstops, tabarray); } - QSize size(int flags, const QString& str, int tabstops=0, int *tabarray=0) const; + QSize size(int flags, const QString& str, int tabstops = 0, int *tabarray = Q_NULLPTR) const; QRect tightBoundingRect(const QString &text) const; @@ -159,8 +161,8 @@ public: QRectF boundingRect(const QString &string) const; QRectF boundingRect(QChar) const; - QRectF boundingRect(const QRectF &r, int flags, const QString& string, int tabstops=0, int *tabarray=0) const; - QSizeF size(int flags, const QString& str, int tabstops=0, int *tabarray=0) const; + QRectF boundingRect(const QRectF &r, int flags, const QString& string, int tabstops = 0, int *tabarray = Q_NULLPTR) const; + QSizeF size(int flags, const QString& str, int tabstops = 0, int *tabarray = Q_NULLPTR) const; QRectF tightBoundingRect(const QString &text) const; diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp index 9f652084be1e263bbe61dbde9946c5f7bbfc81c6..dc32405f3695e56e227fb99422badd00f6b371fa 100644 --- a/src/gui/text/qfontsubset.cpp +++ b/src/gui/text/qfontsubset.cpp @@ -350,6 +350,7 @@ struct qttf_head_table { quint16 macStyle; qint16 indexToLocFormat; }; +Q_DECLARE_TYPEINFO(qttf_head_table, Q_PRIMITIVE_TYPE); struct qttf_hhea_table { @@ -362,6 +363,7 @@ struct qttf_hhea_table { qint16 xMaxExtent; quint16 numberOfHMetrics; }; +Q_DECLARE_TYPEINFO(qttf_hhea_table, Q_PRIMITIVE_TYPE); struct qttf_maxp_table { @@ -373,6 +375,7 @@ struct qttf_maxp_table { quint16 maxComponentElements; quint16 maxComponentDepth; }; +Q_DECLARE_TYPEINFO(qttf_maxp_table, Q_PRIMITIVE_TYPE); struct qttf_name_table { QString copyright; @@ -380,6 +383,7 @@ struct qttf_name_table { QString subfamily; QString postscript_name; }; +Q_DECLARE_TYPEINFO(qttf_name_table, Q_MOVABLE_TYPE); static QTtfTable generateHead(const qttf_head_table &head); @@ -411,9 +415,9 @@ Q_DECLARE_TYPEINFO(QTtfGlyph, Q_MOVABLE_TYPE); static QTtfGlyph generateGlyph(int index, const QPainterPath &path, qreal advance, qreal lsb, qreal ppem); // generates glyf, loca and hmtx -static QList<QTtfTable> generateGlyphTables(qttf_font_tables &tables, const QList<QTtfGlyph> &_glyphs); +static QVector<QTtfTable> generateGlyphTables(qttf_font_tables &tables, const QVector<QTtfGlyph> &_glyphs); -static QByteArray bindFont(const QList<QTtfTable>& _tables); +static QByteArray bindFont(const QVector<QTtfTable>& _tables); static quint32 checksum(const QByteArray &table) @@ -607,12 +611,13 @@ struct QTtfNameRecord { quint16 nameId; QString value; }; +Q_DECLARE_TYPEINFO(QTtfNameRecord, Q_MOVABLE_TYPE); -static QTtfTable generateName(const QList<QTtfNameRecord> &name); +static QTtfTable generateName(const QVector<QTtfNameRecord> &name); static QTtfTable generateName(const qttf_name_table &name) { - QList<QTtfNameRecord> list; + QVector<QTtfNameRecord> list; QTtfNameRecord rec; rec.nameId = 0; rec.value = name.copyright; @@ -636,7 +641,7 @@ static QTtfTable generateName(const qttf_name_table &name) } // ####### should probably generate Macintosh/Roman name entries as well -static QTtfTable generateName(const QList<QTtfNameRecord> &name) +static QTtfTable generateName(const QVector<QTtfNameRecord> &name) { const int char_size = 2; @@ -707,7 +712,7 @@ struct TTF_POINT { }; Q_DECLARE_TYPEINFO(TTF_POINT, Q_PRIMITIVE_TYPE); -static void convertPath(const QPainterPath &path, QList<TTF_POINT> *points, QList<int> *endPoints, qreal ppem) +static void convertPath(const QPainterPath &path, QVector<TTF_POINT> *points, QVector<int> *endPoints, qreal ppem) { int numElements = path.elementCount(); for (int i = 0; i < numElements - 1; ++i) { @@ -829,7 +834,7 @@ static void convertPath(const QPainterPath &path, QList<TTF_POINT> *points, QLis endPoints->append(points->size() - 1); } -static void getBounds(const QList<TTF_POINT> &points, qint16 *xmin, qint16 *xmax, qint16 *ymin, qint16 *ymax) +static void getBounds(const QVector<TTF_POINT> &points, qint16 *xmin, qint16 *xmax, qint16 *ymin, qint16 *ymax) { *xmin = points.at(0).x; *xmax = *xmin; @@ -844,7 +849,7 @@ static void getBounds(const QList<TTF_POINT> &points, qint16 *xmin, qint16 *xmax } } -static int convertToRelative(QList<TTF_POINT> *points) +static int convertToRelative(QVector<TTF_POINT> *points) { // convert points to relative and setup flags // qDebug() << "relative points:"; @@ -897,7 +902,7 @@ static int convertToRelative(QList<TTF_POINT> *points) return point_array_size; } -static void getGlyphData(QTtfGlyph *glyph, const QList<TTF_POINT> &points, const QList<int> &endPoints, int point_array_size) +static void getGlyphData(QTtfGlyph *glyph, const QVector<TTF_POINT> &points, const QVector<int> &endPoints, int point_array_size) { const int max_size = 5*sizeof(qint16) // header + endPoints.size()*sizeof(quint16) // end points of contours @@ -947,8 +952,8 @@ static void getGlyphData(QTtfGlyph *glyph, const QList<TTF_POINT> &points, const static QTtfGlyph generateGlyph(int index, const QPainterPath &path, qreal advance, qreal lsb, qreal ppem) { - QList<TTF_POINT> points; - QList<int> endPoints; + QVector<TTF_POINT> points; + QVector<int> endPoints; QTtfGlyph glyph; glyph.index = index; glyph.advanceWidth = qRound(advance * 2048. / ppem); @@ -983,10 +988,10 @@ static bool operator <(const QTtfGlyph &g1, const QTtfGlyph &g2) return g1.index < g2.index; } -static QList<QTtfTable> generateGlyphTables(qttf_font_tables &tables, const QList<QTtfGlyph> &_glyphs) +static QVector<QTtfTable> generateGlyphTables(qttf_font_tables &tables, const QVector<QTtfGlyph> &_glyphs) { const int max_size_small = 65536*2; - QList<QTtfGlyph> glyphs = _glyphs; + QVector<QTtfGlyph> glyphs = _glyphs; std::sort(glyphs.begin(), glyphs.end()); Q_ASSERT(tables.maxp.numGlyphs == glyphs.at(glyphs.size()-1).index + 1); @@ -1049,7 +1054,7 @@ static QList<QTtfTable> generateGlyphTables(qttf_font_tables &tables, const QLis Q_ASSERT(loca.data.size() == ls.offset()); Q_ASSERT(hmtx.data.size() == hs.offset()); - QList<QTtfTable> list; + QVector<QTtfTable> list; list.append(glyf); list.append(loca); list.append(hmtx); @@ -1061,9 +1066,9 @@ static bool operator <(const QTtfTable &t1, const QTtfTable &t2) return t1.tag < t2.tag; } -static QByteArray bindFont(const QList<QTtfTable>& _tables) +static QByteArray bindFont(const QVector<QTtfTable>& _tables) { - QList<QTtfTable> tables = _tables; + QVector<QTtfTable> tables = _tables; std::sort(tables.begin(), tables.end()); @@ -1154,7 +1159,7 @@ QByteArray QFontSubset::toTruetype() const qreal ppem = fontEngine->fontDef.pixelSize; #define TO_TTF(x) qRound(x * 2048. / ppem) - QList<QTtfGlyph> glyphs; + QVector<QTtfGlyph> glyphs; QFontEngine::Properties properties = fontEngine->properties(); // initialize some stuff needed in createWidthArray @@ -1225,7 +1230,7 @@ QByteArray QFontSubset::toTruetype() const } - QList<QTtfTable> tables = generateGlyphTables(font, glyphs); + QVector<QTtfTable> tables = generateGlyphTables(font, glyphs); tables.append(generateHead(font.head)); tables.append(generateHhea(font.hhea)); tables.append(generateMaxp(font.maxp)); diff --git a/src/gui/text/qfontsubset_p.h b/src/gui/text/qfontsubset_p.h index da8589de3fbac259bd6954244d01d2e66ea153ac..4abdb48c0dd08f93c715a0e5fd7c37ad1a1f5550 100644 --- a/src/gui/text/qfontsubset_p.h +++ b/src/gui/text/qfontsubset_p.h @@ -79,7 +79,7 @@ public: const int object_id; bool noEmbed; QFontEngine *fontEngine; - QList<int> glyph_indices; + QVector<int> glyph_indices; mutable int downloaded_glyphs; mutable bool standard_font; int nGlyphs() const { return glyph_indices.size(); } diff --git a/src/gui/text/qglyphrun.h b/src/gui/text/qglyphrun.h index d3034b75467a478fc70be74895e1eea802a761e6..9f51a49a6d4df4a6b0f2ef408eb12cbccb115c92 100644 --- a/src/gui/text/qglyphrun.h +++ b/src/gui/text/qglyphrun.h @@ -59,9 +59,13 @@ public: QGlyphRun(); QGlyphRun(const QGlyphRun &other); +#ifdef Q_COMPILER_RVALUE_REFS + QGlyphRun &operator=(QGlyphRun &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif + QGlyphRun &operator=(const QGlyphRun &other); ~QGlyphRun(); - void swap(QGlyphRun &other) { qSwap(d, other.d); } + void swap(QGlyphRun &other) Q_DECL_NOTHROW { qSwap(d, other.d); } QRawFont rawFont() const; void setRawFont(const QRawFont &rawFont); @@ -78,8 +82,6 @@ public: void clear(); - QGlyphRun &operator=(const QGlyphRun &other); - bool operator==(const QGlyphRun &other) const; inline bool operator!=(const QGlyphRun &other) const { return !operator==(other); } diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp index 502348a79aaf3ece44a3dd0bf0c40ba8a3c9eaf1..482495302b8bf51783366ef3b4346a813ff3ab60 100644 --- a/src/gui/text/qplatformfontdatabase.cpp +++ b/src/gui/text/qplatformfontdatabase.cpp @@ -40,6 +40,9 @@ #include <QtCore/QLibraryInfo> #include <QtCore/QDir> +#include <algorithm> +#include <iterator> + QT_BEGIN_NAMESPACE void qt_registerFont(const QString &familyname, const QString &stylename, @@ -452,11 +455,11 @@ bool QPlatformFontDatabase::fontsAlwaysScalable() const QList<int> QPlatformFontDatabase::standardSizes() const { QList<int> ret; - static const unsigned short standard[] = - { 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72, 0 }; - ret.reserve(int(sizeof(standard) / sizeof(standard[0]))); - const unsigned short *sizes = standard; - while (*sizes) ret << *sizes++; + static const quint8 standard[] = + { 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72 }; + static const int num_standards = int(sizeof standard / sizeof *standard); + ret.reserve(num_standards); + std::copy(standard, standard + num_standards, std::back_inserter(ret)); return ret; } @@ -473,7 +476,7 @@ QFontEngine::SubpixelAntialiasingType QPlatformFontDatabase::subpixelAntialiasin // ### copied to tools/makeqpf/qpf2.cpp // see the Unicode subset bitfields in the MSDN docs -static const ushort requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = { +static const quint8 requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = { { 127, 127 }, // Any { 0, 127 }, // Latin { 7, 127 }, // Greek diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index d5567e173db5f7ed02e21ecea5e90fe44937b4e6..0fd5f510c7628b9e66f61b8f18b3bbf8b248af2a 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -79,7 +79,7 @@ QT_BEGIN_NAMESPACE also have accessors to some relevant data in the physical font. QRawFont only provides support for the main font technologies: GDI and DirectWrite on Windows - platforms, FreeType on Linux platforms and CoreText on Mac OS X. For other + platforms, FreeType on Linux platforms and CoreText on OS X. For other font back-ends, the APIs will be disabled. QRawFont can be constructed in a number of ways: diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h index 3798555de538e7dda9cad093c0061ebf191621d6..d710658a9b9ab6ab1c155a70595a14d82a3b4164 100644 --- a/src/gui/text/qrawfont.h +++ b/src/gui/text/qrawfont.h @@ -72,13 +72,15 @@ public: qreal pixelSize, QFont::HintingPreference hintingPreference = QFont::PreferDefaultHinting); QRawFont(const QRawFont &other); +#ifdef Q_COMPILER_RVALUE_REFS + QRawFont &operator=(QRawFont &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif + QRawFont &operator=(const QRawFont &other); ~QRawFont(); - bool isValid() const; + void swap(QRawFont &other) Q_DECL_NOTHROW { qSwap(d, other.d); } - QRawFont &operator=(const QRawFont &other); - - void swap(QRawFont &other) { qSwap(d, other.d); } + bool isValid() const; bool operator==(const QRawFont &other) const; inline bool operator!=(const QRawFont &other) const diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index 5d31ab97118834c526d88df07fa4047363ddecf8..74f4b10305de9c7179b7c02bf20bd6801098e4fa 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -558,6 +558,9 @@ namespace { case PdmDevicePixelRatio: val = 1; break; + case PdmDevicePixelRatioScaled: + val = devicePixelRatioFScale(); + break; default: val = 0; qWarning("DrawTextItemDevice::metric: Invalid metric command"); diff --git a/src/gui/text/qstatictext.h b/src/gui/text/qstatictext.h index d2825e73ac6aa7fe2acf6a12be15362b252f8833..0a1d9429b46becce36b1ed7cfb9bed881a0fab86 100644 --- a/src/gui/text/qstatictext.h +++ b/src/gui/text/qstatictext.h @@ -57,9 +57,13 @@ public: QStaticText(); QStaticText(const QString &text); QStaticText(const QStaticText &other); +#ifdef Q_COMPILER_RVALUE_REFS + QStaticText &operator=(QStaticText &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif + QStaticText &operator=(const QStaticText &); ~QStaticText(); - void swap(QStaticText &other) { qSwap(data, other.data); } + void swap(QStaticText &other) Q_DECL_NOTHROW { qSwap(data, other.data); } void setText(const QString &text); QString text() const; @@ -80,7 +84,6 @@ public: void setPerformanceHint(PerformanceHint performanceHint); PerformanceHint performanceHint() const; - QStaticText &operator=(const QStaticText &); bool operator==(const QStaticText &) const; bool operator!=(const QStaticText &) const; diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index f04055603c66678c60c7bdd8d5a16a1ff3f4aa07..350f38cd0201ccd99857439a4167cd3f1520e57c 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -66,10 +66,13 @@ public: explicit QTextCursor(const QTextBlock &block); explicit QTextCursor(QTextCursorPrivate *d); QTextCursor(const QTextCursor &cursor); +#ifdef Q_COMPILER_RVALUE_REFS + QTextCursor &operator=(QTextCursor &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QTextCursor &operator=(const QTextCursor &other); ~QTextCursor(); - void swap(QTextCursor &other) { qSwap(d, other.d); } + void swap(QTextCursor &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool isNull() const; diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 3d248f4afc66785898cfc6085292f696acc35e36..40cca77c269ff8db8f43f55021949194904a67fa 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -533,7 +533,7 @@ QTextOption QTextDocument::defaultTextOption() const /*! \since 4.3 - Sets the default text option. + Sets the default text option to \a option. */ void QTextDocument::setDefaultTextOption(const QTextOption &option) { @@ -1402,7 +1402,9 @@ static bool findInBlock(const QTextBlock &block, const QRegExp &expression, int /*! \overload - Finds the next occurrence, matching the regular expression, \a expr, in the document. + Finds the next occurrence that matches the given regular expression, + \a expr, within the same paragraph in the document. + The search starts at the given \a from position, and proceeds forwards through the document unless specified otherwise in the search options. The \a options control the type of search performed. The FindCaseSensitively @@ -1455,7 +1457,9 @@ QTextCursor QTextDocument::find(const QRegExp & expr, int from, FindFlags option /*! \overload - Finds the next occurrence, matching the regular expression, \a expr, in the document. + Finds the next occurrence that matches the given regular expression, + \a expr, within the same paragraph in the document. + The search starts at the position of the given from \a cursor, and proceeds forwards through the document unless specified otherwise in the search options. The \a options control the type of search performed. The FindCaseSensitively @@ -1464,7 +1468,7 @@ QTextCursor QTextDocument::find(const QRegExp & expr, int from, FindFlags option Returns a cursor with the match selected if a match was found; otherwise returns a null cursor. - If the given \a from cursor has a selection, the search begins after the + If the given \a cursor has a selection, the search begins after the selection; otherwise it begins at the cursor's position. By default the search is case-sensitive, and can match text anywhere in the @@ -1526,7 +1530,9 @@ static bool findInBlock(const QTextBlock &block, const QRegularExpression &expre /*! \since 5.5 - Finds the next occurrence, matching the regular expression, \a expr, in the document. + Finds the next occurrence that matches the given regular expression, + \a expr, within the same paragraph in the document. + The search starts at the given \a from position, and proceeds forwards through the document unless specified otherwise in the search options. The \a options control the type of search performed. @@ -1579,7 +1585,9 @@ QTextCursor QTextDocument::find(const QRegularExpression &expr, int from, FindFl /*! \since 5.5 - Finds the next occurrence, matching the regular expression, \a expr, in the document. + Finds the next occurrence that matches the given regular expression, + \a expr, within the same paragraph in the document. + The search starts at the position of the given \a cursor, and proceeds forwards through the document unless specified otherwise in the search options. The \a options control the type of search performed. diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h index ca80a88033187d2292324d489912c20fbea60c85..f05b624704111cc179194811d455e444c8bb1643 100644 --- a/src/gui/text/qtextdocument.h +++ b/src/gui/text/qtextdocument.h @@ -109,11 +109,11 @@ class Q_GUI_EXPORT QTextDocument : public QObject Q_PROPERTY(QUrl baseUrl READ baseUrl WRITE setBaseUrl NOTIFY baseUrlChanged) public: - explicit QTextDocument(QObject *parent = 0); - explicit QTextDocument(const QString &text, QObject *parent = 0); + explicit QTextDocument(QObject *parent = Q_NULLPTR); + explicit QTextDocument(const QString &text, QObject *parent = Q_NULLPTR); ~QTextDocument(); - QTextDocument *clone(QObject *parent = 0) const; + QTextDocument *clone(QObject *parent = Q_NULLPTR) const; bool isEmpty() const; virtual void clear(); @@ -157,17 +157,17 @@ public: }; Q_DECLARE_FLAGS(FindFlags, FindFlag) - QTextCursor find(const QString &subString, int from = 0, FindFlags options = 0) const; - QTextCursor find(const QString &subString, const QTextCursor &cursor, FindFlags options = 0) const; + QTextCursor find(const QString &subString, int from = 0, FindFlags options = FindFlags()) const; + QTextCursor find(const QString &subString, const QTextCursor &cursor, FindFlags options = FindFlags()) const; #ifndef QT_NO_REGEXP - QTextCursor find(const QRegExp &expr, int from = 0, FindFlags options = 0) const; - QTextCursor find(const QRegExp &expr, const QTextCursor &cursor, FindFlags options = 0) const; + QTextCursor find(const QRegExp &expr, int from = 0, FindFlags options = FindFlags()) const; + QTextCursor find(const QRegExp &expr, const QTextCursor &cursor, FindFlags options = FindFlags()) const; #endif #ifndef QT_NO_REGULAREXPRESSION - QTextCursor find(const QRegularExpression &expr, int from = 0, FindFlags options = 0) const; - QTextCursor find(const QRegularExpression &expr, const QTextCursor &cursor, FindFlags options = 0) const; + QTextCursor find(const QRegularExpression &expr, int from = 0, FindFlags options = FindFlags()) const; + QTextCursor find(const QRegularExpression &expr, const QTextCursor &cursor, FindFlags options = FindFlags()) const; #endif QTextFrame *frameAt(int pos) const; diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index 5864ca0b1a43fd9062da3429e525917b28b90eff..c7bbcea4f4cd89a3780e109c4a3ac8927d14916f 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -106,7 +106,7 @@ public: bool sizeDirty; bool layoutDirty; - QList<QPointer<QTextFrame> > floats; + QVector<QPointer<QTextFrame> > floats; }; QTextFrameData::QTextFrameData() @@ -467,9 +467,9 @@ public: void drawFlow(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, QTextFrame::Iterator it, const QList<QTextFrame *> &floats, QTextBlock *cursorBlockNeedingRepaint) const; void drawBlock(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, - QTextBlock bl, bool inRootFrame) const; + const QTextBlock &bl, bool inRootFrame) const; void drawListItem(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, - QTextBlock bl, const QTextCharFormat *selectionFormat) const; + const QTextBlock &bl, const QTextCharFormat *selectionFormat) const; void drawTableCell(const QRectF &cellRect, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &cell_context, QTextTable *table, QTextTableData *td, int r, int c, QTextBlock *cursorBlockNeedingRepaint, QPointF *cursorBlockOffset) const; @@ -487,7 +487,7 @@ public: HitPoint hitTest(QTextFrame::Iterator it, HitPoint hit, const QFixedPoint &p, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; HitPoint hitTest(QTextTable *table, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; - HitPoint hitTest(QTextBlock bl, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; + HitPoint hitTest(const QTextBlock &bl, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; QTextLayoutStruct layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, int layoutFrom, int layoutTo, QTextTableData *tableData, QFixed absoluteTableY, @@ -749,7 +749,7 @@ QTextDocumentLayoutPrivate::hitTest(QTextTable *table, const QFixedPoint &point, } QTextDocumentLayoutPrivate::HitPoint -QTextDocumentLayoutPrivate::hitTest(QTextBlock bl, const QFixedPoint &point, int *position, QTextLayout **l, +QTextDocumentLayoutPrivate::hitTest(const QTextBlock &bl, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const { QTextLayout *tl = bl.layout(); @@ -1071,7 +1071,9 @@ void QTextDocumentLayoutPrivate::drawFrame(const QPointF &offset, QPainter *pain it = frameIteratorForYPosition(QFixed::fromReal(context.clip.top())); QList<QTextFrame *> floats; - for (int i = 0; i < fd->floats.count(); ++i) + const int numFloats = fd->floats.count(); + floats.reserve(numFloats); + for (int i = 0; i < numFloats; ++i) floats.append(fd->floats.at(i)); drawFlow(off, painter, context, it, floats, &cursorBlockNeedingRepaint); @@ -1283,7 +1285,7 @@ void QTextDocumentLayoutPrivate::drawFlow(const QPointF &offset, QPainter *paint void QTextDocumentLayoutPrivate::drawBlock(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, - QTextBlock bl, bool inRootFrame) const + const QTextBlock &bl, bool inRootFrame) const { const QTextLayout *tl = bl.layout(); QRectF r = tl->boundingRect(); @@ -1377,7 +1379,7 @@ void QTextDocumentLayoutPrivate::drawBlock(const QPointF &offset, QPainter *pain void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, - QTextBlock bl, const QTextCharFormat *selectionFormat) const + const QTextBlock &bl, const QTextCharFormat *selectionFormat) const { Q_Q(const QTextDocumentLayout); const QTextBlockFormat blockFormat = bl.blockFormat(); diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 187ffa5be72b24f2c194f6a60a26ecc178ed3767..d2174c5e06a857a47cb9d4e6ec74627c1d477622 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1256,7 +1256,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st // scaling the advances for this particular version if (actualFontEngine->fontDef.stretch != 100 && QSysInfo::MacintoshVersion != QSysInfo::MV_10_6) { - QFixed stretch = QFixed(actualFontEngine->fontDef.stretch) / QFixed(100); + QFixed stretch = QFixed(int(actualFontEngine->fontDef.stretch)) / QFixed(100); for (uint i = 0; i < num_glyphs; ++i) g.advances[i] *= stretch; } @@ -2863,6 +2863,7 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const if (!tabArray.isEmpty()) { if (isRightToLeft()) { // rebase the tabArray positions. QList<QTextOption::Tab> newTabs; + newTabs.reserve(tabArray.count()); QList<QTextOption::Tab>::Iterator iter = tabArray.begin(); while(iter != tabArray.end()) { QTextOption::Tab tab = *iter; diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 3590c6da078f2f6663888dc1fb6148286bbae792..d2b39f274c7892e1be5fb377bd96b1bb073d0671 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -400,6 +400,7 @@ public: }; struct ItemDecoration { + ItemDecoration() {} // for QVector, don't use ItemDecoration(qreal x1, qreal x2, qreal y, const QPen &pen): x1(x1), x2(x2), y(y), pen(pen) {} @@ -409,7 +410,7 @@ public: QPen pen; }; - typedef QList<ItemDecoration> ItemDecorationList; + typedef QVector<ItemDecoration> ItemDecorationList; QTextEngine(); QTextEngine(const QString &str, const QFont &f); @@ -643,6 +644,7 @@ public: LayoutData _layoutData; void *_memory[MemSize]; }; +Q_DECLARE_TYPEINFO(QTextEngine::ItemDecoration, Q_MOVABLE_TYPE); struct QTextLineItemIterator { diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index d4eb1a4b0b6e9d9c2eb5fa5349fb42c1c6db0b36..7dcd060ba1ebc85f5c526ac1f53b72c47d652f7b 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -1115,7 +1115,9 @@ void QTextFormat::setProperty(int propertyId, const QVector<QTextLength> &value) if (!d) d = new QTextFormatPrivate; QVariantList list; - for (int i=0; i<value.size(); ++i) + const int numValues = value.size(); + list.reserve(numValues); + for (int i = 0; i < numValues; ++i) list << value.at(i); d->insertProperty(propertyId, list); } @@ -1325,7 +1327,7 @@ bool QTextFormat::operator==(const QTextFormat &rhs) const \value WaveUnderline The text is underlined using a wave shaped line. \value SpellCheckUnderline The underline is drawn depending on the QStyle::SH_SpellCeckUnderlineStyle style hint of the QApplication style. By default this is mapped to - WaveUnderline, on Mac OS X it is mapped to DashDotLine. + WaveUnderline, on OS X it is mapped to DashDotLine. \sa Qt::PenStyle */ @@ -2041,6 +2043,7 @@ QTextBlockFormat::QTextBlockFormat(const QTextFormat &fmt) void QTextBlockFormat::setTabPositions(const QList<QTextOption::Tab> &tabs) { QList<QVariant> list; + list.reserve(tabs.count()); QList<QTextOption::Tab>::ConstIterator iter = tabs.constBegin(); while (iter != tabs.constEnd()) { QVariant v; @@ -2065,6 +2068,7 @@ QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const QList<QTextOption::Tab> answer; QList<QVariant> variantsList = qvariant_cast<QList<QVariant> >(variant); QList<QVariant>::Iterator iter = variantsList.begin(); + answer.reserve(variantsList.count()); while(iter != variantsList.end()) { answer.append( qvariant_cast<QTextOption::Tab>(*iter)); ++iter; diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp index e85890baf2f58448e4d76839242ca75c0f3f5fbf..1ba2cb31ca96b6b680d2d502a60117fe07a68b09 100644 --- a/src/gui/text/qtextimagehandler.cpp +++ b/src/gui/text/qtextimagehandler.cpp @@ -256,10 +256,10 @@ void QTextImageHandler::drawObject(QPainter *p, const QRectF &rect, QTextDocumen const QTextImageFormat imageFormat = format.toImageFormat(); if (QCoreApplication::instance()->thread() != QThread::currentThread()) { - const QImage image = getImage(doc, imageFormat, p->device()->devicePixelRatio()); + const QImage image = getImage(doc, imageFormat, p->device()->devicePixelRatioF()); p->drawImage(rect, image, image.rect()); } else { - const QPixmap pixmap = getPixmap(doc, imageFormat, p->device()->devicePixelRatio()); + const QPixmap pixmap = getPixmap(doc, imageFormat, p->device()->devicePixelRatioF()); p->drawPixmap(rect, pixmap, pixmap.rect()); } } diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index c42054c07cf32efe14b53666828eabd487ab659a..d56b9cf1b122e765b94e1f7f43d7cebd796462fb 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -87,6 +87,20 @@ QT_BEGIN_NAMESPACE Specifies the format to apply. */ +/*! \fn bool operator==(const FormatRange &lhs, const FormatRange &rhs) + \relates QTextLayout::FormatRange + + Returns true if the \c {start}, \c {length}, and \c {format} fields + in \a lhs and \a rhs contain the same values respectively. + */ + +/*! \fn bool operator!=(const FormatRange &lhs, const FormatRange &rhs) + \relates QTextLayout::FormatRange + + Returns true if any of the \c {start}, \c {length}, or \c {format} fields + in \a lhs and \a rhs contain different values respectively. + */ + /*! \class QTextInlineObject \reentrant @@ -485,16 +499,15 @@ QString QTextLayout::preeditAreaText() const return d->preeditAreaText(); } +#if QT_DEPRECATED_SINCE(5, 6) /*! - Sets the additional formats supported by the text layout to \a formatList. - The formats are applied with preedit area text in place. - - \sa additionalFormats(), clearAdditionalFormats() + \obsolete Use setFormats() instead. */ void QTextLayout::setAdditionalFormats(const QList<FormatRange> &formatList) { setFormats(formatList.toVector()); } +#endif // deprecated since 5.6 /*! \since 5.6 @@ -512,8 +525,9 @@ void QTextLayout::setFormats(const QVector<FormatRange> &formats) d->block.docHandle()->documentChange(d->block.position(), d->block.length()); } +#if QT_DEPRECATED_SINCE(5, 6) /*! - Returns the list of additional formats supported by the text layout. + \obsolete Use formats() instead. \sa setAdditionalFormats(), clearAdditionalFormats() */ @@ -521,6 +535,7 @@ QList<QTextLayout::FormatRange> QTextLayout::additionalFormats() const { return formats().toList(); } +#endif // deprecated since 5.6 /*! \since 5.6 @@ -534,15 +549,15 @@ QVector<QTextLayout::FormatRange> QTextLayout::formats() const return d->formats(); } +#if QT_DEPRECATED_SINCE(5, 6) /*! - Clears the list of additional formats supported by the text layout. - - \sa additionalFormats(), setAdditionalFormats() + \obsolete Use clearFormats() instead. */ void QTextLayout::clearAdditionalFormats() { clearFormats(); } +#endif // deprecated since 5.6 /*! \since 5.6 diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h index 9709af4fd122347f01dfead8e5b7b9333d9d3df5..f74d4d42297e4dcfa8861556362ff44c8d06c5b6 100644 --- a/src/gui/text/qtextlayout.h +++ b/src/gui/text/qtextlayout.h @@ -62,7 +62,7 @@ class Q_GUI_EXPORT QTextInlineObject { public: QTextInlineObject(int i, QTextEngine *e) : itm(i), eng(e) {} - inline QTextInlineObject() : itm(0), eng(0) {} + inline QTextInlineObject() : itm(0), eng(Q_NULLPTR) {} inline bool isValid() const { return eng; } QRectF rect() const; @@ -100,7 +100,7 @@ public: // does itemization QTextLayout(); QTextLayout(const QString& text); - QTextLayout(const QString& text, const QFont &font, QPaintDevice *paintdevice = 0); + QTextLayout(const QString& text, const QFont &font, QPaintDevice *paintdevice = Q_NULLPTR); QTextLayout(const QTextBlock &b); ~QTextLayout(); @@ -131,9 +131,11 @@ public: friend bool operator!=(const FormatRange &lhs, const FormatRange &rhs) { return !operator==(lhs, rhs); } }; - void setAdditionalFormats(const QList<FormatRange> &overrides); - QList<FormatRange> additionalFormats() const; - void clearAdditionalFormats(); +#if QT_DEPRECATED_SINCE(5, 6) + QT_DEPRECATED_X("Use setFormats()") void setAdditionalFormats(const QList<FormatRange> &overrides); + QT_DEPRECATED_X("Use formats()") QList<FormatRange> additionalFormats() const; + QT_DEPRECATED_X("Use clearFormats()") void clearAdditionalFormats(); +#endif void setFormats(const QVector<FormatRange> &overrides); QVector<FormatRange> formats() const; void clearFormats(); @@ -200,7 +202,7 @@ private: class Q_GUI_EXPORT QTextLine { public: - inline QTextLine() : index(0), eng(0) {} + inline QTextLine() : index(0), eng(Q_NULLPTR) {} inline bool isValid() const { return eng; } QRectF rect() const; @@ -245,7 +247,7 @@ public: int lineNumber() const { return index; } - void draw(QPainter *p, const QPointF &point, const QTextLayout::FormatRange *selection = 0) const; + void draw(QPainter *p, const QPointF &point, const QTextLayout::FormatRange *selection = Q_NULLPTR) const; #if !defined(QT_NO_RAWFONT) QList<QGlyphRun> glyphRuns(int from = -1, int length = -1) const; diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h index 9ad912d9926b09d400e927fed6c2ff254486eb47..fbb90e42b086d3cc4ffd2783775881a0b8db867c 100644 --- a/src/gui/text/qtextobject.h +++ b/src/gui/text/qtextobject.h @@ -190,7 +190,7 @@ class Q_GUI_EXPORT QTextBlock friend class QSyntaxHighlighter; public: inline QTextBlock(QTextDocumentPrivate *priv, int b) : p(priv), n(b) {} - inline QTextBlock() : p(0), n(0) {} + inline QTextBlock() : p(Q_NULLPTR), n(0) {} inline QTextBlock(const QTextBlock &o) : p(o.p), n(o.n) {} inline QTextBlock &operator=(const QTextBlock &o) { p = o.p; n = o.n; return *this; } @@ -247,7 +247,7 @@ public: friend class QTextBlock; iterator(const QTextDocumentPrivate *priv, int begin, int end, int f) : p(priv), b(begin), e(end), n(f) {} public: - iterator() : p(0), b(0), e(0), n(0) {} + iterator() : p(Q_NULLPTR), b(0), e(0), n(0) {} iterator(const iterator &o) : p(o.p), b(o.b), e(o.e), n(o.n) {} QTextFragment fragment() const; @@ -289,7 +289,7 @@ class Q_GUI_EXPORT QTextFragment { public: inline QTextFragment(const QTextDocumentPrivate *priv, int f, int fe) : p(priv), n(f), ne(fe) {} - inline QTextFragment() : p(0), n(0), ne(0) {} + inline QTextFragment() : p(Q_NULLPTR), n(0), ne(0) {} inline QTextFragment(const QTextFragment &o) : p(o.p), n(o.n), ne(o.ne) {} inline QTextFragment &operator=(const QTextFragment &o) { p = o.p; n = o.n; ne = o.ne; return *this; } diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index 6b17a264b1bbb89e18f482ed532c511bbc9ffe92..429e910f18b4234978a6e7002f7fcabdbe811909 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -396,7 +396,7 @@ void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextF writer.writeEndElement(); // frame } -void QTextOdfWriter::writeFormats(QXmlStreamWriter &writer, QSet<int> formats) const +void QTextOdfWriter::writeFormats(QXmlStreamWriter &writer, const QSet<int> &formats) const { writer.writeStartElement(officeNS, QString::fromLatin1("automatic-styles")); QVector<QTextFormat> allStyles = m_document->allFormats(); diff --git a/src/gui/text/qtextodfwriter_p.h b/src/gui/text/qtextodfwriter_p.h index 20805a8d275b3e8f86c3fdc6d78b8ccfbc95d172..15a4b40796f6d0905c88e841cf69ed6ec0412c57 100644 --- a/src/gui/text/qtextodfwriter_p.h +++ b/src/gui/text/qtextodfwriter_p.h @@ -83,7 +83,7 @@ public: bool createArchive() const { return m_createArchive; } void writeBlock(QXmlStreamWriter &writer, const QTextBlock &block); - void writeFormats(QXmlStreamWriter &writer, QSet<int> formatIds) const; + void writeFormats(QXmlStreamWriter &writer, const QSet<int> &formatIds) const; void writeBlockFormat(QXmlStreamWriter &writer, QTextBlockFormat format, int formatIndex) const; void writeCharacterFormat(QXmlStreamWriter &writer, QTextCharFormat format, int formatIndex) const; void writeListFormat(QXmlStreamWriter &writer, QTextListFormat format, int formatIndex) const; diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp index dbafcfd58e65f9312efb45c59746b347452f6eef..5a4f6b7954f7f8fa1e90355c039601384ba9334a 100644 --- a/src/gui/text/qtextoption.cpp +++ b/src/gui/text/qtextoption.cpp @@ -146,6 +146,7 @@ void QTextOption::setTabArray(const QList<qreal> &tabStops) d = new QTextOptionPrivate; QList<QTextOption::Tab> tabs; QTextOption::Tab tab; + tabs.reserve(tabStops.count()); foreach (qreal pos, tabStops) { tab.position = pos; tabs.append(tab); @@ -174,10 +175,11 @@ void QTextOption::setTabs(const QList<QTextOption::Tab> &tabStops) */ QList<qreal> QTextOption::tabArray() const { + QList<qreal> answer; if (!d) - return QList<qreal>(); + return answer; - QList<qreal> answer; + answer.reserve(d->tabStops.count()); QList<QTextOption::Tab>::ConstIterator iter = d->tabStops.constBegin(); while(iter != d->tabStops.constEnd()) { answer.append( (*iter).position); diff --git a/src/gui/text/qtexttable.h b/src/gui/text/qtexttable.h index 6ceb1fdd0f88498056fcf9d906ac3e614ae90d3c..4ff7d19e85e1b4bb5c11d2313885817138754ff8 100644 --- a/src/gui/text/qtexttable.h +++ b/src/gui/text/qtexttable.h @@ -48,7 +48,7 @@ class QTextTablePrivate; class Q_GUI_EXPORT QTextTableCell { public: - QTextTableCell() : table(0) {} + QTextTableCell() : table(Q_NULLPTR) {} ~QTextTableCell() {} QTextTableCell(const QTextTableCell &o) : table(o.table), fragment(o.fragment) {} QTextTableCell &operator=(const QTextTableCell &o) @@ -63,7 +63,7 @@ public: int rowSpan() const; int columnSpan() const; - inline bool isValid() const { return table != 0; } + inline bool isValid() const { return table != Q_NULLPTR; } QTextCursor firstCursorPosition() const; QTextCursor lastCursorPosition() const; diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp index edd344735751e9892dd46df4d04c04cd3b353572..6053466148166b3a83256d807291e978866b9f62 100644 --- a/src/gui/text/qzip.cpp +++ b/src/gui/text/qzip.cpp @@ -38,7 +38,6 @@ #include "qzipreader_p.h" #include "qzipwriter_p.h" #include <qdatetime.h> -#include <qplatformdefs.h> #include <qendian.h> #include <qdebug.h> #include <qdir.h> @@ -49,44 +48,6 @@ // (actually, the only basic support of this version is implemented but it is enough for now) #define ZIP_VERSION 20 -#if defined(Q_OS_WIN) -# undef S_IFREG -# define S_IFREG 0100000 -# ifndef S_IFDIR -# define S_IFDIR 0040000 -# endif -# ifndef S_ISDIR -# define S_ISDIR(x) ((x) & S_IFDIR) > 0 -# endif -# ifndef S_ISREG -# define S_ISREG(x) ((x) & 0170000) == S_IFREG -# endif -# define S_IFLNK 020000 -# define S_ISLNK(x) ((x) & S_IFLNK) > 0 -# ifndef S_IRUSR -# define S_IRUSR 0400 -# endif -# ifndef S_IWUSR -# define S_IWUSR 0200 -# endif -# ifndef S_IXUSR -# define S_IXUSR 0100 -# endif -# define S_IRGRP 0040 -# define S_IWGRP 0020 -# define S_IXGRP 0010 -# define S_IROTH 0004 -# define S_IWOTH 0002 -# define S_IXOTH 0001 -#endif - -#ifndef FILE_ATTRIBUTE_READONLY -# define FILE_ATTRIBUTE_READONLY 0x1 -#endif -#ifndef FILE_ATTRIBUTE_DIRECTORY -# define FILE_ATTRIBUTE_DIRECTORY 0x10 -#endif - #if 0 #define ZDEBUG qDebug #else @@ -159,36 +120,6 @@ static void writeMSDosDate(uchar *dest, const QDateTime& dt) } } -static quint32 permissionsToMode(QFile::Permissions perms) -{ - quint32 mode = 0; - if (perms & QFile::ReadOwner) - mode |= S_IRUSR; - if (perms & QFile::WriteOwner) - mode |= S_IWUSR; - if (perms & QFile::ExeOwner) - mode |= S_IXUSR; - if (perms & QFile::ReadUser) - mode |= S_IRUSR; - if (perms & QFile::WriteUser) - mode |= S_IWUSR; - if (perms & QFile::ExeUser) - mode |= S_IXUSR; - if (perms & QFile::ReadGroup) - mode |= S_IRGRP; - if (perms & QFile::WriteGroup) - mode |= S_IWGRP; - if (perms & QFile::ExeGroup) - mode |= S_IXGRP; - if (perms & QFile::ReadOther) - mode |= S_IROTH; - if (perms & QFile::WriteOther) - mode |= S_IWOTH; - if (perms & QFile::ExeOther) - mode |= S_IXOTH; - return mode; -} - static int inflate(Bytef *dest, ulong *destLen, const Bytef *source, ulong sourceLen) { z_stream stream; @@ -253,36 +184,86 @@ static int deflate (Bytef *dest, ulong *destLen, const Bytef *source, ulong sour return err; } + +namespace WindowsFileAttributes { +enum { + Dir = 0x10, // FILE_ATTRIBUTE_DIRECTORY + File = 0x80, // FILE_ATTRIBUTE_NORMAL + TypeMask = 0x90, + + ReadOnly = 0x01, // FILE_ATTRIBUTE_READONLY + PermMask = 0x01 +}; +} + +namespace UnixFileAttributes { +enum { + Dir = 0040000, // __S_IFDIR + File = 0100000, // __S_IFREG + SymLink = 0120000, // __S_IFLNK + TypeMask = 0170000, // __S_IFMT + + ReadUser = 0400, // __S_IRUSR + WriteUser = 0200, // __S_IWUSR + ExeUser = 0100, // __S_IXUSR + ReadGroup = 0040, // __S_IRGRP + WriteGroup = 0020, // __S_IWGRP + ExeGroup = 0010, // __S_IXGRP + ReadOther = 0004, // __S_IROTH + WriteOther = 0002, // __S_IWOTH + ExeOther = 0001, // __S_IXOTH + PermMask = 0777 +}; +} + static QFile::Permissions modeToPermissions(quint32 mode) { QFile::Permissions ret; - if (mode & S_IRUSR) - ret |= QFile::ReadOwner; - if (mode & S_IWUSR) - ret |= QFile::WriteOwner; - if (mode & S_IXUSR) - ret |= QFile::ExeOwner; - if (mode & S_IRUSR) - ret |= QFile::ReadUser; - if (mode & S_IWUSR) - ret |= QFile::WriteUser; - if (mode & S_IXUSR) - ret |= QFile::ExeUser; - if (mode & S_IRGRP) + if (mode & UnixFileAttributes::ReadUser) + ret |= QFile::ReadOwner | QFile::ReadUser; + if (mode & UnixFileAttributes::WriteUser) + ret |= QFile::WriteOwner | QFile::WriteUser; + if (mode & UnixFileAttributes::ExeUser) + ret |= QFile::ExeOwner | QFile::ExeUser; + if (mode & UnixFileAttributes::ReadGroup) ret |= QFile::ReadGroup; - if (mode & S_IWGRP) + if (mode & UnixFileAttributes::WriteGroup) ret |= QFile::WriteGroup; - if (mode & S_IXGRP) + if (mode & UnixFileAttributes::ExeGroup) ret |= QFile::ExeGroup; - if (mode & S_IROTH) + if (mode & UnixFileAttributes::ReadOther) ret |= QFile::ReadOther; - if (mode & S_IWOTH) + if (mode & UnixFileAttributes::WriteOther) ret |= QFile::WriteOther; - if (mode & S_IXOTH) + if (mode & UnixFileAttributes::ExeOther) ret |= QFile::ExeOther; return ret; } +static quint32 permissionsToMode(QFile::Permissions perms) +{ + quint32 mode = 0; + if (mode & (QFile::ReadOwner | QFile::ReadUser)) + mode |= UnixFileAttributes::ReadUser; + if (mode & (QFile::WriteOwner | QFile::WriteUser)) + mode |= UnixFileAttributes::WriteUser; + if (mode & (QFile::ExeOwner | QFile::ExeUser)) + mode |= UnixFileAttributes::WriteUser; + if (perms & QFile::ReadGroup) + mode |= UnixFileAttributes::ReadGroup; + if (perms & QFile::WriteGroup) + mode |= UnixFileAttributes::WriteGroup; + if (perms & QFile::ExeGroup) + mode |= UnixFileAttributes::ExeGroup; + if (perms & QFile::ReadOther) + mode |= UnixFileAttributes::ReadOther; + if (perms & QFile::WriteOther) + mode |= UnixFileAttributes::WriteOther; + if (perms & QFile::ExeOther) + mode |= UnixFileAttributes::ExeOther; + return mode; +} + static QDateTime readMSDosDate(const uchar *src) { uint dosDate = readUInt(src); @@ -322,6 +303,7 @@ enum HostOS { HostOS400 = 18, HostOSX = 19 }; +Q_DECLARE_TYPEINFO(HostOS, Q_PRIMITIVE_TYPE); enum GeneralPurposeFlag { Encrypted = 0x01, @@ -333,6 +315,7 @@ enum GeneralPurposeFlag { Utf8Names = 0x0800, CentralDirectoryEncrypted = 0x2000 }; +Q_DECLARE_TYPEINFO(GeneralPurposeFlag, Q_PRIMITIVE_TYPE); enum CompressionMethod { CompressionMethodStored = 0, @@ -359,6 +342,7 @@ enum CompressionMethod { CompressionMethodPPMd = 98, CompressionMethodWzAES = 99 }; +Q_DECLARE_TYPEINFO(CompressionMethod, Q_PRIMITIVE_TYPE); struct LocalFileHeader { @@ -373,6 +357,7 @@ struct LocalFileHeader uchar file_name_length[2]; uchar extra_field_length[2]; }; +Q_DECLARE_TYPEINFO(LocalFileHeader, Q_PRIMITIVE_TYPE); struct DataDescriptor { @@ -380,6 +365,7 @@ struct DataDescriptor uchar compressed_size[4]; uchar uncompressed_size[4]; }; +Q_DECLARE_TYPEINFO(DataDescriptor, Q_PRIMITIVE_TYPE); struct CentralFileHeader { @@ -401,6 +387,7 @@ struct CentralFileHeader uchar offset_local_header[4]; LocalFileHeader toLocalHeader() const; }; +Q_DECLARE_TYPEINFO(CentralFileHeader, Q_PRIMITIVE_TYPE); struct EndOfDirectory { @@ -413,6 +400,7 @@ struct EndOfDirectory uchar dir_start_offset[4]; uchar comment_length[2]; }; +Q_DECLARE_TYPEINFO(EndOfDirectory, Q_PRIMITIVE_TYPE); struct FileHeader { @@ -421,38 +409,7 @@ struct FileHeader QByteArray extra_field; QByteArray file_comment; }; - -QZipReader::FileInfo::FileInfo() - : isDir(false), isFile(false), isSymLink(false), crc(0), size(0) -{ -} - -QZipReader::FileInfo::~FileInfo() -{ -} - -QZipReader::FileInfo::FileInfo(const FileInfo &other) -{ - operator=(other); -} - -QZipReader::FileInfo& QZipReader::FileInfo::operator=(const FileInfo &other) -{ - filePath = other.filePath; - isDir = other.isDir; - isFile = other.isFile; - isSymLink = other.isSymLink; - permissions = other.permissions; - crc = other.crc; - size = other.size; - lastModified = other.lastModified; - return *this; -} - -bool QZipReader::FileInfo::isValid() const -{ - return isDir || isFile || isSymLink; -} +Q_DECLARE_TYPEINFO(FileHeader, Q_MOVABLE_TYPE); class QZipPrivate { @@ -468,49 +425,61 @@ public: delete device; } - void fillFileInfo(int index, QZipReader::FileInfo &fileInfo) const; + QZipReader::FileInfo fillFileInfo(int index) const; QIODevice *device; bool ownDevice; bool dirtyFileTree; - QList<FileHeader> fileHeaders; + QVector<FileHeader> fileHeaders; QByteArray comment; uint start_of_directory; }; -void QZipPrivate::fillFileInfo(int index, QZipReader::FileInfo &fileInfo) const +QZipReader::FileInfo QZipPrivate::fillFileInfo(int index) const { + QZipReader::FileInfo fileInfo; FileHeader header = fileHeaders.at(index); quint32 mode = readUInt(header.h.external_file_attributes); const HostOS hostOS = HostOS(readUShort(header.h.version_made) >> 8); switch (hostOS) { case HostUnix: mode = (mode >> 16) & 0xffff; - if (S_ISDIR(mode)) + switch (mode & UnixFileAttributes::TypeMask) { + case UnixFileAttributes::SymLink: + fileInfo.isSymLink = true; + break; + case UnixFileAttributes::Dir: fileInfo.isDir = true; - else if (S_ISREG(mode)) + break; + case UnixFileAttributes::File: + default: // ### just for the case; should we warn? fileInfo.isFile = true; - else if (S_ISLNK(mode)) - fileInfo.isSymLink = true; + break; + } fileInfo.permissions = modeToPermissions(mode); break; case HostFAT: case HostNTFS: case HostHPFS: case HostVFAT: - fileInfo.permissions |= QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther; - if ((mode & FILE_ATTRIBUTE_READONLY) == 0) - fileInfo.permissions |= QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther; - if ((mode & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { + switch (mode & WindowsFileAttributes::TypeMask) { + case WindowsFileAttributes::Dir: fileInfo.isDir = true; - fileInfo.permissions |= QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther; - } else { + break; + case WindowsFileAttributes::File: + default: fileInfo.isFile = true; + break; } + fileInfo.permissions |= QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther; + if ((mode & WindowsFileAttributes::ReadOnly) == 0) + fileInfo.permissions |= QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther; + if (fileInfo.isDir) + fileInfo.permissions |= QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther; break; default: qWarning("QZip: Zip entry format at %d is not supported.", index); - return; // we don't support anything else + return fileInfo; // we don't support anything else } ushort general_purpose_bits = readUShort(header.h.general_purpose_bits); @@ -527,6 +496,8 @@ void QZipPrivate::fillFileInfo(int index, QZipReader::FileInfo &fileInfo) const fileInfo.filePath = fileInfo.filePath.mid(1); while (!fileInfo.filePath.isEmpty() && fileInfo.filePath.at(fileInfo.filePath.size() - 1) == QLatin1Char('/')) fileInfo.filePath.chop(1); + + return fileInfo; } class QZipReaderPrivate : public QZipPrivate @@ -753,9 +724,18 @@ void QZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const //uchar external_file_attributes[4]; quint32 mode = permissionsToMode(permissions); switch (type) { - case File: mode |= S_IFREG; break; - case Directory: mode |= S_IFDIR; break; - case Symlink: mode |= S_IFLNK; break; + case Symlink: + mode |= UnixFileAttributes::SymLink; + break; + case Directory: + mode |= UnixFileAttributes::Dir; + break; + case File: + mode |= UnixFileAttributes::File; + break; + default: + Q_UNREACHABLE(); + break; } writeUInt(header.h.external_file_attributes, mode << 16); writeUInt(header.h.offset_local_header, start_of_directory); @@ -912,15 +892,14 @@ bool QZipReader::exists() const /*! Returns the list of files the archive contains. */ -QList<QZipReader::FileInfo> QZipReader::fileInfoList() const +QVector<QZipReader::FileInfo> QZipReader::fileInfoList() const { d->scanFiles(); - QList<QZipReader::FileInfo> files; - for (int i = 0; i < d->fileHeaders.size(); ++i) { - QZipReader::FileInfo fi; - d->fillFileInfo(i, fi); - files.append(fi); - } + QVector<FileInfo> files; + const int numFileHeaders = d->fileHeaders.size(); + files.reserve(numFileHeaders); + for (int i = 0; i < numFileHeaders; ++i) + files.append(d->fillFileInfo(i)); return files; } @@ -944,10 +923,9 @@ int QZipReader::count() const QZipReader::FileInfo QZipReader::entryInfoAt(int index) const { d->scanFiles(); - QZipReader::FileInfo fi; if (index >= 0 && index < d->fileHeaders.count()) - d->fillFileInfo(index, fi); - return fi; + return d->fillFileInfo(index); + return QZipReader::FileInfo(); } /*! @@ -1043,7 +1021,7 @@ bool QZipReader::extractAll(const QString &destinationDir) const QDir baseDir(destinationDir); // create directories first - QList<FileInfo> allFiles = fileInfoList(); + const QVector<FileInfo> allFiles = fileInfoList(); foreach (const FileInfo &fi, allFiles) { const QString absPath = destinationDir + QDir::separator() + fi.filePath; if (fi.isDir) { diff --git a/src/gui/text/qzipreader_p.h b/src/gui/text/qzipreader_p.h index df7e2d26e98d42f0621999a3f37e5342dcec2348..7f26bfb184a605a72e333961cace7413b05cd819 100644 --- a/src/gui/text/qzipreader_p.h +++ b/src/gui/text/qzipreader_p.h @@ -70,13 +70,14 @@ public: bool isReadable() const; bool exists() const; - struct Q_GUI_EXPORT FileInfo + struct FileInfo { - FileInfo(); - FileInfo(const FileInfo &other); - ~FileInfo(); - FileInfo &operator=(const FileInfo &other); - bool isValid() const; + FileInfo() Q_DECL_NOTHROW + : isDir(false), isFile(false), isSymLink(false), crc(0), size(0) + {} + + bool isValid() const Q_DECL_NOTHROW { return isDir || isFile || isSymLink; } + QString filePath; uint isDir : 1; uint isFile : 1; @@ -85,10 +86,9 @@ public: uint crc; qint64 size; QDateTime lastModified; - void *d; }; - QList<FileInfo> fileInfoList() const; + QVector<FileInfo> fileInfoList() const; int count() const; FileInfo entryInfoAt(int index) const; @@ -111,6 +111,8 @@ private: QZipReaderPrivate *d; Q_DISABLE_COPY(QZipReader) }; +Q_DECLARE_TYPEINFO(QZipReader::FileInfo, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(QZipReader::Status, Q_PRIMITIVE_TYPE); QT_END_NAMESPACE diff --git a/src/gui/util/qvalidator.h b/src/gui/util/qvalidator.h index 0435e4e9ffc372d157363cefc5b9b416bd69d9a0..a979a268aacdc16021df1a28ae709fef7417d572 100644 --- a/src/gui/util/qvalidator.h +++ b/src/gui/util/qvalidator.h @@ -52,7 +52,7 @@ class Q_GUI_EXPORT QValidator : public QObject { Q_OBJECT public: - explicit QValidator(QObject * parent = 0); + explicit QValidator(QObject * parent = Q_NULLPTR); ~QValidator(); enum State { @@ -86,8 +86,8 @@ class Q_GUI_EXPORT QIntValidator : public QValidator Q_PROPERTY(int top READ top WRITE setTop NOTIFY topChanged) public: - explicit QIntValidator(QObject * parent = 0); - QIntValidator(int bottom, int top, QObject *parent = 0); + explicit QIntValidator(QObject * parent = Q_NULLPTR); + QIntValidator(int bottom, int top, QObject *parent = Q_NULLPTR); ~QIntValidator(); QValidator::State validate(QString &, int &) const Q_DECL_OVERRIDE; @@ -123,8 +123,8 @@ class Q_GUI_EXPORT QDoubleValidator : public QValidator Q_PROPERTY(Notation notation READ notation WRITE setNotation NOTIFY notationChanged) public: - explicit QDoubleValidator(QObject * parent = 0); - QDoubleValidator(double bottom, double top, int decimals, QObject *parent = 0); + explicit QDoubleValidator(QObject * parent = Q_NULLPTR); + QDoubleValidator(double bottom, double top, int decimals, QObject *parent = Q_NULLPTR); ~QDoubleValidator(); enum Notation { @@ -167,8 +167,8 @@ class Q_GUI_EXPORT QRegExpValidator : public QValidator Q_PROPERTY(QRegExp regExp READ regExp WRITE setRegExp NOTIFY regExpChanged) public: - explicit QRegExpValidator(QObject *parent = 0); - explicit QRegExpValidator(const QRegExp& rx, QObject *parent = 0); + explicit QRegExpValidator(QObject *parent = Q_NULLPTR); + explicit QRegExpValidator(const QRegExp& rx, QObject *parent = Q_NULLPTR); ~QRegExpValidator(); virtual QValidator::State validate(QString& input, int& pos) const Q_DECL_OVERRIDE; @@ -197,8 +197,8 @@ class Q_GUI_EXPORT QRegularExpressionValidator : public QValidator Q_PROPERTY(QRegularExpression regularExpression READ regularExpression WRITE setRegularExpression NOTIFY regularExpressionChanged) public: - explicit QRegularExpressionValidator(QObject *parent = 0); - explicit QRegularExpressionValidator(const QRegularExpression &re, QObject *parent = 0); + explicit QRegularExpressionValidator(QObject *parent = Q_NULLPTR); + explicit QRegularExpressionValidator(const QRegularExpression &re, QObject *parent = Q_NULLPTR); ~QRegularExpressionValidator(); virtual QValidator::State validate(QString &input, int &pos) const Q_DECL_OVERRIDE; diff --git a/src/network/access/qabstractnetworkcache.h b/src/network/access/qabstractnetworkcache.h index 352daa9700b5631c4f711b053e06467d09247f6f..326891b3dccf0e0be952757e8ee82c96f3dc7a56 100644 --- a/src/network/access/qabstractnetworkcache.h +++ b/src/network/access/qabstractnetworkcache.h @@ -60,9 +60,12 @@ public: QNetworkCacheMetaData(const QNetworkCacheMetaData &other); ~QNetworkCacheMetaData(); +#ifdef Q_COMPILER_RVALUE_REFS + QNetworkCacheMetaData &operator=(QNetworkCacheMetaData &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QNetworkCacheMetaData &operator=(const QNetworkCacheMetaData &other); - void swap(QNetworkCacheMetaData &other) + void swap(QNetworkCacheMetaData &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool operator==(const QNetworkCacheMetaData &other) const; @@ -121,7 +124,7 @@ public Q_SLOTS: virtual void clear() = 0; protected: - explicit QAbstractNetworkCache(QObject *parent = 0); + explicit QAbstractNetworkCache(QObject *parent = Q_NULLPTR); QAbstractNetworkCache(QAbstractNetworkCachePrivate &dd, QObject *parent); private: diff --git a/src/network/access/qhttpmultipart.h b/src/network/access/qhttpmultipart.h index 2e08a3d6f808db949d6299f377ce52822f810913..5f865c059b767cc4dadafe3f5cb44bc23c82cbef 100644 --- a/src/network/access/qhttpmultipart.h +++ b/src/network/access/qhttpmultipart.h @@ -51,9 +51,12 @@ public: QHttpPart(); QHttpPart(const QHttpPart &other); ~QHttpPart(); +#ifdef Q_COMPILER_RVALUE_REFS + QHttpPart &operator=(QHttpPart &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QHttpPart &operator=(const QHttpPart &other); - void swap(QHttpPart &other) { qSwap(d, other.d); } + void swap(QHttpPart &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool operator==(const QHttpPart &other) const; inline bool operator!=(const QHttpPart &other) const @@ -88,8 +91,8 @@ public: AlternativeType }; - explicit QHttpMultiPart(QObject *parent = 0); - explicit QHttpMultiPart(ContentType contentType, QObject *parent = 0); + explicit QHttpMultiPart(QObject *parent = Q_NULLPTR); + explicit QHttpMultiPart(ContentType contentType, QObject *parent = Q_NULLPTR); ~QHttpMultiPart(); void append(const QHttpPart &httpPart); diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 0732a38a6e65465d2faf64ebc9b7489b99cba8cc..16ed67fbc09188a4db828890c447f91b206236c9 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -1443,7 +1443,7 @@ void QHttpNetworkConnectionPrivate::emitProxyAuthenticationRequired(const QHttpN // but that does not matter because the signal will ultimately be emitted // by the QNetworkAccessManager. Q_ASSERT(chan->spdyRequestsToSend.count() > 0); - reply = chan->spdyRequestsToSend.values().first().second; + reply = chan->spdyRequestsToSend.cbegin().value().second; } else { // HTTP #endif // QT_NO_SSL reply = chan->reply; diff --git a/src/network/access/qhttpnetworkheader.cpp b/src/network/access/qhttpnetworkheader.cpp index af9f38cdec02a334feb41d78ca0876a588d7f123..cf8259294d7a30d43b5103ba4887d6740f5f2c1d 100644 --- a/src/network/access/qhttpnetworkheader.cpp +++ b/src/network/access/qhttpnetworkheader.cpp @@ -79,16 +79,8 @@ QByteArray QHttpNetworkHeaderPrivate::headerField(const QByteArray &name, const QList<QByteArray> allValues = headerFieldValues(name); if (allValues.isEmpty()) return defaultValue; - - QByteArray result; - bool first = true; - foreach (const QByteArray &value, allValues) { - if (!first) - result += ", "; - first = false; - result += value; - } - return result; + else + return allValues.join(", "); } QList<QByteArray> QHttpNetworkHeaderPrivate::headerFieldValues(const QByteArray &name) const diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 2758c79a29b6f683c8c62e0783c6333cfb67c98b..c4664246d8888830c2e017ae8426a95782d6dc30 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -455,7 +455,6 @@ static void ensureInitialized() QNetworkAccessManager::QNetworkAccessManager(QObject *parent) : QObject(*new QNetworkAccessManagerPrivate, parent) { - Q_D(QNetworkAccessManager); ensureInitialized(); qRegisterMetaType<QNetworkReply::NetworkError>(); @@ -475,16 +474,17 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent) qRegisterMetaType<QSharedPointer<char> >(); #ifndef QT_NO_BEARERMANAGEMENT + Q_D(QNetworkAccessManager); if (!d->networkSessionRequired) { // if a session is required, we track online state through // the QNetworkSession's signals connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)), SLOT(_q_onlineStateChanged(bool))); - // we would need all active configurations to check for - // d->networkConfigurationManager.isOnline(), which is asynchronous - // and potentially expensive. We can just check the configuration here - d->online = (d->networkConfiguration.state() & QNetworkConfiguration::Active); } + // we would need all active configurations to check for + // d->networkConfigurationManager.isOnline(), which is asynchronous + // and potentially expensive. We can just check the configuration here + d->online = (d->networkConfiguration.state() & QNetworkConfiguration::Active); #else Q_UNUSED(d); #endif @@ -956,6 +956,7 @@ QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const void QNetworkAccessManager::setNetworkAccessible(QNetworkAccessManager::NetworkAccessibility accessible) { Q_D(QNetworkAccessManager); + d->defaultAccessControl = false; if (d->networkAccessible != accessible) { NetworkAccessibility previous = networkAccessible(); @@ -974,7 +975,6 @@ void QNetworkAccessManager::setNetworkAccessible(QNetworkAccessManager::NetworkA QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccessible() const { Q_D(const QNetworkAccessManager); - if (d->networkSessionRequired) { QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession()); if (networkSession) { @@ -985,7 +985,13 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess return NotAccessible; } else { // Network accessibility is either disabled or unknown. - return (d->networkAccessible == NotAccessible) ? NotAccessible : UnknownAccessibility; + if (d->defaultAccessControl) { + if (d->online) + return d->networkAccessible; + else + return NotAccessible; + } + return (d->networkAccessible); } } else { if (d->online) @@ -1584,7 +1590,7 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co if (!networkSessionStrongRef) { online = false; - if (networkAccessible == QNetworkAccessManager::NotAccessible) + if (networkAccessible == QNetworkAccessManager::NotAccessible || !online) emit q->networkAccessibleChanged(QNetworkAccessManager::NotAccessible); else emit q->networkAccessibleChanged(QNetworkAccessManager::UnknownAccessibility); @@ -1632,11 +1638,14 @@ void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession if (online) { if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) { online = false; - emit q->networkAccessibleChanged(QNetworkAccessManager::NotAccessible); + networkAccessible = QNetworkAccessManager::NotAccessible; + emit q->networkAccessibleChanged(networkAccessible); } } else { if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) { online = true; + if (defaultAccessControl) + networkAccessible = QNetworkAccessManager::Accessible; emit q->networkAccessibleChanged(networkAccessible); } } diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h index 988eafa18b64906e4968c067c49849fcabb7c0ef..c8df213eadfceac1f15d299bc3516ef9b4cb46db 100644 --- a/src/network/access/qnetworkaccessmanager.h +++ b/src/network/access/qnetworkaccessmanager.h @@ -90,7 +90,7 @@ public: }; #endif - explicit QNetworkAccessManager(QObject *parent = 0); + explicit QNetworkAccessManager(QObject *parent = Q_NULLPTR); ~QNetworkAccessManager(); // ### Qt 6: turn into virtual @@ -120,7 +120,7 @@ public: QNetworkReply *put(const QNetworkRequest &request, const QByteArray &data); QNetworkReply *put(const QNetworkRequest &request, QHttpMultiPart *multiPart); QNetworkReply *deleteResource(const QNetworkRequest &request); - QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = 0); + QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = Q_NULLPTR); #ifndef QT_NO_BEARERMANAGEMENT void setConfiguration(const QNetworkConfiguration &config); @@ -157,7 +157,7 @@ Q_SIGNALS: protected: virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, - QIODevice *outgoingData = 0); + QIODevice *outgoingData = Q_NULLPTR); protected Q_SLOTS: QStringList supportedSchemesImplementation() const; diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index f5133244619d80cda7983d2abe07d2c5835b7550..c715da00c167132a7a121e5f32f0f646f16f1b78 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -84,6 +84,7 @@ public: initializeSession(true), #endif cookieJarCreated(false), + defaultAccessControl(true), authenticationManager(QSharedPointer<QNetworkAccessAuthenticationManager>::create()) { } ~QNetworkAccessManagerPrivate(); @@ -164,6 +165,7 @@ public: #endif bool cookieJarCreated; + bool defaultAccessControl; // The cache with authorization data: QSharedPointer<QNetworkAccessAuthenticationManager> authenticationManager; diff --git a/src/network/access/qnetworkcookie.h b/src/network/access/qnetworkcookie.h index 2da86d3f818e6b26214f35d8e1be5b6ea2c1fc91..27925c8201159d18e8557c5aba0ff5d9f887390c 100644 --- a/src/network/access/qnetworkcookie.h +++ b/src/network/access/qnetworkcookie.h @@ -59,9 +59,12 @@ public: explicit QNetworkCookie(const QByteArray &name = QByteArray(), const QByteArray &value = QByteArray()); QNetworkCookie(const QNetworkCookie &other); ~QNetworkCookie(); +#ifdef Q_COMPILER_RVALUE_REFS + QNetworkCookie &operator=(QNetworkCookie &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QNetworkCookie &operator=(const QNetworkCookie &other); - void swap(QNetworkCookie &other) { qSwap(d, other.d); } + void swap(QNetworkCookie &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool operator==(const QNetworkCookie &other) const; inline bool operator!=(const QNetworkCookie &other) const diff --git a/src/network/access/qnetworkcookiejar.h b/src/network/access/qnetworkcookiejar.h index 59ba7f87389aa10aefb60ab2faa7de807d89e58b..3ac78ea1c3dc062a96de76d8ca0a5d825644edca 100644 --- a/src/network/access/qnetworkcookiejar.h +++ b/src/network/access/qnetworkcookiejar.h @@ -47,7 +47,7 @@ class Q_NETWORK_EXPORT QNetworkCookieJar: public QObject { Q_OBJECT public: - explicit QNetworkCookieJar(QObject *parent = 0); + explicit QNetworkCookieJar(QObject *parent = Q_NULLPTR); virtual ~QNetworkCookieJar(); virtual QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const; diff --git a/src/network/access/qnetworkdiskcache.h b/src/network/access/qnetworkdiskcache.h index 568d34dc0f4540e378ebd153074b3513a13607b5..533eabce9b50a8f42d5cfe1c5dc048a0c3a535e2 100644 --- a/src/network/access/qnetworkdiskcache.h +++ b/src/network/access/qnetworkdiskcache.h @@ -47,7 +47,7 @@ class Q_NETWORK_EXPORT QNetworkDiskCache : public QAbstractNetworkCache Q_OBJECT public: - explicit QNetworkDiskCache(QObject *parent = 0); + explicit QNetworkDiskCache(QObject *parent = Q_NULLPTR); ~QNetworkDiskCache(); QString cacheDirectory() const; diff --git a/src/network/access/qnetworkreply.h b/src/network/access/qnetworkreply.h index 672a69e12b98d47c2b4b1489b82d545feaf1dc49..254dd3ff121c5617636bf13f2101e26fef500234 100644 --- a/src/network/access/qnetworkreply.h +++ b/src/network/access/qnetworkreply.h @@ -161,7 +161,7 @@ Q_SIGNALS: void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); protected: - explicit QNetworkReply(QObject *parent = 0); + explicit QNetworkReply(QObject *parent = Q_NULLPTR); QNetworkReply(QNetworkReplyPrivate &dd, QObject *parent); virtual qint64 writeData(const char *data, qint64 len) Q_DECL_OVERRIDE; diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index c08648c47b19e7a2d8a00b7b4160fda24474d472..8c0c0981472e13d4d0a8f7a561ce81f9154f1845 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -49,6 +49,8 @@ #include "qthread.h" #include "QtCore/qcoreapplication.h" +#include <QtCore/private/qthread_p.h> + #include "qnetworkcookiejar.h" #ifndef QT_NO_HTTP diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 6b6265db323a9eab1f0a3fff702349960acb96f6..a73e0ea75eb2283d6644fe13c4f317b35f03aafb 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -65,8 +65,6 @@ inline QNetworkReplyImplPrivate::QNetworkReplyImplPrivate() void QNetworkReplyImplPrivate::_q_startOperation() { - Q_Q(QNetworkReplyImpl); - // ensure this function is only being called once if (state == Working || state == Finished) { qDebug("QNetworkReplyImpl::_q_startOperation was called more than once"); @@ -85,6 +83,7 @@ void QNetworkReplyImplPrivate::_q_startOperation() } #ifndef QT_NO_BEARERMANAGEMENT + Q_Q(QNetworkReplyImpl); // Do not start background requests if they are not allowed by session policy QSharedPointer<QNetworkSession> session(manager->d_func()->getNetworkSession()); QVariant isBackground = backend->request().attribute(QNetworkRequest::BackgroundRequestAttribute, QVariant::fromValue(false)); diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h index d2e7d02408ef3b2b1fcdbb61e69c1f08b9972e0d..088cb80653542b6236514f0f7072f94fbdf931bb 100644 --- a/src/network/access/qnetworkreplyimpl_p.h +++ b/src/network/access/qnetworkreplyimpl_p.h @@ -203,6 +203,7 @@ public: Q_DECLARE_PUBLIC(QNetworkReplyImpl) }; +Q_DECLARE_TYPEINFO(QNetworkReplyImplPrivate::InternalNotifications, Q_PRIMITIVE_TYPE); #ifndef QT_NO_BEARERMANAGEMENT class QDisabledNetworkReply : public QNetworkReply diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 94e2b437b3c31621821a6fbbc71bc6d00af70576..558e015ae4c02915bd4c4e506d6cd9dfe229c33a 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -919,6 +919,7 @@ QNetworkHeadersPrivate::RawHeadersList QNetworkHeadersPrivate::allRawHeaders() c QList<QByteArray> QNetworkHeadersPrivate::rawHeadersKeys() const { QList<QByteArray> result; + result.reserve(rawHeaders.size()); RawHeadersList::ConstIterator it = rawHeaders.constBegin(), end = rawHeaders.constEnd(); for ( ; it != end; ++it) diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h index c726db78cb7c4a877cde0207f766fc9cbb858a78..eb343c97df47f2e0ed89c173c45d612234de1412 100644 --- a/src/network/access/qnetworkrequest.h +++ b/src/network/access/qnetworkrequest.h @@ -106,9 +106,12 @@ public: explicit QNetworkRequest(const QUrl &url = QUrl()); QNetworkRequest(const QNetworkRequest &other); ~QNetworkRequest(); +#ifdef Q_COMPILER_RVALUE_REFS + QNetworkRequest &operator=(QNetworkRequest &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QNetworkRequest &operator=(const QNetworkRequest &other); - inline void swap(QNetworkRequest &other) { qSwap(d, other.d); } + void swap(QNetworkRequest &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool operator==(const QNetworkRequest &other) const; inline bool operator!=(const QNetworkRequest &other) const diff --git a/src/network/access/qspdyprotocolhandler.cpp b/src/network/access/qspdyprotocolhandler.cpp index 7430ca029d6733f8ce4fc29d90b0a41ef796bcc6..7d2c0dfef2b6d7a5737b837a7e954856584f80cb 100644 --- a/src/network/access/qspdyprotocolhandler.cpp +++ b/src/network/access/qspdyprotocolhandler.cpp @@ -288,16 +288,14 @@ bool QSpdyProtocolHandler::sendRequest() m_channel->state = QHttpNetworkConnectionChannel::WritingState; - // requests will be ordered by priority (see QMultiMap doc) - QList<HttpMessagePair> requests = m_channel->spdyRequestsToSend.values(); - QList<int> priorities = m_channel->spdyRequestsToSend.keys(); - - int requestsToSend = qMin(requests.count(), maxPossibleRequests); + int requestsToSend = qMin(m_channel->spdyRequestsToSend.size(), maxPossibleRequests); + QMultiMap<int, HttpMessagePair>::iterator it = m_channel->spdyRequestsToSend.begin(); + // requests will be ordered by priority (see QMultiMap doc) for (int a = 0; a < requestsToSend; ++a) { - HttpMessagePair currentPair = requests.at(a); - QHttpNetworkRequest currentRequest = requests.at(a).first; - QHttpNetworkReply *currentReply = requests.at(a).second; + HttpMessagePair currentPair = *it; + QHttpNetworkRequest currentRequest = currentPair.first; + QHttpNetworkReply *currentReply = currentPair.second; currentReply->setSpdyWasUsed(true); qint32 streamID = generateNextStreamID(); @@ -310,10 +308,7 @@ bool QSpdyProtocolHandler::sendRequest() connect(currentReply, SIGNAL(destroyed(QObject*)), this, SLOT(_q_replyDestroyed(QObject*))); sendSYN_STREAM(currentPair, streamID, /* associatedToStreamID = */ 0); - int requestsRemoved = m_channel->spdyRequestsToSend.remove( - priorities.at(a), currentPair); - Q_ASSERT(requestsRemoved == 1); - Q_UNUSED(requestsRemoved); // silence -Wunused-variable + m_channel->spdyRequestsToSend.erase(it++); } m_channel->state = QHttpNetworkConnectionChannel::IdleState; return true; diff --git a/src/network/bearer/qnetworkconfigmanager.h b/src/network/bearer/qnetworkconfigmanager.h index b62a44c422cdd497f204917e9e87eee59c77dfab..84080ba83e7c4054f5deabe098acc211182cec72 100644 --- a/src/network/bearer/qnetworkconfigmanager.h +++ b/src/network/bearer/qnetworkconfigmanager.h @@ -59,13 +59,13 @@ public: Q_DECLARE_FLAGS(Capabilities, Capability) - explicit QNetworkConfigurationManager(QObject *parent = 0); + explicit QNetworkConfigurationManager(QObject *parent = Q_NULLPTR); virtual ~QNetworkConfigurationManager(); QNetworkConfigurationManager::Capabilities capabilities() const; QNetworkConfiguration defaultConfiguration() const; - QList<QNetworkConfiguration> allConfigurations(QNetworkConfiguration::StateFlags flags = 0) const; + QList<QNetworkConfiguration> allConfigurations(QNetworkConfiguration::StateFlags flags = QNetworkConfiguration::StateFlags()) const; QNetworkConfiguration configurationFromIdentifier(const QString &identifier) const; bool isOnline() const; diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index c1e837de7b59d402371b6e67cb17f6c0ef730450..78d4970ca1c4f21ba2e68707331bb5ac8e20b985 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -41,6 +41,7 @@ #include <QtCore/qstringlist.h> #include <QtCore/qthread.h> #include <QtCore/private/qcoreapplication_p.h> +#include <QtCore/private/qthread_p.h> #ifndef QT_NO_BEARERMANAGEMENT @@ -61,7 +62,7 @@ QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate() void QNetworkConfigurationManagerPrivate::initialize() { //Two stage construction, because we only want to do this heavyweight work for the winner of the Q_GLOBAL_STATIC race. - bearerThread = new QThread(); + bearerThread = new QDaemonThread(); bearerThread->setObjectName(QStringLiteral("Qt bearer thread")); bearerThread->moveToThread(QCoreApplicationPrivate::mainThread()); // because cleanup() is called in main thread context. diff --git a/src/network/bearer/qnetworkconfiguration.h b/src/network/bearer/qnetworkconfiguration.h index dbef344e6900a3ba5f59f81eb157d18ce13f3b60..317c232bea7bd0fc1edbe1bcd2d79a1021a88b4d 100644 --- a/src/network/bearer/qnetworkconfiguration.h +++ b/src/network/bearer/qnetworkconfiguration.h @@ -49,10 +49,13 @@ class Q_NETWORK_EXPORT QNetworkConfiguration public: QNetworkConfiguration(); QNetworkConfiguration(const QNetworkConfiguration& other); +#ifdef Q_COMPILER_RVALUE_REFS + QNetworkConfiguration &operator=(QNetworkConfiguration &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QNetworkConfiguration &operator=(const QNetworkConfiguration &other); ~QNetworkConfiguration(); - void swap(QNetworkConfiguration &other) { qSwap(d, other.d); } + void swap(QNetworkConfiguration &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool operator==(const QNetworkConfiguration &other) const; inline bool operator!=(const QNetworkConfiguration &other) const diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp index 35aa3cd2c9dc0656c175bbe664073ca14d5d972d..6f83fd25ca602de738e84dd3e646064f97810f58 100644 --- a/src/network/bearer/qnetworksession.cpp +++ b/src/network/bearer/qnetworksession.cpp @@ -468,7 +468,7 @@ QString QNetworkSession::errorString() const The following property keys are guaranteed to be specified on all platforms: - \table + \table 80% \header \li Key \li Description \row diff --git a/src/network/bearer/qnetworksession.h b/src/network/bearer/qnetworksession.h index 34d721f484fd4cb7052653629fe96e740c4bbad5..bee4be7eb66a3291200c190749f288d527f42c9d 100644 --- a/src/network/bearer/qnetworksession.h +++ b/src/network/bearer/qnetworksession.h @@ -80,7 +80,7 @@ public: Q_DECLARE_FLAGS(UsagePolicies, UsagePolicy) - explicit QNetworkSession(const QNetworkConfiguration &connConfig, QObject *parent = 0); + explicit QNetworkSession(const QNetworkConfiguration &connConfig, QObject *parent = Q_NULLPTR); virtual ~QNetworkSession(); bool isOpen() const; diff --git a/src/network/kernel/qdnslookup.h b/src/network/kernel/qdnslookup.h index 01ebbb6535d38c96323b5b6c1ebbb08662cd78c5..ae015a22b8b3311bbd808719af1b23e9cefed986 100644 --- a/src/network/kernel/qdnslookup.h +++ b/src/network/kernel/qdnslookup.h @@ -55,16 +55,18 @@ class Q_NETWORK_EXPORT QDnsDomainNameRecord public: QDnsDomainNameRecord(); QDnsDomainNameRecord(const QDnsDomainNameRecord &other); +#ifdef Q_COMPILER_RVALUE_REFS + QDnsDomainNameRecord &operator=(QDnsDomainNameRecord &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif + QDnsDomainNameRecord &operator=(const QDnsDomainNameRecord &other); ~QDnsDomainNameRecord(); - void swap(QDnsDomainNameRecord &other) { qSwap(d, other.d); } + void swap(QDnsDomainNameRecord &other) Q_DECL_NOTHROW { qSwap(d, other.d); } QString name() const; quint32 timeToLive() const; QString value() const; - QDnsDomainNameRecord &operator=(const QDnsDomainNameRecord &other); - private: QSharedDataPointer<QDnsDomainNameRecordPrivate> d; friend class QDnsLookupRunnable; @@ -77,16 +79,18 @@ class Q_NETWORK_EXPORT QDnsHostAddressRecord public: QDnsHostAddressRecord(); QDnsHostAddressRecord(const QDnsHostAddressRecord &other); +#ifdef Q_COMPILER_RVALUE_REFS + QDnsHostAddressRecord &operator=(QDnsHostAddressRecord &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif + QDnsHostAddressRecord &operator=(const QDnsHostAddressRecord &other); ~QDnsHostAddressRecord(); - void swap(QDnsHostAddressRecord &other) { qSwap(d, other.d); } + void swap(QDnsHostAddressRecord &other) Q_DECL_NOTHROW { qSwap(d, other.d); } QString name() const; quint32 timeToLive() const; QHostAddress value() const; - QDnsHostAddressRecord &operator=(const QDnsHostAddressRecord &other); - private: QSharedDataPointer<QDnsHostAddressRecordPrivate> d; friend class QDnsLookupRunnable; @@ -99,17 +103,19 @@ class Q_NETWORK_EXPORT QDnsMailExchangeRecord public: QDnsMailExchangeRecord(); QDnsMailExchangeRecord(const QDnsMailExchangeRecord &other); +#ifdef Q_COMPILER_RVALUE_REFS + QDnsMailExchangeRecord &operator=(QDnsMailExchangeRecord &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif + QDnsMailExchangeRecord &operator=(const QDnsMailExchangeRecord &other); ~QDnsMailExchangeRecord(); - void swap(QDnsMailExchangeRecord &other) { qSwap(d, other.d); } + void swap(QDnsMailExchangeRecord &other) Q_DECL_NOTHROW { qSwap(d, other.d); } QString exchange() const; QString name() const; quint16 preference() const; quint32 timeToLive() const; - QDnsMailExchangeRecord &operator=(const QDnsMailExchangeRecord &other); - private: QSharedDataPointer<QDnsMailExchangeRecordPrivate> d; friend class QDnsLookupRunnable; @@ -122,9 +128,13 @@ class Q_NETWORK_EXPORT QDnsServiceRecord public: QDnsServiceRecord(); QDnsServiceRecord(const QDnsServiceRecord &other); +#ifdef Q_COMPILER_RVALUE_REFS + QDnsServiceRecord &operator=(QDnsServiceRecord &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif + QDnsServiceRecord &operator=(const QDnsServiceRecord &other); ~QDnsServiceRecord(); - void swap(QDnsServiceRecord &other) { qSwap(d, other.d); } + void swap(QDnsServiceRecord &other) Q_DECL_NOTHROW { qSwap(d, other.d); } QString name() const; quint16 port() const; @@ -133,8 +143,6 @@ public: quint32 timeToLive() const; quint16 weight() const; - QDnsServiceRecord &operator=(const QDnsServiceRecord &other); - private: QSharedDataPointer<QDnsServiceRecordPrivate> d; friend class QDnsLookupRunnable; @@ -147,16 +155,18 @@ class Q_NETWORK_EXPORT QDnsTextRecord public: QDnsTextRecord(); QDnsTextRecord(const QDnsTextRecord &other); +#ifdef Q_COMPILER_RVALUE_REFS + QDnsTextRecord &operator=(QDnsTextRecord &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif + QDnsTextRecord &operator=(const QDnsTextRecord &other); ~QDnsTextRecord(); - void swap(QDnsTextRecord &other) { qSwap(d, other.d); } + void swap(QDnsTextRecord &other) Q_DECL_NOTHROW { qSwap(d, other.d); } QString name() const; quint32 timeToLive() const; QList<QByteArray> values() const; - QDnsTextRecord &operator=(const QDnsTextRecord &other); - private: QSharedDataPointer<QDnsTextRecordPrivate> d; friend class QDnsLookupRunnable; @@ -201,9 +211,9 @@ public: }; Q_ENUM(Type) - explicit QDnsLookup(QObject *parent = 0); - QDnsLookup(Type type, const QString &name, QObject *parent = 0); - QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent = 0); + explicit QDnsLookup(QObject *parent = Q_NULLPTR); + QDnsLookup(Type type, const QString &name, QObject *parent = Q_NULLPTR); + QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent = Q_NULLPTR); ~QDnsLookup(); Error error() const; diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h index 0c2229c3341f2a5beeba8454300b5ff266d7c810..8478240d286843f42a0cdb0fb188906887cbda88 100644 --- a/src/network/kernel/qhostaddress.h +++ b/src/network/kernel/qhostaddress.h @@ -84,9 +84,16 @@ public: QHostAddress(SpecialAddress address); ~QHostAddress(); +#ifdef Q_COMPILER_RVALUE_REFS + QHostAddress &operator=(QHostAddress &&other) Q_DECL_NOTHROW + { swap(other); return *this; } +#endif + QHostAddress &operator=(const QHostAddress &other); QHostAddress &operator=(const QString &address); + void swap(QHostAddress &other) Q_DECL_NOTHROW { d.swap(other.d); } + void setAddress(quint32 ip4Addr); void setAddress(quint8 *ip6Addr); // ### Qt 6: remove me void setAddress(const quint8 *ip6Addr); diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp index 8d891733acf95662204bac2627f33a397b5aa3df..2fbbf56e0fa0ad5ec5d7870938f32e68395884c5 100644 --- a/src/network/kernel/qnetworkinterface.cpp +++ b/src/network/kernel/qnetworkinterface.cpp @@ -108,6 +108,7 @@ QList<QSharedDataPointer<QNetworkInterfacePrivate> > QNetworkInterfaceManager::a { QList<QNetworkInterfacePrivate *> list = postProcess(scan()); QList<QSharedDataPointer<QNetworkInterfacePrivate> > result; + result.reserve(list.size()); foreach (QNetworkInterfacePrivate *ptr, list) result << QSharedDataPointer<QNetworkInterfacePrivate>(ptr); @@ -549,6 +550,7 @@ QList<QNetworkInterface> QNetworkInterface::allInterfaces() { QList<QSharedDataPointer<QNetworkInterfacePrivate> > privs = manager()->allInterfaces(); QList<QNetworkInterface> result; + result.reserve(privs.size()); foreach (const QSharedDataPointer<QNetworkInterfacePrivate> &p, privs) { QNetworkInterface item; item.d = p; diff --git a/src/network/kernel/qnetworkinterface.h b/src/network/kernel/qnetworkinterface.h index a4d93156fb92514f20c69af992e0974af2c10237..31d3b7b128a3686ce4fa3e08e527ad6acff57463 100644 --- a/src/network/kernel/qnetworkinterface.h +++ b/src/network/kernel/qnetworkinterface.h @@ -51,10 +51,13 @@ class Q_NETWORK_EXPORT QNetworkAddressEntry public: QNetworkAddressEntry(); QNetworkAddressEntry(const QNetworkAddressEntry &other); +#ifdef Q_COMPILER_RVALUE_REFS + QNetworkAddressEntry &operator=(QNetworkAddressEntry &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QNetworkAddressEntry &operator=(const QNetworkAddressEntry &other); ~QNetworkAddressEntry(); - void swap(QNetworkAddressEntry &other) { qSwap(d, other.d); } + void swap(QNetworkAddressEntry &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool operator==(const QNetworkAddressEntry &other) const; inline bool operator!=(const QNetworkAddressEntry &other) const @@ -93,10 +96,13 @@ public: QNetworkInterface(); QNetworkInterface(const QNetworkInterface &other); +#ifdef Q_COMPILER_RVALUE_REFS + QNetworkInterface &operator=(QNetworkInterface &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QNetworkInterface &operator=(const QNetworkInterface &other); ~QNetworkInterface(); - void swap(QNetworkInterface &other) { qSwap(d, other.d); } + void swap(QNetworkInterface &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool isValid() const; diff --git a/src/network/kernel/qnetworkproxy.h b/src/network/kernel/qnetworkproxy.h index 6b0f4a3937db264947dab0a980e75d2444a424ad..717c141d60c9a996544f9a8366b17fe28e53d4c6 100644 --- a/src/network/kernel/qnetworkproxy.h +++ b/src/network/kernel/qnetworkproxy.h @@ -63,7 +63,6 @@ public: QueryType queryType = TcpSocket); explicit QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag = QString(), QueryType queryType = TcpServer); - QNetworkProxyQuery(const QNetworkProxyQuery &other); #ifndef QT_NO_BEARERMANAGEMENT QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, const QUrl &requestUrl, QueryType queryType = UrlRequest); @@ -74,10 +73,14 @@ public: quint16 bindPort, const QString &protocolTag = QString(), QueryType queryType = TcpServer); #endif - ~QNetworkProxyQuery(); + QNetworkProxyQuery(const QNetworkProxyQuery &other); +#ifdef Q_COMPILER_RVALUE_REFS + QNetworkProxyQuery &operator=(QNetworkProxyQuery &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QNetworkProxyQuery &operator=(const QNetworkProxyQuery &other); + ~QNetworkProxyQuery(); - void swap(QNetworkProxyQuery &other) { qSwap(d, other.d); } + void swap(QNetworkProxyQuery &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool operator==(const QNetworkProxyQuery &other) const; inline bool operator!=(const QNetworkProxyQuery &other) const @@ -139,10 +142,13 @@ public: QNetworkProxy(ProxyType type, const QString &hostName = QString(), quint16 port = 0, const QString &user = QString(), const QString &password = QString()); QNetworkProxy(const QNetworkProxy &other); +#ifdef Q_COMPILER_RVALUE_REFS + QNetworkProxy &operator=(QNetworkProxy &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QNetworkProxy &operator=(const QNetworkProxy &other); ~QNetworkProxy(); - void swap(QNetworkProxy &other) { qSwap(d, other.d); } + void swap(QNetworkProxy &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool operator==(const QNetworkProxy &other) const; inline bool operator!=(const QNetworkProxy &other) const diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index d6a38224222c96f07b12998bba2c4f19e9ded1a1..35b541d739bcc00aa911c5c7e87d6f905f53f806 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -420,7 +420,7 @@ allowed to rebind, even if they pass ReuseAddressHint. This option provides more security than ShareAddress, but on certain operating systems, it requires you to run the server with administrator privileges. - On Unix and Mac OS X, not sharing is the default behavior for binding + On Unix and OS X, not sharing is the default behavior for binding an address and port, so this option is ignored. On Windows, this option uses the SO_EXCLUSIVEADDRUSE socket option. @@ -430,7 +430,7 @@ socket option. On Unix, this option is ignored. \value DefaultForPlatform The default option for the current platform. - On Unix and Mac OS X, this is equivalent to (DontShareAddress + On Unix and OS X, this is equivalent to (DontShareAddress + ReuseAddressHint), and on Windows, its equivalent to ShareAddress. */ diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h index f3d7f13f48af9f0b191ad13bddaa425170cc26e3..b433c7e97fe070499dadb99b507257b761d06904 100644 --- a/src/network/socket/qabstractsocket.h +++ b/src/network/socket/qabstractsocket.h @@ -213,7 +213,7 @@ protected: void setPeerAddress(const QHostAddress &address); void setPeerName(const QString &name); - QAbstractSocket(SocketType socketType, QAbstractSocketPrivate &dd, QObject *parent = 0); + QAbstractSocket(SocketType socketType, QAbstractSocketPrivate &dd, QObject *parent = Q_NULLPTR); private: Q_DECLARE_PRIVATE(QAbstractSocket) diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp index 585446670402615055fedc57613fa410bfa30189..0f49cb986e4c0c0be289991166f5589b88ff4c41 100644 --- a/src/network/socket/qlocalserver.cpp +++ b/src/network/socket/qlocalserver.cpp @@ -141,7 +141,7 @@ QLocalServer::~QLocalServer() and are created based on the umask. Setting the access flags will overide this and will restrict or permit access as specified. - Other Unix-based operating systems, such as Mac OS X, do not + Other Unix-based operating systems, such as OS X, do not honor file permissions for Unix domain sockets and by default have WorldAccess and these permission flags will have no effect. diff --git a/src/network/socket/qlocalserver.h b/src/network/socket/qlocalserver.h index a03cdb726dcceb9e21b1c807d9a4d0938decc573..24908db4aa14c334609ad0f8f9d304fc35bedf8a 100644 --- a/src/network/socket/qlocalserver.h +++ b/src/network/socket/qlocalserver.h @@ -64,7 +64,7 @@ public: }; Q_DECLARE_FLAGS(SocketOptions, SocketOption) - explicit QLocalServer(QObject *parent = 0); + explicit QLocalServer(QObject *parent = Q_NULLPTR); ~QLocalServer(); void close(); @@ -80,7 +80,7 @@ public: static bool removeServer(const QString &name); QAbstractSocket::SocketError serverError() const; void setMaxPendingConnections(int numConnections); - bool waitForNewConnection(int msec = 0, bool *timedOut = 0); + bool waitForNewConnection(int msec = 0, bool *timedOut = Q_NULLPTR); void setSocketOptions(SocketOptions options); SocketOptions socketOptions() const; diff --git a/src/network/socket/qlocalsocket.h b/src/network/socket/qlocalsocket.h index a4d84059122b45b9e79d5a99458f5b138de09bb4..4b39a7c562c2fd140c3a428e0ed88ba4d02e1275 100644 --- a/src/network/socket/qlocalsocket.h +++ b/src/network/socket/qlocalsocket.h @@ -73,7 +73,7 @@ public: ClosingState = QAbstractSocket::ClosingState }; - QLocalSocket(QObject *parent = 0); + QLocalSocket(QObject *parent = Q_NULLPTR); ~QLocalSocket(); void connectToServer(OpenMode openMode = ReadWrite); diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 5c615034fcc462134d165b702dbfec2e99c71d00..5e58ee38952cb69ae9a71848a559982a578cb929 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -285,11 +285,23 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port) return false; } d->socketState = QAbstractSocket::ConnectingState; - hr = d->connectOp->put_Completed(Callback<IAsyncActionCompletedHandler>( - d, &QNativeSocketEnginePrivate::handleConnectToHost).Get()); - Q_ASSERT_SUCCEEDED(hr); + hr = QWinRTFunctions::await(d->connectOp); + RETURN_FALSE_IF_FAILED("Connection could not be established"); + bool connectionErrors = false; + d->handleConnectionErrors(d->connectOp.Get(), &connectionErrors); + if (connectionErrors) + return false; + d->connectOp.Reset(); + + d->socketState = QAbstractSocket::ConnectedState; + emit connectionReady(); - return d->socketState == QAbstractSocket::ConnectedState; + // Delay the reader so that the SSL socket can upgrade + if (d->sslSocket) + connect(d->sslSocket, SIGNAL(encrypted()), SLOT(establishRead())); + else + establishRead(); + return true; } bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port) @@ -1104,47 +1116,34 @@ HRESULT QNativeSocketEnginePrivate::handleClientConnection(IStreamSocketListener return S_OK; } -HRESULT QNativeSocketEnginePrivate::handleConnectToHost(IAsyncAction *action, AsyncStatus) +void QNativeSocketEnginePrivate::handleConnectionErrors(IAsyncAction *connectAction, bool *errorsOccured) { - Q_Q(QNativeSocketEngine); - - HRESULT hr = action->GetResults(); - if (wasDeleted || !connectOp) // Protect against a late callback - return S_OK; - - connectOp.Reset(); + bool error = true; + HRESULT hr = connectAction->GetResults(); switch (hr) { case 0x8007274c: // A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString); socketState = QAbstractSocket::UnconnectedState; - return S_OK; + break; case 0x80072751: // A socket operation was attempted to an unreachable host. setError(QAbstractSocket::HostNotFoundError, HostUnreachableErrorString); socketState = QAbstractSocket::UnconnectedState; - return S_OK; + break; case 0x8007274d: // No connection could be made because the target machine actively refused it. setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString); socketState = QAbstractSocket::UnconnectedState; - return S_OK; + break; default: if (FAILED(hr)) { setError(QAbstractSocket::UnknownSocketError, UnknownSocketErrorString); socketState = QAbstractSocket::UnconnectedState; - return S_OK; + } else { + error = false; } break; } - - socketState = QAbstractSocket::ConnectedState; - emit q->connectionReady(); - - // Delay the reader so that the SSL socket can upgrade - if (sslSocket) - q->connect(sslSocket, SIGNAL(encrypted()), SLOT(establishRead())); - else - q->establishRead(); - - return S_OK; + if (errorsOccured) + *errorsOccured = error; } HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status) diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index 42920c96f26a3a56814b56f173a703de19f1375e..eb032bc977a5728e860b819ff234f6a8dcdc52d2 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -216,7 +216,7 @@ private: ABI::Windows::Networking::Sockets::IDatagramSocketMessageReceivedEventArgs *args); HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *tcpListener, ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args); - HRESULT handleConnectToHost(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus); + void handleConnectionErrors(ABI::Windows::Foundation::IAsyncAction *connectAction, bool *errorsOccured); HRESULT handleReadyRead(ABI::Windows::Foundation::IAsyncOperationWithProgress<ABI::Windows::Storage::Streams::IBuffer *, UINT32> *asyncInfo, ABI::Windows::Foundation::AsyncStatus); }; diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h index cd118afd6324c0e05959af44ca6a2b5a61c94808..a5a87fc7c15f51c7958b6c9811da0a63caf22550 100644 --- a/src/network/socket/qnet_unix_p.h +++ b/src/network/socket/qnet_unix_p.h @@ -77,15 +77,13 @@ static inline int qt_safe_socket(int domain, int type, int protocol, int flags = Q_ASSERT((flags & ~O_NONBLOCK) == 0); int fd; -#if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) +#ifdef QT_THREADSAFE_CLOEXEC int newtype = type | SOCK_CLOEXEC; if (flags & O_NONBLOCK) newtype |= SOCK_NONBLOCK; fd = ::socket(domain, newtype, protocol); - if (fd != -1 || errno != EINVAL) - return fd; -#endif - + return fd; +#else fd = ::socket(domain, type, protocol); if (fd == -1) return -1; @@ -97,6 +95,7 @@ static inline int qt_safe_socket(int domain, int type, int protocol, int flags = ::fcntl(fd, F_SETFL, ::fcntl(fd, F_GETFL) | O_NONBLOCK); return fd; +#endif } // Tru64 redefines accept -> _accept with _XOPEN_SOURCE_EXTENDED @@ -105,16 +104,14 @@ static inline int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *add Q_ASSERT((flags & ~O_NONBLOCK) == 0); int fd; -#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) +#ifdef QT_THREADSAFE_CLOEXEC // use accept4 int sockflags = SOCK_CLOEXEC; if (flags & O_NONBLOCK) sockflags |= SOCK_NONBLOCK; fd = ::accept4(s, addr, static_cast<QT_SOCKLEN_T *>(addrlen), sockflags); - if (fd != -1 || !(errno == ENOSYS || errno == EINVAL)) - return fd; -#endif - + return fd; +#else fd = ::accept(s, addr, static_cast<QT_SOCKLEN_T *>(addrlen)); if (fd == -1) return -1; @@ -126,6 +123,7 @@ static inline int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *add ::fcntl(fd, F_SETFL, ::fcntl(fd, F_GETFL) | O_NONBLOCK); return fd; +#endif } // UnixWare 7 redefines listen -> _listen diff --git a/src/network/socket/qtcpserver.h b/src/network/socket/qtcpserver.h index 8c7537a9b10925d159935f4d6c33b4c1d574d303..dd7b12c96a59af9d7278b84af3542f0208d526d7 100644 --- a/src/network/socket/qtcpserver.h +++ b/src/network/socket/qtcpserver.h @@ -51,7 +51,7 @@ class Q_NETWORK_EXPORT QTcpServer : public QObject { Q_OBJECT public: - explicit QTcpServer(QObject *parent = 0); + explicit QTcpServer(QObject *parent = Q_NULLPTR); virtual ~QTcpServer(); bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0); @@ -68,7 +68,7 @@ public: qintptr socketDescriptor() const; bool setSocketDescriptor(qintptr socketDescriptor); - bool waitForNewConnection(int msec = 0, bool *timedOut = 0); + bool waitForNewConnection(int msec = 0, bool *timedOut = Q_NULLPTR); virtual bool hasPendingConnections() const; virtual QTcpSocket *nextPendingConnection(); @@ -87,7 +87,7 @@ protected: virtual void incomingConnection(qintptr handle); void addPendingConnection(QTcpSocket* socket); - QTcpServer(QTcpServerPrivate &dd, QObject *parent = 0); + QTcpServer(QTcpServerPrivate &dd, QObject *parent = Q_NULLPTR); Q_SIGNALS: void newConnection(); diff --git a/src/network/socket/qtcpsocket.h b/src/network/socket/qtcpsocket.h index bf5370c976215cf6e0f03edeed7f8dbbe9202473..8e3cb5946f20ab6c05a3c7b22e97c44d9b588a79 100644 --- a/src/network/socket/qtcpsocket.h +++ b/src/network/socket/qtcpsocket.h @@ -46,13 +46,13 @@ class Q_NETWORK_EXPORT QTcpSocket : public QAbstractSocket { Q_OBJECT public: - explicit QTcpSocket(QObject *parent = 0); + explicit QTcpSocket(QObject *parent = Q_NULLPTR); virtual ~QTcpSocket(); protected: - QTcpSocket(QTcpSocketPrivate &dd, QObject *parent = 0); + QTcpSocket(QTcpSocketPrivate &dd, QObject *parent = Q_NULLPTR); QTcpSocket(QAbstractSocket::SocketType socketType, QTcpSocketPrivate &dd, - QObject *parent = 0); + QObject *parent = Q_NULLPTR); private: Q_DISABLE_COPY(QTcpSocket) diff --git a/src/network/socket/qudpsocket.h b/src/network/socket/qudpsocket.h index fcf16fb345c23fcacd9a176ad8ddcfcd509d80bb..e902984b4f02fa2ff929f8a1722fd1f66aae3e48 100644 --- a/src/network/socket/qudpsocket.h +++ b/src/network/socket/qudpsocket.h @@ -49,7 +49,7 @@ class Q_NETWORK_EXPORT QUdpSocket : public QAbstractSocket { Q_OBJECT public: - explicit QUdpSocket(QObject *parent = 0); + explicit QUdpSocket(QObject *parent = Q_NULLPTR); virtual ~QUdpSocket(); #ifndef QT_NO_NETWORKINTERFACE @@ -66,7 +66,7 @@ public: bool hasPendingDatagrams() const; qint64 pendingDatagramSize() const; - qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *host = 0, quint16 *port = 0); + qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *host = Q_NULLPTR, quint16 *port = Q_NULLPTR); qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port); inline qint64 writeDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port) { return writeDatagram(datagram.constData(), datagram.size(), host, port); } diff --git a/src/network/socket/socket.pri b/src/network/socket/socket.pri index 2f00224e40741ec9ceb72a9a3f908783ad71b5ca..cf1e18fc0d26890dea17ca3cac20697c1df15348 100644 --- a/src/network/socket/socket.pri +++ b/src/network/socket/socket.pri @@ -43,7 +43,7 @@ win32:!winrt:SOURCES += socket/qnativesocketengine_win.cpp \ socket/qlocalsocket_win.cpp \ socket/qlocalserver_win.cpp -win32:!wince*:!winrt:LIBS_PRIVATE += -ladvapi32 +win32:!wince:!winrt:LIBS_PRIVATE += -ladvapi32 winrt { SOURCES += socket/qnativesocketengine_winrt.cpp \ @@ -54,7 +54,7 @@ winrt { DEFINES += QT_LOCALSOCKET_TCP } -wince*: { +wince { SOURCES -= socket/qlocalsocket_win.cpp \ socket/qlocalserver_win.cpp SOURCES += socket/qlocalsocket_tcp.cpp \ diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h index ef0767ae8f9b27b83f211eb1bb97f2024b787192..af605b062938a5cd1d0535f21a7cf830f96df1a5 100644 --- a/src/network/ssl/qsslcertificate.h +++ b/src/network/ssl/qsslcertificate.h @@ -83,9 +83,12 @@ public: explicit QSslCertificate(const QByteArray &data = QByteArray(), QSsl::EncodingFormat format = QSsl::Pem); QSslCertificate(const QSslCertificate &other); ~QSslCertificate(); +#ifdef Q_COMPILER_RVALUE_REFS + QSslCertificate &operator=(QSslCertificate &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QSslCertificate &operator=(const QSslCertificate &other); - inline void swap(QSslCertificate &other) + void swap(QSslCertificate &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool operator==(const QSslCertificate &other) const; @@ -144,7 +147,7 @@ public: static bool importPkcs12(QIODevice *device, QSslKey *key, QSslCertificate *cert, - QList<QSslCertificate> *caCertificates=0, + QList<QSslCertificate> *caCertificates = Q_NULLPTR, const QByteArray &passPhrase=QByteArray()); Qt::HANDLE handle() const; diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp index ad88ea5d56ea7dc7ef343c9a7454a43e9f0cb6d1..33245878214724caa0c80e3b2445984c4168c76c 100644 --- a/src/network/ssl/qsslcertificate_openssl.cpp +++ b/src/network/ssl/qsslcertificate_openssl.cpp @@ -464,8 +464,9 @@ QList<QSslCertificateExtension> QSslCertificate::extensions() const return result; int count = q_X509_get_ext_count(d->x509); + result.reserve(count); - for (int i=0; i < count; i++) { + for (int i = 0; i < count; i++) { X509_EXTENSION *ext = q_X509_get_ext(d->x509, i); result << QSslCertificatePrivate::convertExtension(ext); } diff --git a/src/network/ssl/qsslcertificateextension.h b/src/network/ssl/qsslcertificateextension.h index 7c958eff307974149e5daeb8ccd65d0780a575e7..8dd0e8eb4b5356fc820b23e432759e206a70fefe 100644 --- a/src/network/ssl/qsslcertificateextension.h +++ b/src/network/ssl/qsslcertificateextension.h @@ -51,11 +51,13 @@ class Q_NETWORK_EXPORT QSslCertificateExtension public: QSslCertificateExtension(); QSslCertificateExtension(const QSslCertificateExtension &other); - ~QSslCertificateExtension(); - +#ifdef Q_COMPILER_RVALUE_REFS + QSslCertificateExtension &operator=(QSslCertificateExtension &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QSslCertificateExtension &operator=(const QSslCertificateExtension &other); + ~QSslCertificateExtension(); - void swap(QSslCertificateExtension &other) { qSwap(d, other.d); } + void swap(QSslCertificateExtension &other) Q_DECL_NOTHROW { qSwap(d, other.d); } QString oid() const; QString name() const; diff --git a/src/network/ssl/qsslcipher.cpp b/src/network/ssl/qsslcipher.cpp index 8f2b8b54ad4c24a7054a624cef74e16b0a02c606..c480b79371aad934b07b1f2474e49b51ecb8c145 100644 --- a/src/network/ssl/qsslcipher.cpp +++ b/src/network/ssl/qsslcipher.cpp @@ -54,6 +54,7 @@ #include "qsslcipher.h" #include "qsslcipher_p.h" #include "qsslsocket.h" +#include "qsslconfiguration.h" #ifndef QT_NO_DEBUG_STREAM #include <QtCore/qdebug.h> @@ -81,7 +82,7 @@ QSslCipher::QSslCipher() QSslCipher::QSslCipher(const QString &name) : d(new QSslCipherPrivate) { - foreach (const QSslCipher &cipher, QSslSocket::supportedCiphers()) { + foreach (const QSslCipher &cipher, QSslConfiguration::supportedCiphers()) { if (cipher.name() == name) { *this = cipher; return; @@ -102,7 +103,7 @@ QSslCipher::QSslCipher(const QString &name) QSslCipher::QSslCipher(const QString &name, QSsl::SslProtocol protocol) : d(new QSslCipherPrivate) { - foreach (const QSslCipher &cipher, QSslSocket::supportedCiphers()) { + foreach (const QSslCipher &cipher, QSslConfiguration::supportedCiphers()) { if (cipher.name() == name && cipher.protocol() == protocol) { *this = cipher; return; diff --git a/src/network/ssl/qsslcipher.h b/src/network/ssl/qsslcipher.h index dc65e32111b92ede44e47bf130f1a553fd03d52a..64122cdd534991dd53e343430b583d0cec5b8742 100644 --- a/src/network/ssl/qsslcipher.h +++ b/src/network/ssl/qsslcipher.h @@ -52,10 +52,13 @@ public: explicit QSslCipher(const QString &name); QSslCipher(const QString &name, QSsl::SslProtocol protocol); QSslCipher(const QSslCipher &other); - ~QSslCipher(); +#ifdef Q_COMPILER_RVALUE_REFS + QSslCipher &operator=(QSslCipher &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QSslCipher &operator=(const QSslCipher &other); + ~QSslCipher(); - inline void swap(QSslCipher &other) + void swap(QSslCipher &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool operator==(const QSslCipher &other) const; diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp index 5c95c9f5440d47afa5bed74dd1158b1bc85f7ec8..4803e472243caec80f6ead6c04623dd027dbe52c 100644 --- a/src/network/ssl/qsslconfiguration.cpp +++ b/src/network/ssl/qsslconfiguration.cpp @@ -36,6 +36,7 @@ #include "qsslconfiguration.h" #include "qsslconfiguration_p.h" #include "qsslsocket.h" +#include "qsslsocket_p.h" #include "qmutex.h" #include "qdebug.h" @@ -589,6 +590,20 @@ void QSslConfiguration::setCiphers(const QList<QSslCipher> &ciphers) d->ciphers = ciphers; } +/*! + \since 5.5 + + Returns the list of cryptographic ciphers supported by this + system. This list is set by the system's SSL libraries and may + vary from system to system. + + \sa ciphers(), setCiphers() +*/ +QList<QSslCipher> QSslConfiguration::supportedCiphers() +{ + return QSslSocketPrivate::supportedCiphers(); +} + /*! Returns this connection's CA certificate database. The CA certificate database is used by the socket during the handshake phase to @@ -618,6 +633,22 @@ void QSslConfiguration::setCaCertificates(const QList<QSslCertificate> &certific d->allowRootCertOnDemandLoading = false; } +/*! + \since 5.5 + + This function provides the CA certificate database + provided by the operating system. The CA certificate database + returned by this function is used to initialize the database + returned by caCertificates() on the default QSslConfiguration. + + \sa caCertificates(), setCaCertificates(), defaultConfiguration() +*/ +QList<QSslCertificate> QSslConfiguration::systemCaCertificates() +{ + // we are calling ensureInitialized() in the method below + return QSslSocketPrivate::systemCaCertificates(); +} + /*! Enables or disables an SSL compatibility \a option. If \a on is true, the \a option is enabled. If \a on is false, the @@ -743,6 +774,20 @@ void QSslConfiguration::setEllipticCurves(const QVector<QSslEllipticCurve> &curv d->ellipticCurves = curves; } +/*! + \since 5.5 + + Returns the list of elliptic curves supported by this + system. This list is set by the system's SSL libraries and may + vary from system to system. + + \sa ellipticCurves(), setEllipticCurves() +*/ +QVector<QSslEllipticCurve> QSslConfiguration::supportedEllipticCurves() +{ + return QSslSocketPrivate::supportedEllipticCurves(); +} + /*! \since 5.3 diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h index c5a1c6e6d43337a36fc6b8b58d6535fd40035529..2cbc31b03265974dbe69fe0fce38551d7533533b 100644 --- a/src/network/ssl/qsslconfiguration.h +++ b/src/network/ssl/qsslconfiguration.h @@ -71,9 +71,12 @@ public: QSslConfiguration(); QSslConfiguration(const QSslConfiguration &other); ~QSslConfiguration(); +#ifdef Q_COMPILER_RVALUE_REFS + QSslConfiguration &operator=(QSslConfiguration &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QSslConfiguration &operator=(const QSslConfiguration &other); - inline void swap(QSslConfiguration &other) + void swap(QSslConfiguration &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool operator==(const QSslConfiguration &other) const; @@ -111,10 +114,12 @@ public: // Cipher settings QList<QSslCipher> ciphers() const; void setCiphers(const QList<QSslCipher> &ciphers); + static QList<QSslCipher> supportedCiphers(); // Certificate Authority (CA) settings QList<QSslCertificate> caCertificates() const; void setCaCertificates(const QList<QSslCertificate> &certificates); + static QList<QSslCertificate> systemCaCertificates(); void setSslOption(QSsl::SslOption option, bool on); bool testSslOption(QSsl::SslOption option) const; @@ -126,6 +131,7 @@ public: // EC settings QVector<QSslEllipticCurve> ellipticCurves() const; void setEllipticCurves(const QVector<QSslEllipticCurve> &curves); + static QVector<QSslEllipticCurve> supportedEllipticCurves(); static QSslConfiguration defaultConfiguration(); static void setDefaultConfiguration(const QSslConfiguration &configuration); diff --git a/src/network/ssl/qsslellipticcurve.h b/src/network/ssl/qsslellipticcurve.h index a4dc4517ffcf70bb2fb07143845f4ea8aa7bcf21..5716e3447d1777f2dedeb2e91d9df1853f97a22e 100644 --- a/src/network/ssl/qsslellipticcurve.h +++ b/src/network/ssl/qsslellipticcurve.h @@ -71,10 +71,8 @@ public: private: int id; - friend Q_DECL_CONSTEXPR bool operator==(QSslEllipticCurve lhs, QSslEllipticCurve rhs) Q_DECL_NOTHROW - { return lhs.id == rhs.id; } - friend Q_DECL_CONSTEXPR uint qHash(QSslEllipticCurve curve, uint seed) Q_DECL_NOTHROW - { return qHash(curve.id, seed); } + friend Q_DECL_CONSTEXPR bool operator==(QSslEllipticCurve lhs, QSslEllipticCurve rhs) Q_DECL_NOTHROW; + friend Q_DECL_CONSTEXPR uint qHash(QSslEllipticCurve curve, uint seed) Q_DECL_NOTHROW; friend class QSslSocketPrivate; friend class QSslSocketBackendPrivate; @@ -82,6 +80,12 @@ private: Q_DECLARE_TYPEINFO(QSslEllipticCurve, Q_PRIMITIVE_TYPE); +Q_DECL_CONSTEXPR inline uint qHash(QSslEllipticCurve curve, uint seed) Q_DECL_NOTHROW +{ return qHash(curve.id, seed); } + +Q_DECL_CONSTEXPR inline bool operator==(QSslEllipticCurve lhs, QSslEllipticCurve rhs) Q_DECL_NOTHROW +{ return lhs.id == rhs.id; } + Q_DECL_CONSTEXPR inline bool operator!=(QSslEllipticCurve lhs, QSslEllipticCurve rhs) Q_DECL_NOTHROW { return !operator==(lhs, rhs); } diff --git a/src/network/ssl/qsslerror.h b/src/network/ssl/qsslerror.h index b149f86d9ef8b3453a69862dc9a584550528207f..bc2a2d5220269e6cf59f89152d2b0bd3e9cda397 100644 --- a/src/network/ssl/qsslerror.h +++ b/src/network/ssl/qsslerror.h @@ -84,10 +84,13 @@ public: QSslError(const QSslError &other); - inline void swap(QSslError &other) + void swap(QSslError &other) Q_DECL_NOTHROW { qSwap(d, other.d); } ~QSslError(); +#ifdef Q_COMPILER_RVALUE_REFS + QSslError &operator=(QSslError &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QSslError &operator=(const QSslError &other); bool operator==(const QSslError &other) const; inline bool operator!=(const QSslError &other) const diff --git a/src/network/ssl/qsslkey.h b/src/network/ssl/qsslkey.h index b89069e4cb1eccd05cca400a7df42e4d7b4aec43..d02c03101555d03a421ac9a52b759f5a589b9260 100644 --- a/src/network/ssl/qsslkey.h +++ b/src/network/ssl/qsslkey.h @@ -64,10 +64,13 @@ public: const QByteArray &passPhrase = QByteArray()); explicit QSslKey(Qt::HANDLE handle, QSsl::KeyType type = QSsl::PrivateKey); QSslKey(const QSslKey &other); - ~QSslKey(); +#ifdef Q_COMPILER_RVALUE_REFS + QSslKey &operator=(QSslKey &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif QSslKey &operator=(const QSslKey &other); + ~QSslKey(); - inline void swap(QSslKey &other) { qSwap(d, other.d); } + void swap(QSslKey &other) Q_DECL_NOTHROW { qSwap(d, other.d); } bool isNull() const; void clear(); diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp index 33cb81ce714e2fe3f64b7a312653265732d84361..a90c9411b73259672f98a8a5f0775815d0fc140e 100644 --- a/src/network/ssl/qsslkey_openssl.cpp +++ b/src/network/ssl/qsslkey_openssl.cpp @@ -265,4 +265,53 @@ Qt::HANDLE QSslKeyPrivate::handle() const } } +static QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv, int enc) +{ + EVP_CIPHER_CTX ctx; + const EVP_CIPHER* type = 0; + int i = 0, len = 0; + + switch (cipher) { + case QSslKeyPrivate::DesCbc: + type = q_EVP_des_cbc(); + break; + case QSslKeyPrivate::DesEde3Cbc: + type = q_EVP_des_ede3_cbc(); + break; + case QSslKeyPrivate::Rc2Cbc: + type = q_EVP_rc2_cbc(); + break; + } + + QByteArray output; + output.resize(data.size() + EVP_MAX_BLOCK_LENGTH); + q_EVP_CIPHER_CTX_init(&ctx); + q_EVP_CipherInit(&ctx, type, NULL, NULL, enc); + q_EVP_CIPHER_CTX_set_key_length(&ctx, key.size()); + if (cipher == QSslKeyPrivate::Rc2Cbc) + q_EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_SET_RC2_KEY_BITS, 8 * key.size(), NULL); + q_EVP_CipherInit(&ctx, NULL, + reinterpret_cast<const unsigned char *>(key.constData()), + reinterpret_cast<const unsigned char *>(iv.constData()), enc); + q_EVP_CipherUpdate(&ctx, + reinterpret_cast<unsigned char *>(output.data()), &len, + reinterpret_cast<const unsigned char *>(data.constData()), data.size()); + q_EVP_CipherFinal(&ctx, + reinterpret_cast<unsigned char *>(output.data()) + len, &i); + len += i; + q_EVP_CIPHER_CTX_cleanup(&ctx); + + return output.left(len); +} + +QByteArray QSslKeyPrivate::decrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv) +{ + return doCrypt(cipher, data, key, iv, 0); +} + +QByteArray QSslKeyPrivate::encrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv) +{ + return doCrypt(cipher, data, key, iv, 1); +} + QT_END_NAMESPACE diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h index be981bb484b448c8c22f7e6c28962854433e6539..fea0e30bbc1421fa56faa83015d59afae16064fb 100644 --- a/src/network/ssl/qsslkey_p.h +++ b/src/network/ssl/qsslkey_p.h @@ -90,6 +90,16 @@ public: bool isNull; QSsl::KeyType type; QSsl::KeyAlgorithm algorithm; + + enum Cipher { + DesCbc, + DesEde3Cbc, + Rc2Cbc + }; + + Q_AUTOTEST_EXPORT static QByteArray decrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv); + Q_AUTOTEST_EXPORT static QByteArray encrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv); + #ifndef QT_NO_OPENSSL union { EVP_PKEY *opaque; @@ -100,15 +110,6 @@ public: #endif }; #else - enum Cipher { - DesCbc, - DesEde3Cbc, - Rc2Cbc - }; - - Q_AUTOTEST_EXPORT static QByteArray decrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv); - Q_AUTOTEST_EXPORT static QByteArray encrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv); - Qt::HANDLE opaque; QByteArray derData; int keyLength; diff --git a/src/network/ssl/qsslpresharedkeyauthenticator.h b/src/network/ssl/qsslpresharedkeyauthenticator.h index 52301ef7e57f6b0cd38a91eb0e6b2cc7f76d3078..34e5d6fd50ea0d17f5f32dbeb57def81fb5f6e19 100644 --- a/src/network/ssl/qsslpresharedkeyauthenticator.h +++ b/src/network/ssl/qsslpresharedkeyauthenticator.h @@ -43,33 +43,29 @@ QT_BEGIN_NAMESPACE class QSslPreSharedKeyAuthenticatorPrivate; -class Q_NETWORK_EXPORT QSslPreSharedKeyAuthenticator +class QSslPreSharedKeyAuthenticator { public: - QSslPreSharedKeyAuthenticator(); - ~QSslPreSharedKeyAuthenticator(); - QSslPreSharedKeyAuthenticator(const QSslPreSharedKeyAuthenticator &authenticator); - QSslPreSharedKeyAuthenticator &operator=(const QSslPreSharedKeyAuthenticator &authenticator); + Q_NETWORK_EXPORT QSslPreSharedKeyAuthenticator(); + Q_NETWORK_EXPORT ~QSslPreSharedKeyAuthenticator(); + Q_NETWORK_EXPORT QSslPreSharedKeyAuthenticator(const QSslPreSharedKeyAuthenticator &authenticator); + Q_NETWORK_EXPORT QSslPreSharedKeyAuthenticator &operator=(const QSslPreSharedKeyAuthenticator &authenticator); #ifdef Q_COMPILER_RVALUE_REFS - inline QSslPreSharedKeyAuthenticator &operator=(QSslPreSharedKeyAuthenticator &&authenticator) - { d.swap(authenticator.d); return *this; } + QSslPreSharedKeyAuthenticator &operator=(QSslPreSharedKeyAuthenticator &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif - void swap(QSslPreSharedKeyAuthenticator &authenticator) - { - d.swap(authenticator.d); - } + void swap(QSslPreSharedKeyAuthenticator &other) Q_DECL_NOTHROW { qSwap(d, other.d); } - QByteArray identityHint() const; + Q_NETWORK_EXPORT QByteArray identityHint() const; - void setIdentity(const QByteArray &identity); - QByteArray identity() const; - int maximumIdentityLength() const; + Q_NETWORK_EXPORT void setIdentity(const QByteArray &identity); + Q_NETWORK_EXPORT QByteArray identity() const; + Q_NETWORK_EXPORT int maximumIdentityLength() const; - void setPreSharedKey(const QByteArray &preSharedKey); - QByteArray preSharedKey() const; - int maximumPreSharedKeyLength() const; + Q_NETWORK_EXPORT void setPreSharedKey(const QByteArray &preSharedKey); + Q_NETWORK_EXPORT QByteArray preSharedKey() const; + Q_NETWORK_EXPORT int maximumPreSharedKeyLength() const; private: friend Q_NETWORK_EXPORT bool operator==(const QSslPreSharedKeyAuthenticator &lhs, const QSslPreSharedKeyAuthenticator &rhs); diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 513cc51620b6ec28f299f3424744be5320f3851a..b9b49ac26ea506299a284adb306912d4d427b11b 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -136,7 +136,7 @@ setDefaultCaCertificates(). \endlist - \note If available, root certificates on Unix (excluding Mac OS X) will be + \note If available, root certificates on Unix (excluding OS X) will be loaded on demand from the standard certificate directories. If you do not want to load root certificates on demand, you need to call either the static function setDefaultCaCertificates() before the first SSL handshake @@ -1166,6 +1166,10 @@ QSslKey QSslSocket::privateKey() const } /*! + \deprecated + + Use QSslConfiguration::ciphers() instead. + Returns this socket's current cryptographic cipher suite. This list is used during the socket's handshake phase for choosing a session cipher. The returned list of ciphers is ordered by @@ -1197,6 +1201,10 @@ QList<QSslCipher> QSslSocket::ciphers() const } /*! + \deprecated + + USe QSslConfiguration::setCiphers() instead. + Sets the cryptographic cipher suite for this socket to \a ciphers, which must contain a subset of the ciphers in the list returned by supportedCiphers(). @@ -1213,6 +1221,10 @@ void QSslSocket::setCiphers(const QList<QSslCipher> &ciphers) } /*! + \deprecated + + Use QSslConfiguration::setCiphers() instead. + Sets the cryptographic cipher suite for this socket to \a ciphers, which is a colon-separated list of cipher suite names. The ciphers are listed in order of preference, starting with the most preferred cipher. For example: @@ -1238,6 +1250,10 @@ void QSslSocket::setCiphers(const QString &ciphers) } /*! + \deprecated + + Use QSslConfiguration::setCiphers() on the default QSslConfiguration instead. + Sets the default cryptographic cipher suite for all sockets in this application to \a ciphers, which must contain a subset of the ciphers in the list returned by supportedCiphers(). @@ -1254,6 +1270,10 @@ void QSslSocket::setDefaultCiphers(const QList<QSslCipher> &ciphers) } /*! + \deprecated + + Use QSslConfiguration::ciphers() on the default QSslConfiguration instead. + Returns the default cryptographic cipher suite for all sockets in this application. This list is used during the socket's handshake phase when negotiating with the peer to choose a session cipher. @@ -1273,6 +1293,10 @@ QList<QSslCipher> QSslSocket::defaultCiphers() } /*! + \deprecated + + Use QSslConfiguration::supportedCiphers() instead. + Returns the list of cryptographic ciphers supported by this system. This list is set by the system's SSL libraries and may vary from system to system. @@ -1284,120 +1308,6 @@ QList<QSslCipher> QSslSocket::supportedCiphers() return QSslSocketPrivate::supportedCiphers(); } -/*! - \since 5.5 - - Returns this socket's current list of elliptic curves. This - list is used during the socket's handshake phase for choosing an - elliptic curve (when using an elliptic curve cipher). - The returned list of curves is ordered by descending preference - (i.e., the first curve in the list is the most preferred one). - - By default, this list is empty. An empty default list means that the - handshake phase can choose any of the curves supported by this system's SSL - libraries (which may vary from system to system). The list of curves - supported by this system's SSL libraries is returned by - supportedEllipticCurves(). - - You can restrict the list of curves used for choosing the session cipher - for this socket by calling setEllipticCurves() with a subset of the - supported ciphers. You can revert to using the entire set by calling - setEllipticCurves() with the list returned by supportedEllipticCurves(). - - \sa setEllipticCurves(), defaultEllipticCurves(), setDefaultEllipticCurves(), supportedEllipticCurves() -*/ -QVector<QSslEllipticCurve> QSslSocket::ellipticCurves() const -{ - Q_D(const QSslSocket); - return d->configuration.ellipticCurves; -} - -/*! - \since 5.5 - - Sets the list of elliptic curves to be used by this socket to \a curves, - which must contain a subset of the curves in the list returned by - supportedEllipticCurves(). - - Restricting the elliptic curves must be done before the handshake - phase, where the session cipher is chosen. - - If an empty list is set, then the handshake phase can choose any of the - curves supported by this system's SSL libraries (which may vary from system - to system). The list of curves supported by this system's SSL libraries is - returned by supportedEllipticCurves(). - - Use setCipher() in order to disable the usage of elliptic curve ciphers. - - \sa ellipticCurves(), setDefaultEllipticCurves(), supportedEllipticCurves() -*/ -void QSslSocket::setEllipticCurves(const QVector<QSslEllipticCurve> &curves) -{ - Q_D(QSslSocket); - d->configuration.ellipticCurves = curves; -} - -/*! - \since 5.5 - - Sets the list of elliptic curves to be used by all sockets in this - application to \a curves, which must contain a subset of the curves in the - list returned by supportedEllipticCurves(). - - Restricting the default elliptic curves only affects SSL sockets - that perform their handshake phase after the default list has been changed. - - If an empty list is set, then the handshake phase can choose any of the - curves supported by this system's SSL libraries (which may vary from system - to system). The list of curves supported by this system's SSL libraries is - returned by supportedEllipticCurves(). - - Use setDefaultCiphers() in order to disable the usage of elliptic curve ciphers. - - \sa setEllipticCurves(), defaultEllipticCurves(), supportedEllipticCurves() -*/ -void QSslSocket::setDefaultEllipticCurves(const QVector<QSslEllipticCurve> &curves) -{ - QSslSocketPrivate::setDefaultEllipticCurves(curves); -} - - -/*! - \since 5.5 - - Returns the default elliptic curves list for all sockets in - this application. This list is used during the socket's handshake - phase when negotiating with the peer to choose a session cipher. - The list is ordered by preference (i.e., the first curve in the - list is the most preferred one). - - By default, this list is empty. An empty default list means that the - handshake phase can choose any of the curves supported by this system's SSL - libraries (which may vary from system to system). The list of curves - supported by this system's SSL libraries is returned by - supportedEllipticCurves(). - - \sa setDefaultEllipticCurves(), supportedEllipticCurves() -*/ -QVector<QSslEllipticCurve> QSslSocket::defaultEllipticCurves() -{ - return QSslSocketPrivate::defaultEllipticCurves(); -} - -/*! - \since 5.5 - - Returns the list of elliptic curves supported by this - system. This list is set by the system's SSL libraries and may - vary from system to system. - - \sa ellipticCurves(), setEllipticCurves(), defaultEllipticCurves() -*/ -QVector<QSslEllipticCurve> QSslSocket::supportedEllipticCurves() -{ - return QSslSocketPrivate::supportedEllipticCurves(); -} - /*! Searches all files in the \a path for certificates encoded in the specified \a format and adds them to this socket's CA certificate @@ -1456,6 +1366,10 @@ void QSslSocket::addCaCertificates(const QList<QSslCertificate> &certificates) } /*! + \deprecated + + Use QSslConfiguration::setCaCertificates() instead. + Sets this socket's CA certificate database to be \a certificates. The certificate database must be set prior to the SSL handshake. The CA certificate database is used by the socket during the @@ -1475,6 +1389,10 @@ void QSslSocket::setCaCertificates(const QList<QSslCertificate> &certificates) } /*! + \deprecated + + Use QSslConfiguration::caCertificates() instead. + Returns this socket's CA certificate database. The CA certificate database is used by the socket during the handshake phase to validate the peer's certificate. It can be moodified prior to the @@ -1535,6 +1453,10 @@ void QSslSocket::addDefaultCaCertificates(const QList<QSslCertificate> &certific } /*! + \deprecated + + Use QSslConfiguration::setCaCertificates() on the default QSslConfiguration instead. + Sets the default CA certificate database to \a certificates. The default CA certificate database is originally set to your system's default CA certificate database. You can override the default CA @@ -1552,6 +1474,10 @@ void QSslSocket::setDefaultCaCertificates(const QList<QSslCertificate> &certific } /*! + \deprecated + + Use QSslConfiguration::caCertificates() on the default QSslConfiguration instead. + Returns the current default CA certificate database. This database is originally set to your system's default CA certificate database. If no system default database is found, an empty database will be @@ -1572,6 +1498,10 @@ QList<QSslCertificate> QSslSocket::defaultCaCertificates() } /*! + \deprecated + + Use QSslConfiguration::systemDefaultCaCertificates instead. + This function provides the CA certificate database provided by the operating system. The CA certificate database returned by this function is used to initialize the database @@ -2163,16 +2093,6 @@ void QSslSocketPrivate::setDefaultSupportedCiphers(const QList<QSslCipher> &ciph globalData()->supportedCiphers = ciphers; } -/*! - \internal -*/ -QVector<QSslEllipticCurve> QSslSocketPrivate::defaultEllipticCurves() -{ - QSslSocketPrivate::ensureInitialized(); - const QMutexLocker locker(&globalData()->mutex); - return globalData()->config->ellipticCurves; -} - /*! \internal */ @@ -2183,16 +2103,6 @@ QVector<QSslEllipticCurve> QSslSocketPrivate::supportedEllipticCurves() return globalData()->supportedEllipticCurves; } -/*! - \internal -*/ -void QSslSocketPrivate::setDefaultEllipticCurves(const QVector<QSslEllipticCurve> &curves) -{ - const QMutexLocker locker(&globalData()->mutex); - globalData()->config.detach(); - globalData()->config->ellipticCurves = curves; -} - /*! \internal */ diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h index 8ad6d033a72caca2dfef8c124e24a86ffc3ce691..22856c6ea9fac4655b1b5be69a7924fb35208ee4 100644 --- a/src/network/ssl/qsslsocket.h +++ b/src/network/ssl/qsslsocket.h @@ -72,7 +72,7 @@ public: AutoVerifyPeer }; - explicit QSslSocket(QObject *parent = 0); + explicit QSslSocket(QObject *parent = Q_NULLPTR); ~QSslSocket(); void resume() Q_DECL_OVERRIDE; // to continue after proxy authentication required, SSL errors etc. @@ -144,34 +144,33 @@ public: QSslKey privateKey() const; // Cipher settings. - QList<QSslCipher> ciphers() const; - void setCiphers(const QList<QSslCipher> &ciphers); - void setCiphers(const QString &ciphers); - static void setDefaultCiphers(const QList<QSslCipher> &ciphers); - static QList<QSslCipher> defaultCiphers(); - static QList<QSslCipher> supportedCiphers(); - - // EC settings. - QVector<QSslEllipticCurve> ellipticCurves() const; - void setEllipticCurves(const QVector<QSslEllipticCurve> &curves); - static void setDefaultEllipticCurves(const QVector<QSslEllipticCurve> &curves); - static QVector<QSslEllipticCurve> defaultEllipticCurves(); - static QVector<QSslEllipticCurve> supportedEllipticCurves(); +#if QT_DEPRECATED_SINCE(5, 5) + QT_DEPRECATED_X("Use QSslConfiguration::ciphers()") QList<QSslCipher> ciphers() const; + QT_DEPRECATED_X("Use QSslConfiguration::setCiphers()") void setCiphers(const QList<QSslCipher> &ciphers); + QT_DEPRECATED void setCiphers(const QString &ciphers); + QT_DEPRECATED static void setDefaultCiphers(const QList<QSslCipher> &ciphers); + QT_DEPRECATED static QList<QSslCipher> defaultCiphers(); + QT_DEPRECATED_X("Use QSslConfiguration::supportedCiphers()") static QList<QSslCipher> supportedCiphers(); +#endif // QT_DEPRECATED_SINCE(5, 5) // CA settings. bool addCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem, QRegExp::PatternSyntax syntax = QRegExp::FixedString); void addCaCertificate(const QSslCertificate &certificate); void addCaCertificates(const QList<QSslCertificate> &certificates); - void setCaCertificates(const QList<QSslCertificate> &certificates); - QList<QSslCertificate> caCertificates() const; +#if QT_DEPRECATED_SINCE(5, 5) + QT_DEPRECATED_X("Use QSslConfiguration::setCaCertificates()") void setCaCertificates(const QList<QSslCertificate> &certificates); + QT_DEPRECATED_X("Use QSslConfiguration::caCertificates()") QList<QSslCertificate> caCertificates() const; +#endif // QT_DEPRECATED_SINCE(5, 5) static bool addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem, QRegExp::PatternSyntax syntax = QRegExp::FixedString); static void addDefaultCaCertificate(const QSslCertificate &certificate); static void addDefaultCaCertificates(const QList<QSslCertificate> &certificates); - static void setDefaultCaCertificates(const QList<QSslCertificate> &certificates); - static QList<QSslCertificate> defaultCaCertificates(); - static QList<QSslCertificate> systemCaCertificates(); +#if QT_DEPRECATED_SINCE(5, 5) + QT_DEPRECATED static void setDefaultCaCertificates(const QList<QSslCertificate> &certificates); + QT_DEPRECATED static QList<QSslCertificate> defaultCaCertificates(); + QT_DEPRECATED_X("Use QSslConfiguration::systemCaCertificates()") static QList<QSslCertificate> systemCaCertificates(); +#endif // QT_DEPRECATED_SINCE(5, 5) bool waitForConnected(int msecs = 30000) Q_DECL_OVERRIDE; bool waitForEncrypted(int msecs = 30000); diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 497cbf4c9b1882fd4360d26112c5e2bae3e2813e..b83e56c29e47e957e654722b729ad2156cc7487d 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -33,6 +33,7 @@ #include "qsslsocket.h" +#include "qssl_p.h" #include "qsslsocket_mac_p.h" #include "qasn1element_p.h" #include "qsslcertificate_p.h" @@ -93,7 +94,7 @@ static OSStatus _q_SSLRead(QTcpSocket *plainSocket, char *data, size_t *dataLeng const qint64 bytes = plainSocket->read(data, *dataLength); #ifdef QSSLSOCKET_DEBUG - qDebug() << Q_FUNC_INFO << plainSocket << "read" << bytes; + qCDebug(lcSsl) << plainSocket << "read" << bytes; #endif if (bytes < 0) { *dataLength = 0; @@ -114,7 +115,7 @@ static OSStatus _q_SSLWrite(QTcpSocket *plainSocket, const char *data, size_t *d const qint64 bytes = plainSocket->write(data, *dataLength); #ifdef QSSLSOCKET_DEBUG - qDebug() << Q_FUNC_INFO << plainSocket << "write" << bytes; + qCDebug(lcSsl) << plainSocket << "write" << bytes; #endif if (bytes < 0) { *dataLength = 0; @@ -166,7 +167,7 @@ void QSslSocketPrivate::ensureInitialized() if (!s_loadRootCertsOnDemand) setDefaultCaCertificates(systemCaCertificates()); } else { - qWarning() << Q_FUNC_INFO << "SSLCreateContext failed"; + qCWarning(lcSsl) << "SSLCreateContext failed"; s_loadedCiphersAndCerts = false; } @@ -225,7 +226,7 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates() } } else { // no detailed error handling here - qWarning("could not retrieve system CA certificates"); + qCWarning(lcSsl) << "SecTrustSettingsCopyCertificates failed:" << status; } #endif return systemCerts; @@ -244,7 +245,7 @@ QSslSocketBackendPrivate::~QSslSocketBackendPrivate() void QSslSocketBackendPrivate::continueHandshake() { #ifdef QSSLSOCKET_DEBUG - qDebug() << Q_FUNC_INFO << plainSocket << "connection encrypted"; + qCDebug(lcSsl) << plainSocket << "connection encrypted"; #endif Q_Q(QSslSocket); connectionEncrypted = true; @@ -291,8 +292,7 @@ QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const SSLProtocol protocol = kSSLProtocolUnknown; const OSStatus err = SSLGetNegotiatedProtocolVersion(context, &protocol); if (err != noErr) { - qWarning() << Q_FUNC_INFO << "SSLGetNegotiatedProtocolVersion failed:" - << int(err); + qCWarning(lcSsl) << "SSLGetNegotiatedProtocolVersion failed:" << err; return QSsl::UnknownProtocol; } @@ -356,9 +356,12 @@ void QSslSocketBackendPrivate::transmit() const size_t nextDataBlockSize = writeBuffer.nextDataBlockSize(); size_t writtenBytes = 0; const OSStatus err = SSLWrite(context, writeBuffer.readPointer(), nextDataBlockSize, &writtenBytes); +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << plainSocket << "SSLWrite returned" << err; +#endif if (err != noErr && err != errSSLWouldBlock) { - qWarning() << Q_FUNC_INFO << "SSL write failed with error:" << int(err); - setError("SSL write failed", QAbstractSocket::SslInternalError); + setError(QStringLiteral("SSLWrite failed: %1").arg(err), + QAbstractSocket::SslInternalError); break; } @@ -387,9 +390,17 @@ void QSslSocketBackendPrivate::transmit() size_t readBytes = 0; data.resize(4096); const OSStatus err = SSLRead(context, data.data(), data.size(), &readBytes); - if (err != noErr && err != errSSLWouldBlock) { - qWarning() << Q_FUNC_INFO << "SSLRead failed with:" << int(err); - setError("SSL read failed", QAbstractSocket::SslInternalError); +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << plainSocket << "SSLRead returned" << err; +#endif + if (err == errSSLClosedGraceful) { + shutdown = true; // the other side shut down, make sure we do not send shutdown ourselves + setError(QSslSocket::tr("The TLS/SSL connection has been closed"), + QAbstractSocket::RemoteHostClosedError); + break; + } else if (err != noErr && err != errSSLWouldBlock) { + setError(QStringLiteral("SSLRead failed: %1").arg(err), + QAbstractSocket::SslInternalError); break; } @@ -596,7 +607,7 @@ QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSLCipherSuite(SSLCipherSui } else if (ciph.d->name.startsWith("ECDH-") || ciph.d->name.startsWith("ECDHE-")) { ciph.d->keyExchangeMethod = QLatin1String("ECDH"); } else { - qWarning() << Q_FUNC_INFO << "Unknown Kx" << ciph.d->name; + qCWarning(lcSsl) << "Unknown Kx" << ciph.d->name; } if (bits.size() == 2 || bits.size() == 3) { @@ -606,7 +617,7 @@ QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSLCipherSuite(SSLCipherSui } else if (ciph.d->name.contains("-RSA-")) { ciph.d->authenticationMethod = QLatin1String("RSA"); } else { - qWarning() << Q_FUNC_INFO << "Unknown Au" << ciph.d->name; + qCWarning(lcSsl) << "Unknown Au" << ciph.d->name; } if (ciph.d->name.contains("RC4-")) { @@ -628,7 +639,7 @@ QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSLCipherSuite(SSLCipherSui } else if (ciph.d->name.contains("NULL-")) { ciph.d->encryptionMethod = QLatin1String("NULL"); } else { - qWarning() << Q_FUNC_INFO << "Unknown Enc" << ciph.d->name; + qCWarning(lcSsl) << "Unknown Enc" << ciph.d->name; } } return ciph; @@ -647,7 +658,6 @@ bool QSslSocketBackendPrivate::initSslContext() context = SSLCreateContext(Q_NULLPTR, side, kSSLStreamType); if (!context) { - qWarning() << Q_FUNC_INFO << "SSLCreateContext failed"; setError("SSLCreateContext failed", QAbstractSocket::SslInternalError); return false; } @@ -655,9 +665,9 @@ bool QSslSocketBackendPrivate::initSslContext() const OSStatus err = SSLSetIOFuncs(context, reinterpret_cast<SSLReadFunc>(&_q_SSLRead), reinterpret_cast<SSLWriteFunc>(&_q_SSLWrite)); if (err != noErr) { - qWarning() << Q_FUNC_INFO << "SSLSetIOFuncs failed with error " << int(err); destroySslContext(); - setError("SSLSetIOFuncs failed", QAbstractSocket::SslInternalError); + setError(QStringLiteral("SSLSetIOFuncs failed: %1").arg(err), + QAbstractSocket::SslInternalError); return false; } @@ -675,7 +685,6 @@ bool QSslSocketBackendPrivate::initSslContext() } if (!setSessionProtocol()) { - qWarning() << Q_FUNC_INFO << "failed to set protocol version"; destroySslContext(); setError("Failed to set protocol version", QAbstractSocket::SslInternalError); return false; @@ -688,7 +697,6 @@ bool QSslSocketBackendPrivate::initSslContext() // But for OS X versions below 10.8 we have to do it explicitly: const OSStatus err = SSLSetEnableCertVerify(context, false); if (err != noErr) { - qWarning() << Q_FUNC_INFO << "SSLSetEnableCertVerify failed:" << int(err); destroySslContext(); setError(QStringLiteral("SSLSetEnableCertVerify failed: %1").arg(err), QSslSocket::SslInternalError); @@ -711,7 +719,6 @@ bool QSslSocketBackendPrivate::initSslContext() err = SSLSetSessionOption(context, kSSLSessionOptionBreakOnCertRequested, true); if (err != noErr) { - qWarning() << Q_FUNC_INFO << "SSLSetSessionOption failed:" << int(err); destroySslContext(); setError(QStringLiteral("SSLSetSessionOption failed: %1").arg(err), QSslSocket::SslInternalError); @@ -729,7 +736,6 @@ bool QSslSocketBackendPrivate::initSslContext() } if (err != noErr) { - qWarning() << Q_FUNC_INFO << "failed to set SSL context option in server mode"; destroySslContext(); setError(QStringLiteral("failed to set SSL context option in server mode: %1").arg(err), QAbstractSocket::SslInternalError); @@ -781,7 +787,7 @@ bool QSslSocketBackendPrivate::setSessionCertificate(QString &errorDescription, OSStatus err = SecPKCS12Import(pkcs12, options, &items); if (err != noErr) { #ifdef QSSLSOCKET_DEBUG - qWarning() << Q_FUNC_INFO << plainSocket + qCWarning(lcSsl) << plainSocket << QStringLiteral("SecPKCS12Import failed: %1").arg(err); #endif errorCode = QAbstractSocket::SslInvalidUserDataError; @@ -791,7 +797,7 @@ bool QSslSocketBackendPrivate::setSessionCertificate(QString &errorDescription, if (!CFArrayGetCount(items)) { #ifdef QSSLSOCKET_DEBUG - qWarning() << Q_FUNC_INFO << plainSocket << "SecPKCS12Import returned no items"; + qCWarning(lcSsl) << plainSocket << "SecPKCS12Import returned no items"; #endif errorCode = QAbstractSocket::SslInvalidUserDataError; errorDescription = QStringLiteral("SecPKCS12Import returned no items"); @@ -802,7 +808,7 @@ bool QSslSocketBackendPrivate::setSessionCertificate(QString &errorDescription, SecIdentityRef identity = (SecIdentityRef)CFDictionaryGetValue(import, kSecImportItemIdentity); if (!identity) { #ifdef QSSLSOCKET_DEBUG - qWarning() << Q_FUNC_INFO << plainSocket << "SecPKCS12Import returned no identity"; + qCWarning(lcSsl) << plainSocket << "SecPKCS12Import returned no identity"; #endif errorCode = QAbstractSocket::SslInvalidUserDataError; errorDescription = QStringLiteral("SecPKCS12Import returned no identity"); @@ -827,7 +833,7 @@ bool QSslSocketBackendPrivate::setSessionCertificate(QString &errorDescription, err = SSLSetCertificate(context, certs); if (err != noErr) { #ifdef QSSLSOCKET_DEBUG - qWarning() << Q_FUNC_INFO << plainSocket + qCWarning(lcSsl) << plainSocket << QStringLiteral("Cannot set certificate and key: %1").arg(err); #endif errorCode = QAbstractSocket::SslInvalidUserDataError; @@ -851,41 +857,41 @@ bool QSslSocketBackendPrivate::setSessionProtocol() // return errSSLIllegalParam; // where MINIMUM_STREAM_VERSION is SSL_Version_3_0, MAXIMUM_STREAM_VERSION is TLS_Version_1_2. if (configuration.protocol == QSsl::SslV2) { - qDebug() << Q_FUNC_INFO << "protocol QSsl::SslV2 is disabled"; + qCDebug(lcSsl) << "protocol QSsl::SslV2 is disabled"; return false; } if (configuration.protocol == QSsl::SslV3) { #ifdef QSSLSOCKET_DEBUG - qDebug() << Q_FUNC_INFO << plainSocket << "requesting : SSLv3"; + qCDebug(lcSsl) << plainSocket << "requesting : SSLv3"; #endif err = SSLSetProtocolVersionMin(context, kSSLProtocol3); if (err == noErr) err = SSLSetProtocolVersionMax(context, kSSLProtocol3); } else if (configuration.protocol == QSsl::TlsV1_0) { #ifdef QSSLSOCKET_DEBUG - qDebug() << Q_FUNC_INFO << plainSocket << "requesting : TLSv1.0"; + qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.0"; #endif err = SSLSetProtocolVersionMin(context, kTLSProtocol1); if (err == noErr) err = SSLSetProtocolVersionMax(context, kTLSProtocol1); } else if (configuration.protocol == QSsl::TlsV1_1) { #ifdef QSSLSOCKET_DEBUG - qDebug() << Q_FUNC_INFO << plainSocket << "requesting : TLSv1.1"; + qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.1"; #endif err = SSLSetProtocolVersionMin(context, kTLSProtocol11); if (err == noErr) err = SSLSetProtocolVersionMax(context, kTLSProtocol11); } else if (configuration.protocol == QSsl::TlsV1_2) { #ifdef QSSLSOCKET_DEBUG - qDebug() << Q_FUNC_INFO << plainSocket << "requesting : TLSv1.2"; + qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.2"; #endif err = SSLSetProtocolVersionMin(context, kTLSProtocol12); if (err == noErr) err = SSLSetProtocolVersionMax(context, kTLSProtocol12); } else if (configuration.protocol == QSsl::AnyProtocol) { #ifdef QSSLSOCKET_DEBUG - qDebug() << Q_FUNC_INFO << plainSocket << "requesting : any"; + qCDebug(lcSsl) << plainSocket << "requesting : any"; #endif // kSSLProtocol3, since kSSLProtocol2 is disabled: err = SSLSetProtocolVersionMin(context, kSSLProtocol3); @@ -893,41 +899,43 @@ bool QSslSocketBackendPrivate::setSessionProtocol() err = SSLSetProtocolVersionMax(context, kTLSProtocol12); } else if (configuration.protocol == QSsl::TlsV1SslV3) { #ifdef QSSLSOCKET_DEBUG - qDebug() << Q_FUNC_INFO << plainSocket << "requesting : SSLv3 - TLSv1.2"; + qCDebug(lcSsl) << plainSocket << "requesting : SSLv3 - TLSv1.2"; #endif err = SSLSetProtocolVersionMin(context, kSSLProtocol3); if (err == noErr) err = SSLSetProtocolVersionMax(context, kTLSProtocol12); } else if (configuration.protocol == QSsl::SecureProtocols) { #ifdef QSSLSOCKET_DEBUG - qDebug() << Q_FUNC_INFO << plainSocket << "requesting : TLSv1 - TLSv1.2"; + qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2"; #endif err = SSLSetProtocolVersionMin(context, kTLSProtocol1); if (err == noErr) err = SSLSetProtocolVersionMax(context, kTLSProtocol12); } else if (configuration.protocol == QSsl::TlsV1_0OrLater) { #ifdef QSSLSOCKET_DEBUG - qDebug() << Q_FUNC_INFO << plainSocket << "requesting : TLSv1 - TLSv1.2"; + qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2"; #endif err = SSLSetProtocolVersionMin(context, kTLSProtocol1); if (err == noErr) err = SSLSetProtocolVersionMax(context, kTLSProtocol12); } else if (configuration.protocol == QSsl::TlsV1_1OrLater) { #ifdef QSSLSOCKET_DEBUG - qDebug() << Q_FUNC_INFO << plainSocket << "requesting : TLSv1.1 - TLSv1.2"; + qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.1 - TLSv1.2"; #endif err = SSLSetProtocolVersionMin(context, kTLSProtocol11); if (err == noErr) err = SSLSetProtocolVersionMax(context, kTLSProtocol12); } else if (configuration.protocol == QSsl::TlsV1_2OrLater) { #ifdef QSSLSOCKET_DEBUG - qDebug() << Q_FUNC_INFO << plainSocket << "requesting : TLSv1.2"; + qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.2"; #endif err = SSLSetProtocolVersionMin(context, kTLSProtocol12); if (err == noErr) err = SSLSetProtocolVersionMax(context, kTLSProtocol12); } else { - qDebug() << Q_FUNC_INFO << "no protocol version found in the configuration"; +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << plainSocket << "no protocol version found in the configuration"; +#endif return false; } @@ -997,7 +1005,8 @@ bool QSslSocketBackendPrivate::verifyPeerTrust() if (err != noErr) { // We can not ignore this, it's not even about trust verification // probably ... - setError("SecTrustEvaluate failed", QAbstractSocket::SslHandshakeFailedError); + setError(QStringLiteral("SecTrustEvaluate failed: %1").arg(err), + QAbstractSocket::SslHandshakeFailedError); plainSocket->disconnectFromHost(); return false; } @@ -1132,7 +1141,7 @@ bool QSslSocketBackendPrivate::startHandshake() OSStatus err = SSLHandshake(context); #ifdef QSSLSOCKET_DEBUG - qDebug() << Q_FUNC_INFO << plainSocket << "SSLHandhake returned" << err; + qCDebug(lcSsl) << plainSocket << "SSLHandhake returned" << err; #endif if (err == errSSLWouldBlock) { @@ -1153,7 +1162,6 @@ bool QSslSocketBackendPrivate::startHandshake() // setSessionCertificate does not fail if we have no certificate. // Failure means a real error (invalid certificate, no private key, etc). if (!setSessionCertificate(errorDescription, errorCode)) { - qWarning() << Q_FUNC_INFO << "Failed to provide a client certificate"; setError(errorDescription, errorCode); return false; } else { @@ -1169,7 +1177,7 @@ bool QSslSocketBackendPrivate::startHandshake() return startHandshake(); } - setError(QStringLiteral("Error during SSL handshake: %1").arg(err), + setError(QStringLiteral("SSLHandshake failed: %1").arg(err), QAbstractSocket::SslHandshakeFailedError); plainSocket->disconnectFromHost(); return false; @@ -1177,7 +1185,7 @@ bool QSslSocketBackendPrivate::startHandshake() // Connection aborted during handshake phase. if (q->state() != QAbstractSocket::ConnectedState) { - qDebug() << Q_FUNC_INFO << "connection aborted"; + qCDebug(lcSsl) << "connection aborted"; return false; } diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 436588afc5aed1f454a89571ecebb06a76b37eaa..3bcb8925c15a341bda59c4b1a6165af889f337b8 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -671,6 +671,7 @@ void QSslSocketPrivate::resetDefaultEllipticCurves() QVarLengthArray<EC_builtin_curve> builtinCurves(static_cast<int>(curveCount)); if (q_EC_get_builtin_curves(builtinCurves.data(), curveCount) == curveCount) { + curves.reserve(int(curveCount)); for (size_t i = 0; i < curveCount; ++i) { QSslEllipticCurve curve; curve.id = builtinCurves[int(i)].nid; @@ -1199,7 +1200,9 @@ bool QSslSocketBackendPrivate::startHandshake() } // Translate errors from the error list into QSslErrors. - for (int i = 0; i < errorList.size(); ++i) { + const int numErrors = errorList.size(); + errors.reserve(errors.size() + numErrors); + for (int i = 0; i < numErrors; ++i) { const QPair<int, int> &errorAndDepth = errorList.at(i); int err = errorAndDepth.first; int depth = errorAndDepth.second; @@ -1668,7 +1671,7 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> & setDefaultCaCertificates(defaultCaCertificates() + systemCaCertificates()); } - foreach (const QSslCertificate &caCertificate, QSslSocket::defaultCaCertificates()) { + foreach (const QSslCertificate &caCertificate, QSslConfiguration::defaultConfiguration().caCertificates()) { // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html: // // If several CA certificates matching the name, key identifier, and @@ -1761,7 +1764,9 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> & } // Translate errors from the error list into QSslErrors. - for (int i = 0; i < errorList.size(); ++i) { + const int numErrors = errorList.size(); + errors.reserve(errors.size() + numErrors); + for (int i = 0; i < numErrors; ++i) { const QPair<int, int> &errorAndDepth = errorList.at(i); int err = errorAndDepth.first; int depth = errorAndDepth.second; diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index e2700df3cc7906d92d94bea3d2ae862f6569b446..e7829bac909628c5f78529a7ec2ec95ac43ba90c 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -119,10 +119,13 @@ void qsslSocketUnresolvedSymbolWarning(const char *functionName) qCWarning(lcSsl, "QSslSocket: cannot call unresolved function %s", functionName); } +#ifndef QT_NO_LIBRARY void qsslSocketCannotResolveSymbolWarning(const char *functionName) { qCWarning(lcSsl, "QSslSocket: cannot resolve %s", functionName); } +#endif + } #endif // QT_LINKED_OPENSSL @@ -156,7 +159,16 @@ DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, const unsigned char **b, b, long c, c DEFINEFUNC2(char *, ERR_error_string, unsigned long a, a, char *b, b, return 0, return) DEFINEFUNC(unsigned long, ERR_get_error, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(void, ERR_free_strings, void, DUMMYARG, return, DUMMYARG) +DEFINEFUNC(void, EVP_CIPHER_CTX_cleanup, EVP_CIPHER_CTX *a, a, return, DUMMYARG) +DEFINEFUNC(void, EVP_CIPHER_CTX_init, EVP_CIPHER_CTX *a, a, return, DUMMYARG) +DEFINEFUNC4(int, EVP_CIPHER_CTX_ctrl, EVP_CIPHER_CTX *ctx, ctx, int type, type, int arg, arg, void *ptr, ptr, return 0, return); +DEFINEFUNC2(int, EVP_CIPHER_CTX_set_key_length, EVP_CIPHER_CTX *ctx, ctx, int keylen, keylen, return 0, return) +DEFINEFUNC5(int, EVP_CipherInit, EVP_CIPHER_CTX *ctx, ctx, const EVP_CIPHER *type, type, const unsigned char *key, key, const unsigned char *iv, iv, int enc, enc, return 0, return); +DEFINEFUNC5(int, EVP_CipherUpdate, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, const unsigned char *in, in, int inl, inl, return 0, return); +DEFINEFUNC3(int, EVP_CipherFinal, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, return 0, return); +DEFINEFUNC(const EVP_CIPHER *, EVP_des_cbc, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return 0, return) +DEFINEFUNC(const EVP_CIPHER *, EVP_rc2_cbc, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return) DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return) DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return) @@ -309,13 +321,17 @@ DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return 0, return) #endif #else +#ifndef OPENSSL_NO_SSL2 DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return) +#endif #ifndef OPENSSL_NO_SSL3_METHOD DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return) #endif DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return) +#ifndef OPENSSL_NO_SSL2 DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return) +#endif #ifndef OPENSSL_NO_SSL3_METHOD DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return) #endif @@ -436,39 +452,41 @@ bool q_resolveOpenSslSymbols() #else # ifdef Q_OS_UNIX -static bool libGreaterThan(const QString &lhs, const QString &rhs) +struct NumericallyLess { - QStringList lhsparts = lhs.split(QLatin1Char('.')); - QStringList rhsparts = rhs.split(QLatin1Char('.')); - Q_ASSERT(lhsparts.count() > 1 && rhsparts.count() > 1); - - for (int i = 1; i < rhsparts.count(); ++i) { - if (lhsparts.count() <= i) - // left hand side is shorter, so it's less than rhs - return false; - + typedef bool result_type; + result_type operator()(const QStringRef &lhs, const QStringRef &rhs) const + { bool ok = false; int b = 0; - int a = lhsparts.at(i).toInt(&ok); + int a = lhs.toInt(&ok); if (ok) - b = rhsparts.at(i).toInt(&ok); + b = rhs.toInt(&ok); if (ok) { // both toInt succeeded - if (a == b) - continue; - return a > b; + return a < b; } else { // compare as strings; - if (lhsparts.at(i) == rhsparts.at(i)) - continue; - return lhsparts.at(i) > rhsparts.at(i); + return lhs < rhs; } } +}; - // they compared strictly equally so far - // lhs cannot be less than rhs - return true; -} +struct LibGreaterThan +{ + typedef bool result_type; + result_type operator()(const QString &lhs, const QString &rhs) const + { + const QVector<QStringRef> lhsparts = lhs.splitRef(QLatin1Char('.')); + const QVector<QStringRef> rhsparts = rhs.splitRef(QLatin1Char('.')); + Q_ASSERT(lhsparts.count() > 1 && rhsparts.count() > 1); + + // note: checking rhs < lhs, the same as lhs > rhs + return std::lexicographical_compare(rhsparts.begin() + 1, rhsparts.end(), + lhsparts.begin() + 1, lhsparts.end(), + NumericallyLess()); + } +}; #if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) static int dlIterateCallback(struct dl_phdr_info *info, size_t size, void *data) @@ -522,39 +540,33 @@ static QStringList libraryPathList() return paths; } - -static QStringList findAllLibSsl() +Q_NEVER_INLINE +static QStringList findAllLibs(QLatin1String filter) { QStringList paths = libraryPathList(); - QStringList foundSsls; + QStringList found; + const QStringList filters((QString(filter))); foreach (const QString &path, paths) { QDir dir(path); - QStringList entryList = dir.entryList(QStringList() << QLatin1String("libssl.*"), QDir::Files); + QStringList entryList = dir.entryList(filters, QDir::Files); - std::sort(entryList.begin(), entryList.end(), libGreaterThan); + std::sort(entryList.begin(), entryList.end(), LibGreaterThan()); foreach (const QString &entry, entryList) - foundSsls << path + QLatin1Char('/') + entry; + found << path + QLatin1Char('/') + entry; } - return foundSsls; + return found; } -static QStringList findAllLibCrypto() +static QStringList findAllLibSsl() { - QStringList paths = libraryPathList(); - - QStringList foundCryptos; - foreach (const QString &path, paths) { - QDir dir(path); - QStringList entryList = dir.entryList(QStringList() << QLatin1String("libcrypto.*"), QDir::Files); - - std::sort(entryList.begin(), entryList.end(), libGreaterThan); - foreach (const QString &entry, entryList) - foundCryptos << path + QLatin1Char('/') + entry; - } + return findAllLibs(QLatin1String("libssl.*")); +} - return foundCryptos; +static QStringList findAllLibCrypto() +{ + return findAllLibs(QLatin1String("libcrypto.*")); } # endif @@ -759,7 +771,16 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(ERR_error_string) RESOLVEFUNC(ERR_get_error) RESOLVEFUNC(ERR_free_strings) + RESOLVEFUNC(EVP_CIPHER_CTX_cleanup) + RESOLVEFUNC(EVP_CIPHER_CTX_init) + RESOLVEFUNC(EVP_CIPHER_CTX_ctrl) + RESOLVEFUNC(EVP_CIPHER_CTX_set_key_length) + RESOLVEFUNC(EVP_CipherInit) + RESOLVEFUNC(EVP_CipherUpdate) + RESOLVEFUNC(EVP_CipherFinal) + RESOLVEFUNC(EVP_des_cbc) RESOLVEFUNC(EVP_des_ede3_cbc) + RESOLVEFUNC(EVP_rc2_cbc) RESOLVEFUNC(EVP_PKEY_assign) RESOLVEFUNC(EVP_PKEY_set1_RSA) RESOLVEFUNC(EVP_PKEY_set1_DSA) diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index 626c049629022501b698a37361bcb91494cc1fb5..7f87f11b7c76be3e7c96940fcd4e802c49b3759a 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -235,7 +235,16 @@ X509 *q_d2i_X509(X509 **a, const unsigned char **b, long c); char *q_ERR_error_string(unsigned long a, char *b); unsigned long q_ERR_get_error(); void q_ERR_free_strings(); +void q_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a); +void q_EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a); +int q_EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +int q_EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); +int q_EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, const unsigned char *key, const unsigned char *iv, int enc); +int q_EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); +int q_EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +const EVP_CIPHER *q_EVP_des_cbc(); const EVP_CIPHER *q_EVP_des_ede3_cbc(); +const EVP_CIPHER *q_EVP_rc2_cbc(); int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c); Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b); int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b); @@ -363,27 +372,43 @@ typedef unsigned int (*q_psk_client_callback_t)(SSL *ssl, const char *hint, char void q_SSL_set_psk_client_callback(SSL *ssl, q_psk_client_callback_t callback); #endif // OPENSSL_NO_PSK #if OPENSSL_VERSION_NUMBER >= 0x10000000L +#ifndef OPENSSL_NO_SSL2 const SSL_METHOD *q_SSLv2_client_method(); +#endif +#ifndef OPENSSL_NO_SSL3_METHOD const SSL_METHOD *q_SSLv3_client_method(); +#endif const SSL_METHOD *q_SSLv23_client_method(); const SSL_METHOD *q_TLSv1_client_method(); const SSL_METHOD *q_TLSv1_1_client_method(); const SSL_METHOD *q_TLSv1_2_client_method(); +#ifndef OPENSSL_NO_SSL2 const SSL_METHOD *q_SSLv2_server_method(); +#endif +#ifndef OPENSSL_NO_SSL3_METHOD const SSL_METHOD *q_SSLv3_server_method(); +#endif const SSL_METHOD *q_SSLv23_server_method(); const SSL_METHOD *q_TLSv1_server_method(); const SSL_METHOD *q_TLSv1_1_server_method(); const SSL_METHOD *q_TLSv1_2_server_method(); #else +#ifndef OPENSSL_NO_SSL2 SSL_METHOD *q_SSLv2_client_method(); +#endif +#ifndef OPENSSL_NO_SSL3_METHOD SSL_METHOD *q_SSLv3_client_method(); +#endif SSL_METHOD *q_SSLv23_client_method(); SSL_METHOD *q_TLSv1_client_method(); SSL_METHOD *q_TLSv1_1_client_method(); SSL_METHOD *q_TLSv1_2_client_method(); +#ifndef OPENSSL_NO_SSL2 SSL_METHOD *q_SSLv2_server_method(); +#endif +#ifndef OPENSSL_NO_SSL3_METHOD SSL_METHOD *q_SSLv3_server_method(); +#endif SSL_METHOD *q_SSLv23_server_method(); SSL_METHOD *q_TLSv1_server_method(); SSL_METHOD *q_TLSv1_1_server_method(); diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index 5f726f2371b788a4c2acb82f930947bee9392620..d6519718d95946adf2e3a163b05384fc3cfe7b60 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -137,9 +137,7 @@ public: static void setDefaultSupportedCiphers(const QList<QSslCipher> &ciphers); static void resetDefaultCiphers(); - static QVector<QSslEllipticCurve> defaultEllipticCurves(); static QVector<QSslEllipticCurve> supportedEllipticCurves(); - static void setDefaultEllipticCurves(const QVector<QSslEllipticCurve> &curves); static void setDefaultSupportedEllipticCurves(const QVector<QSslEllipticCurve> &curves); static void resetDefaultEllipticCurves(); diff --git a/src/opengl/doc/src/qtopengl-index.qdoc b/src/opengl/doc/src/qtopengl-index.qdoc index 3c6fcde482bb023fe3b9fc83876814577b2520df..d8e63547b75719517e65833ced82e10d40811a3b 100644 --- a/src/opengl/doc/src/qtopengl-index.qdoc +++ b/src/opengl/doc/src/qtopengl-index.qdoc @@ -37,7 +37,7 @@ OpenGL is a standard API for rendering 3D graphics. OpenGL only deals with 3D rendering and provides little or no support for GUI programming issues. The user interface for an OpenGL application - must be created with another toolkit, such as Cocoa on the Mac OS X + must be created with another toolkit, such as Cocoa on the OS X platform, Microsoft Foundation Classes (MFC) under Windows, or Qt on both platforms. diff --git a/src/opengl/doc/src/qtopengl-module.qdoc b/src/opengl/doc/src/qtopengl-module.qdoc index 1dbfd1bd01202fb67ba6f5c45a9a41df5ab47ea3..824db487547d995af17f688eb9469dd114f3c14f 100644 --- a/src/opengl/doc/src/qtopengl-module.qdoc +++ b/src/opengl/doc/src/qtopengl-module.qdoc @@ -40,7 +40,7 @@ OpenGL is a standard API for rendering 3D graphics. OpenGL only deals with 3D rendering and provides little or no support for GUI programming issues. The user interface for an OpenGL application - must be created with another toolkit, such as Cocoa on the Mac OS X + must be created with another toolkit, such as Cocoa on the OS X platform, Microsoft Foundation Classes (MFC) under Windows, or Qt on both platforms. diff --git a/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp b/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp index 1551d1c7cb04bb1b4b6a654972ecb1b29504df18..6bf152b83dd9bea1dba88b27e20c32833785d913 100644 --- a/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp +++ b/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp @@ -63,6 +63,7 @@ QGLCustomShaderStage::~QGLCustomShaderStage() d->m_manager->removeCustomStage(); d->m_manager->sharedShaders->cleanupCustomStage(this); } + delete d_ptr; } void QGLCustomShaderStage::setUniformsDirty() diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 5aec058532442339ff187f635ac406f220354a89..63ebf14bd5440a344ecf55cf217a5e4d989a88d5 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -3687,7 +3687,7 @@ void QGLContext::doneCurrent() QGLWidget. This will side-step the issue altogether, and is what we recommend for users that need this kind of functionality. - On Mac OS X, when Qt is built with Cocoa support, a QGLWidget + On OS X, when Qt is built with Cocoa support, a QGLWidget can't have any sibling widgets placed ontop of itself. This is due to limitations in the Cocoa API and is not supported by Apple. @@ -4354,6 +4354,8 @@ void QGLWidget::resizeOverlayGL(int, int) { } +/*!\reimp + */ bool QGLWidget::event(QEvent *e) { Q_D(QGLWidget); @@ -4494,7 +4496,7 @@ QImage QGLWidget::grabFrameBuffer(bool withAlpha) { makeCurrent(); QImage res; - qreal pixelRatio = devicePixelRatio(); + qreal pixelRatio = devicePixelRatioF(); int w = pixelRatio * width(); int h = pixelRatio * height(); if (format().rgba()) @@ -4907,7 +4909,7 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con GLdouble win_x = 0, win_y = 0, win_z = 0; qgluProject(x, y, z, &model[0], &proj[0], &view[0], &win_x, &win_y, &win_z); - const int dpr = d->glcx->device()->devicePixelRatio(); + const int dpr = d->glcx->device()->devicePixelRatioF(); win_x /= dpr; win_y /= dpr; win_y = height - win_y; // y is inverted diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 8c55cffbb3e4fd8f03384e395097dab4da61b195..99abdd2ad634b861709e008e66843b20e9df91fa 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -235,7 +235,7 @@ public: QGLContext(const QGLFormat& format); virtual ~QGLContext(); - virtual bool create(const QGLContext* shareContext = 0); + virtual bool create(const QGLContext* shareContext = Q_NULLPTR); bool isValid() const; bool isSharing() const; void reset(); @@ -303,7 +303,7 @@ public: QOpenGLContext *contextHandle() const; protected: - virtual bool chooseContext(const QGLContext* shareContext = 0); + virtual bool chooseContext(const QGLContext* shareContext = Q_NULLPTR); bool deviceIsPixmap() const; bool windowCreated() const; @@ -356,12 +356,12 @@ class Q_OPENGL_EXPORT QGLWidget : public QWidget Q_OBJECT Q_DECLARE_PRIVATE(QGLWidget) public: - explicit QGLWidget(QWidget* parent=0, - const QGLWidget* shareWidget = 0, Qt::WindowFlags f=0); - explicit QGLWidget(QGLContext *context, QWidget* parent=0, - const QGLWidget* shareWidget = 0, Qt::WindowFlags f=0); - explicit QGLWidget(const QGLFormat& format, QWidget* parent=0, - const QGLWidget* shareWidget = 0, Qt::WindowFlags f=0); + explicit QGLWidget(QWidget* parent=Q_NULLPTR, + const QGLWidget* shareWidget = Q_NULLPTR, Qt::WindowFlags f=Qt::WindowFlags()); + explicit QGLWidget(QGLContext *context, QWidget* parent=Q_NULLPTR, + const QGLWidget* shareWidget = Q_NULLPTR, Qt::WindowFlags f=Qt::WindowFlags()); + explicit QGLWidget(const QGLFormat& format, QWidget* parent=Q_NULLPTR, + const QGLWidget* shareWidget = Q_NULLPTR, Qt::WindowFlags f=Qt::WindowFlags()); ~QGLWidget(); void qglColor(const QColor& c) const; @@ -380,7 +380,7 @@ public: void setFormat(const QGLFormat& format); QGLContext* context() const; - void setContext(QGLContext* context, const QGLContext* shareContext = 0, + void setContext(QGLContext* context, const QGLContext* shareContext = Q_NULLPTR, bool deleteOldContext = true); QPixmap renderPixmap(int w = 0, int h = 0, bool useContext = false); @@ -442,9 +442,9 @@ protected: QGLWidget(QGLWidgetPrivate &dd, const QGLFormat &format = QGLFormat(), - QWidget *parent = 0, - const QGLWidget* shareWidget = 0, - Qt::WindowFlags f = 0); + QWidget *parent = Q_NULLPTR, + const QGLWidget* shareWidget = Q_NULLPTR, + Qt::WindowFlags f = Qt::WindowFlags()); private: Q_DISABLE_COPY(QGLWidget) diff --git a/src/opengl/qglbuffer.h b/src/opengl/qglbuffer.h index e424ff2b5cd5506bdbb301dd6c7a942d329937af..67b1a68072381cb100c7a5237cee4e1557d9cda4 100644 --- a/src/opengl/qglbuffer.h +++ b/src/opengl/qglbuffer.h @@ -103,7 +103,7 @@ public: void write(int offset, const void *data, int count); void allocate(const void *data, int count); - inline void allocate(int count) { allocate(0, count); } + inline void allocate(int count) { allocate(Q_NULLPTR, count); } void *map(QGLBuffer::Access access); bool unmap(); diff --git a/src/opengl/qglcolormap.h b/src/opengl/qglcolormap.h index f16f94c7f5277ca2a4267e95bf85f7b63daa8cf5..53031fd98fd324be861f239df57bd0fd6d14f4aa 100644 --- a/src/opengl/qglcolormap.h +++ b/src/opengl/qglcolormap.h @@ -63,7 +63,7 @@ public: int findNearest(QRgb color) const; protected: - Qt::HANDLE handle() { return d ? d->cmapHandle : 0; } + Qt::HANDLE handle() { return d ? d->cmapHandle : Q_NULLPTR; } void setHandle(Qt::HANDLE ahandle) { d->cmapHandle = ahandle; } private: diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 3479fccf5864f69ee7ec59bd145b073d1820f6a1..b636f90918a8651cc0eee03ee39a299c414e01be 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -1285,6 +1285,9 @@ int QGLFramebufferObject::metric(PaintDeviceMetric metric) const case QPaintDevice::PdmDevicePixelRatio: return 1; + case QPaintDevice::PdmDevicePixelRatioScaled: + return 1 * QPaintDevice::devicePixelRatioFScale(); + default: qWarning("QGLFramebufferObject::metric(), Unhandled metric type: %d.\n", metric); break; diff --git a/src/opengl/qglfunctions.h b/src/opengl/qglfunctions.h index 80b8596a20bd2f19e53c23b428c618e9b7aa0e82..ddb7b89d987149e27ba710113736abd9ccace2c5 100644 --- a/src/opengl/qglfunctions.h +++ b/src/opengl/qglfunctions.h @@ -70,7 +70,7 @@ public: QGLFunctions::OpenGLFeatures openGLFeatures() const; bool hasOpenGLFeature(QGLFunctions::OpenGLFeature feature) const; - void initializeGLFunctions(const QGLContext *context = 0); + void initializeGLFunctions(const QGLContext *context = Q_NULLPTR); void glActiveTexture(GLenum texture); void glAttachShader(GLuint program, GLuint shader); @@ -172,14 +172,14 @@ public: private: QGLFunctionsPrivate *d_ptr; - static bool isInitialized(const QGLFunctionsPrivate *d) { return d != 0; } + static bool isInitialized(const QGLFunctionsPrivate *d) { return d != Q_NULLPTR; } }; Q_DECLARE_OPERATORS_FOR_FLAGS(QGLFunctions::OpenGLFeatures) struct QGLFunctionsPrivate { - QGLFunctionsPrivate(const QGLContext *context = 0); + QGLFunctionsPrivate(const QGLContext *context = Q_NULLPTR); QOpenGLFunctions *funcs; }; diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp index 89cf01d8ec5eceff8066e77e01ae23725ffd6bd8..b5df45bcc81adf7ff8b6c7ac440653cdb2029c18 100644 --- a/src/opengl/qglpaintdevice.cpp +++ b/src/opengl/qglpaintdevice.cpp @@ -62,6 +62,8 @@ int QGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const } case PdmDevicePixelRatio: return 1; + case PdmDevicePixelRatioScaled: + return 1 * QPaintDevice::devicePixelRatioFScale(); default: qWarning("QGLPaintDevice::metric() - metric %d not known", metric); return 0; diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index 49d2df9e1dbaf6e9e3c998807ffbf664c988c72f..943ec7ad30d93ab75bb7c30df91c41e4e6b6d3ee 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -60,7 +60,7 @@ an OpenGL texture.} The texture is then updated automatically when the pbuffer contents change, eliminating the need for additional copy operations. This is supported only on Windows - and Mac OS X systems that provide the \c render_texture + and OS X systems that provide the \c render_texture extension. Note that under Windows, a multi-sampled pbuffer can't be used in conjunction with the \c render_texture extension. If a multi-sampled pbuffer is requested under @@ -287,7 +287,7 @@ QGLContext *QGLPixelBuffer::context() const pbuffer contents to a texture using updateDynamicTexture(). \warning For the bindToDynamicTexture() call to succeed on the - Mac OS X, the pbuffer needs a shared context, i.e. the + OS X, the pbuffer needs a shared context, i.e. the QGLPixelBuffer must be created with a share widget. \sa generateDynamicTexture(), releaseFromDynamicTexture() @@ -316,7 +316,7 @@ QGLContext *QGLPixelBuffer::context() const \snippet code/src_opengl_qglpixelbuffer.cpp 1 - An alternative on Windows and Mac OS X systems that support the + An alternative on Windows and OS X systems that support the \c render_texture extension is to use bindToDynamicTexture() to get dynamic updates of the texture. @@ -458,6 +458,9 @@ int QGLPixelBuffer::metric(PaintDeviceMetric metric) const case QPaintDevice::PdmDevicePixelRatio: return 1; + case QPaintDevice::PdmDevicePixelRatioScaled: + return QPaintDevice::devicePixelRatioFScale(); + default: qWarning("QGLPixelBuffer::metric(), Unhandled metric type: %d\n", metric); break; diff --git a/src/opengl/qglpixelbuffer.h b/src/opengl/qglpixelbuffer.h index 0f0110da9636116bf2219c64096c93fb414dc64e..2aad76b002aefbbc002bca19003a707666ab33df 100644 --- a/src/opengl/qglpixelbuffer.h +++ b/src/opengl/qglpixelbuffer.h @@ -47,9 +47,9 @@ class Q_OPENGL_EXPORT QGLPixelBuffer : public QPaintDevice Q_DECLARE_PRIVATE(QGLPixelBuffer) public: QGLPixelBuffer(const QSize &size, const QGLFormat &format = QGLFormat::defaultFormat(), - QGLWidget *shareWidget = 0); + QGLWidget *shareWidget = Q_NULLPTR); QGLPixelBuffer(int width, int height, const QGLFormat &format = QGLFormat::defaultFormat(), - QGLWidget *shareWidget = 0); + QGLWidget *shareWidget = Q_NULLPTR); virtual ~QGLPixelBuffer(); bool isValid() const; diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index c0122eb59f36202d068130e92a014344a5191a7f..abd4a59fb8050d5074f1d69a12e206f251d03bba 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -1706,7 +1706,7 @@ void QGLShaderProgram::setAttributeBuffer Q_UNUSED(d); if (location != -1) { d->glfuncs->glVertexAttribPointer(location, tupleSize, type, GL_TRUE, stride, - reinterpret_cast<const void *>(offset)); + reinterpret_cast<const void *>(qintptr(offset))); } } diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h index 5d9fe22b0baba56f7297ea6aafd6a0fb148ca085..8f2c74fae7830f672cb08a0af1b4724949353891 100644 --- a/src/opengl/qglshaderprogram.h +++ b/src/opengl/qglshaderprogram.h @@ -58,8 +58,8 @@ public: }; Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit) - explicit QGLShader(QGLShader::ShaderType type, QObject *parent = 0); - QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObject *parent = 0); + explicit QGLShader(QGLShader::ShaderType type, QObject *parent = Q_NULLPTR); + QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObject *parent = Q_NULLPTR); virtual ~QGLShader(); QGLShader::ShaderType shaderType() const; @@ -76,7 +76,7 @@ public: GLuint shaderId() const; - static bool hasOpenGLShaders(ShaderType type, const QGLContext *context = 0); + static bool hasOpenGLShaders(ShaderType type, const QGLContext *context = Q_NULLPTR); private: friend class QGLShaderProgram; @@ -94,8 +94,8 @@ class Q_OPENGL_EXPORT QGLShaderProgram : public QObject { Q_OBJECT public: - explicit QGLShaderProgram(QObject *parent = 0); - explicit QGLShaderProgram(const QGLContext *context, QObject *parent = 0); + explicit QGLShaderProgram(QObject *parent = Q_NULLPTR); + explicit QGLShaderProgram(const QGLContext *context, QObject *parent = Q_NULLPTR); virtual ~QGLShaderProgram(); bool addShader(QGLShader *shader); @@ -280,7 +280,7 @@ public: void setUniformValueArray(const char *name, const QMatrix4x3 *values, int count); void setUniformValueArray(const char *name, const QMatrix4x4 *values, int count); - static bool hasOpenGLShaderPrograms(const QGLContext *context = 0); + static bool hasOpenGLShaderPrograms(const QGLContext *context = Q_NULLPTR); private Q_SLOTS: void shaderDestroyed(); diff --git a/src/platformheaders/cocoafunctions/cocoafunctions.pri b/src/platformheaders/cocoafunctions/cocoafunctions.pri new file mode 100644 index 0000000000000000000000000000000000000000..3987523f9afbbb7d3ad95fdf65a8bbc1361de7f4 --- /dev/null +++ b/src/platformheaders/cocoafunctions/cocoafunctions.pri @@ -0,0 +1 @@ +HEADERS += $$PWD/qcocoawindowfunctions.h diff --git a/src/plugins/platforms/windows/qwindowsscaling.cpp b/src/platformheaders/cocoafunctions/qcocoawindowfunctions.h similarity index 61% rename from src/plugins/platforms/windows/qwindowsscaling.cpp rename to src/platformheaders/cocoafunctions/qcocoawindowfunctions.h index 6ab7f254fdafd4ada4dba5ee9557239c9a198ec0..997f440e659f8c05b1063a8251aa9a9c7fa054c0 100644 --- a/src/plugins/platforms/windows/qwindowsscaling.cpp +++ b/src/platformheaders/cocoafunctions/qcocoawindowfunctions.h @@ -31,41 +31,27 @@ ** ****************************************************************************/ -#include "qwindowsscaling.h" -#include "qwindowsscreen.h" +#ifndef QXCBWINDOWFUNCTIONS_H +#define QXCBWINDOWFUNCTIONS_H -#include <QtCore/QDebug> -#include <QtCore/QCoreApplication> +#include <QtPlatformHeaders/QPlatformHeaderHelper> QT_BEGIN_NAMESPACE -/*! - \class QWindowsScaling - \brief Windows scaling utilities +class QWindow; - \internal - \ingroup qt-lighthouse-win -*/ +class QCocoaWindowFunctions { +public: + typedef QPoint (*BottomLeftClippedByNSWindowOffset)(QWindow *window); + static const QByteArray bottomLeftClippedByNSWindowOffsetIdentifier() { return QByteArrayLiteral("CocoaBottomLeftClippedByNSWindowOffset"); } -int QWindowsScaling::m_factor = 1; - -static const char devicePixelRatioEnvVar[] = "QT_DEVICE_PIXEL_RATIO"; - -// Suggest a scale factor by checking monitor sizes. -int QWindowsScaling::determineUiScaleFactor() -{ - if (!qEnvironmentVariableIsSet(devicePixelRatioEnvVar)) - return 1; - const QByteArray envDevicePixelRatioEnv = qgetenv(devicePixelRatioEnvVar); - // Auto: Suggest a scale factor by checking monitor resolution. - if (envDevicePixelRatioEnv == "auto") { - const int maxResolution = QWindowsScreen::maxMonitorHorizResolution(); - return maxResolution > 180 ? maxResolution / 96 : 1; + static QPoint bottomLeftClippedByNSWindowOffset(QWindow *window) + { + return QPlatformHeaderHelper::callPlatformFunction<QPoint, BottomLeftClippedByNSWindowOffset>(bottomLeftClippedByNSWindowOffsetIdentifier(),window); } - // Get factor from environment - bool ok = false; - const int envFactor = envDevicePixelRatioEnv.toInt(&ok); - return ok && envFactor > 0 ? envFactor : 1; -} +}; + QT_END_NAMESPACE + +#endif // QXCBWINDOWFUNCTIONS_H diff --git a/examples/widgets/doc/src/recentfiles.qdoc b/src/platformheaders/cocoafunctions/qcocoawindowfunctions.qdoc similarity index 52% rename from examples/widgets/doc/src/recentfiles.qdoc rename to src/platformheaders/cocoafunctions/qcocoawindowfunctions.qdoc index b58c9a1f7675c8155178fb1f5d27cf61613131ff..e95f92edb5264eb53b82e3f54a2fab3611a6ab6a 100644 --- a/examples/widgets/doc/src/recentfiles.qdoc +++ b/src/platformheaders/cocoafunctions/qcocoawindowfunctions.qdoc @@ -26,12 +26,33 @@ ****************************************************************************/ /*! - \example mainwindows/recentfiles - \title Recent Files Example - \ingroup examples-mainwindow + \class QCocoaWindowFunctions + \inmodule QtPlatformHeaders - \brief The Recent Files example shows how a standard File menu can be extended to show - the most recent files loaded by a main window application. + \brief The QCocoaWindowFunctions class is an inline class containing + miscellaneous functionality for NSWindow and NSView window specific functionality. - \image recentfiles-example.png + \note There is no binary compatibility guarantee for this class, + meaning that an application using it is only guaranteed to work with the Qt + version it was developed against. +*/ + +/*! + \typedef QCocoaWindowFunctions::BottomLeftClippedByNSWindowOffset + + This is the typedef for the function returned by QGuiApplication::platformFunction when passed clippedByNSWindowIdentifier. +*/ + +/*! + \fn QByteArray QCocoaWindowFunctions::bottomLeftClippedByNSWindowOffsetIdentifier() + + This function returnes the bytearray that can be used to query + QGuiApplication::platformFunction to retrieve the BottomLeftClippedByNSWindowOffset function. +*/ + +/*! + \fn QPoint QCocoaWindowFunctions::bottomLeftClippedByNSWindowOffset(QWindow *window) + + This is a convenience function that can be used directly instead of resolving the function pointer. + \a window will be relayed to the function retrieved by QGuiApplication */ diff --git a/src/platformheaders/platformheaders.pro b/src/platformheaders/platformheaders.pro index 6b6294d34c01b195f054c036ce5bd67d72c6b709..1ced4f1c951f40f22d8b7ebbd793392e184cb884 100644 --- a/src/platformheaders/platformheaders.pro +++ b/src/platformheaders/platformheaders.pro @@ -8,6 +8,7 @@ include(xcbfunctions/xcbfunctions.pri) include(eglfsfunctions/eglfsfunctions.pri) include(windowsfunctions/windowsfunctions.pri) include(helper/helper.pri) +include(cocoafunctions/cocoafunctions.pri) QMAKE_DOCS = $$PWD/doc/qtplatformheaders.qdocconf diff --git a/src/platformsupport/dbusmenu/qdbusmenutypes.cpp b/src/platformsupport/dbusmenu/qdbusmenutypes.cpp index 73957eacfe7c9ff3f3c877ba53b4711825c8b3d4..94df0f53ddd83cad9fada4cbb519b790b72c688c 100644 --- a/src/platformsupport/dbusmenu/qdbusmenutypes.cpp +++ b/src/platformsupport/dbusmenu/qdbusmenutypes.cpp @@ -208,6 +208,7 @@ QDBusMenuItemList QDBusMenuItem::items(const QList<int> &ids, const QStringList Q_UNUSED(propertyNames) QDBusMenuItemList ret; QList<const QDBusPlatformMenuItem *> items = QDBusPlatformMenuItem::byIds(ids); + ret.reserve(items.size()); Q_FOREACH (const QDBusPlatformMenuItem *item, items) ret << QDBusMenuItem(item); return ret; diff --git a/src/platformsupport/dbusmenu/qdbusmenutypes_p.h b/src/platformsupport/dbusmenu/qdbusmenutypes_p.h index 28d16b32d5cfcf90cec9380761758b6c14920794..8dae75281c4d0af878b0971cbd4bd873d3f742fd 100644 --- a/src/platformsupport/dbusmenu/qdbusmenutypes_p.h +++ b/src/platformsupport/dbusmenu/qdbusmenutypes_p.h @@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE class QDBusPlatformMenu; class QDBusPlatformMenuItem; class QDBusMenuItem; -typedef QList<QDBusMenuItem> QDBusMenuItemList; +typedef QVector<QDBusMenuItem> QDBusMenuItemList; class QDBusMenuItem { @@ -61,6 +61,7 @@ public: int m_id; QVariantMap m_properties; }; +Q_DECLARE_TYPEINFO(QDBusMenuItem, Q_MOVABLE_TYPE); const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuItem &item); const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuItem &item); @@ -72,11 +73,12 @@ public: int id; QStringList properties; }; +Q_DECLARE_TYPEINFO(QDBusMenuItemKeys, Q_MOVABLE_TYPE); const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuItemKeys &keys); const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuItemKeys &keys); -typedef QList<QDBusMenuItemKeys> QDBusMenuItemKeysList; +typedef QVector<QDBusMenuItemKeys> QDBusMenuItemKeysList; class QDBusMenuLayoutItem { @@ -87,13 +89,14 @@ public: int m_id; QVariantMap m_properties; - QList<QDBusMenuLayoutItem> m_children; + QVector<QDBusMenuLayoutItem> m_children; }; +Q_DECLARE_TYPEINFO(QDBusMenuLayoutItem, Q_MOVABLE_TYPE); const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuLayoutItem &); const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuLayoutItem &item); -typedef QList<QDBusMenuLayoutItem> QDBusMenuLayoutItemList; +typedef QVector<QDBusMenuLayoutItem> QDBusMenuLayoutItemList; class QDBusMenuEvent { @@ -103,11 +106,13 @@ public: QDBusVariant m_data; uint m_timestamp; }; +Q_DECLARE_TYPEINFO(QDBusMenuEvent, Q_MOVABLE_TYPE); // QDBusVariant is movable, even though it cannot + // be marked as such until Qt 6. const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuEvent &ev); const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuEvent &ev); -typedef QList<QDBusMenuEvent> QDBusMenuEventList; +typedef QVector<QDBusMenuEvent> QDBusMenuEventList; #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const QDBusMenuItem &item); diff --git a/src/platformsupport/dbustray/qdbustraytypes.cpp b/src/platformsupport/dbustray/qdbustraytypes.cpp index 7b7d31b7c39bcc7f38cb34cdbecb3161f389d80a..83b5d5da3f1adf57bdcd5b756f751b2890df9d04 100644 --- a/src/platformsupport/dbustray/qdbustraytypes.cpp +++ b/src/platformsupport/dbustray/qdbustraytypes.cpp @@ -82,6 +82,8 @@ QXdgDBusImageVector iconToQXdgDBusImageVector(const QIcon &icon) sizes.append(QSize(IconNormalSmallSize * dpr, IconNormalSmallSize * dpr)); if (!hasMediumIcon) sizes.append(QSize(IconNormalMediumSize * dpr, IconNormalMediumSize * dpr)); + + ret.reserve(sizes.size()); foreach (QSize size, sizes) { // Protocol specifies ARGB32 format in network byte order QImage im = icon.pixmap(size).toImage().convertToFormat(QImage::Format_ARGB32); diff --git a/src/platformsupport/dbustray/qdbustraytypes_p.h b/src/platformsupport/dbustray/qdbustraytypes_p.h index 4e7ae70a96b12b949e56876ba5fc702891613133..e6f200362fff270fa2a2bd9568f889ad23f25b18 100644 --- a/src/platformsupport/dbustray/qdbustraytypes_p.h +++ b/src/platformsupport/dbustray/qdbustraytypes_p.h @@ -56,6 +56,7 @@ struct QXdgDBusImageStruct int height; QByteArray data; }; +Q_DECLARE_TYPEINFO(QXdgDBusImageStruct, Q_MOVABLE_TYPE); typedef QVector<QXdgDBusImageStruct> QXdgDBusImageVector; @@ -69,6 +70,7 @@ struct QXdgDBusToolTipStruct QString title; QString subTitle; }; +Q_DECLARE_TYPEINFO(QXdgDBusToolTipStruct, Q_MOVABLE_TYPE); const QDBusArgument &operator<<(QDBusArgument &argument, const QXdgDBusImageStruct &icon); const QDBusArgument &operator>>(const QDBusArgument &argument, QXdgDBusImageStruct &icon); diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri index d102203d5e5d10741bb2faf8456674a22134071a..457efd68fbc4e1e75513e00c0ca8709fc5bd0380 100644 --- a/src/platformsupport/eglconvenience/eglconvenience.pri +++ b/src/platformsupport/eglconvenience/eglconvenience.pri @@ -1,29 +1,16 @@ contains(QT_CONFIG,egl) { HEADERS += \ - $$PWD/qeglconvenience_p.h \ - $$PWD/qeglpbuffer_p.h + $$PWD/qeglconvenience_p.h SOURCES += \ - $$PWD/qeglconvenience.cpp \ - $$PWD/qeglpbuffer.cpp + $$PWD/qeglconvenience.cpp contains(QT_CONFIG,opengl) { - HEADERS += $$PWD/qeglplatformcontext_p.h - SOURCES += $$PWD/qeglplatformcontext.cpp + HEADERS += $$PWD/qeglplatformcontext_p.h \ + $$PWD/qeglpbuffer_p.h - unix { - HEADERS += \ - $$PWD/qeglplatformcursor_p.h \ - $$PWD/qeglplatformwindow_p.h \ - $$PWD/qeglplatformscreen_p.h \ - $$PWD/qeglplatformintegration_p.h - - SOURCES += \ - $$PWD/qeglplatformcursor.cpp \ - $$PWD/qeglplatformwindow.cpp \ - $$PWD/qeglplatformscreen.cpp \ - $$PWD/qeglplatformintegration.cpp - } + SOURCES += $$PWD/qeglplatformcontext.cpp \ + $$PWD/qeglpbuffer.cpp } # Avoid X11 header collision diff --git a/src/platformsupport/eglconvenience/qeglpbuffer.cpp b/src/platformsupport/eglconvenience/qeglpbuffer.cpp index 9cdf5a09317eb23d3e0c78338e159a3ca626e295..756609a641cb2bd6fc72b5a8d65ac059122ec414 100644 --- a/src/platformsupport/eglconvenience/qeglpbuffer.cpp +++ b/src/platformsupport/eglconvenience/qeglpbuffer.cpp @@ -55,7 +55,18 @@ QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffs , m_display(display) , m_pbuffer(EGL_NO_SURFACE) { - if (q_hasEglExtension(display, "EGL_KHR_surfaceless_context")) + bool hasSurfaceless = q_hasEglExtension(display, "EGL_KHR_surfaceless_context"); + + // Disable surfaceless contexts on Mesa for now. As of 10.6.0 and Intel at least, some + // operations (glReadPixels) are unable to work without a surface since they at some + // point temporarily unbind the current FBO and then later blow up in some seemingly + // safe operations, like setting the viewport, that apparently need access to the + // read/draw surface in the Intel backend. + const char *vendor = eglQueryString(display, EGL_VENDOR); // hard to check for GL_ strings here, so blacklist all Mesa + if (vendor && strstr(vendor, "Mesa")) + hasSurfaceless = false; + + if (hasSurfaceless) return; EGLConfig config = q_configFromGLFormat(m_display, m_format, false, EGL_PBUFFER_BIT); diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp index 6d9f9e4ae0e0ecd19de195d1af3c4b74f0b5d9c0..8929a038e0c930810757fb74f82971f45b716e78 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp @@ -154,6 +154,7 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont } } contextAttrs.append(EGL_NONE); + m_contextAttrs = contextAttrs; switch (m_format.renderableType()) { case QSurfaceFormat::OpenVG: @@ -243,6 +244,8 @@ void QEGLPlatformContext::initialize() updateFormatFromGL(); } +// Base implementation for pbuffers. Subclasses will handle the specialized cases for +// platforms without pbuffers. EGLSurface QEGLPlatformContext::createTemporaryOffscreenSurface() { // Make the context current to ensure the GL version query works. This needs a surface too. @@ -282,10 +285,18 @@ void QEGLPlatformContext::updateFormatFromGL() // avoid creating an extra pbuffer surface which is apparently troublesome with some // drivers (Mesa) when certain attributes are present (multisampling). EGLSurface tempSurface = EGL_NO_SURFACE; + EGLContext tempContext = EGL_NO_CONTEXT; if (!q_hasEglExtension(m_eglDisplay, "EGL_KHR_surfaceless_context")) tempSurface = createTemporaryOffscreenSurface(); - if (eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, m_eglContext)) { + EGLBoolean ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, m_eglContext); + if (!ok) { + EGLConfig config = q_configFromGLFormat(m_eglDisplay, m_format, false, EGL_PBUFFER_BIT); + tempContext = eglCreateContext(m_eglDisplay, config, 0, m_contextAttrs.constData()); + if (tempContext != EGL_NO_CONTEXT) + ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, tempContext); + } + if (ok) { if (m_format.renderableType() == QSurfaceFormat::OpenGL || m_format.renderableType() == QSurfaceFormat::OpenGLES) { const GLubyte *s = glGetString(GL_VERSION); @@ -323,10 +334,12 @@ void QEGLPlatformContext::updateFormatFromGL() } eglMakeCurrent(prevDisplay, prevSurfaceDraw, prevSurfaceRead, prevContext); } else { - qWarning("QEGLPlatformContext: Failed to make temporary surface current, format not updated"); + qWarning("QEGLPlatformContext: Failed to make temporary surface current, format not updated (%x)", eglGetError()); } if (tempSurface != EGL_NO_SURFACE) destroyTemporaryOffscreenSurface(tempSurface); + if (tempContext != EGL_NO_CONTEXT) + eglDestroyContext(m_eglDisplay, tempContext); #endif // QT_NO_OPENGL } diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h index 50c264e1dc6872d58268fa32773895639504b7a8..2ab7ad28d0ca52b95d4e634d858a538bf7896e6c 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h @@ -94,6 +94,7 @@ private: bool m_swapIntervalEnvChecked; int m_swapIntervalFromEnv; bool m_ownsContext; + QVector<EGLint> m_contextAttrs; }; QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp deleted file mode 100644 index 1868ff1665b111758914a45ac7670f452cb2dd4b..0000000000000000000000000000000000000000 --- a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtGui/QWindow> -#include <QtGui/QOpenGLContext> -#include <QtGui/QOffscreenSurface> -#include <QtGui/QGuiApplication> -#include <QtGui/private/qguiapplication_p.h> -#include <qpa/qwindowsysteminterface.h> -#include <qpa/qplatforminputcontextfactory_p.h> - -#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h> -#include <QtPlatformSupport/private/qgenericunixservices_p.h> -#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h> -#include <QtPlatformSupport/private/qfbvthandler_p.h> -#include <QtPlatformSupport/private/qopenglcompositorbackingstore_p.h> - -#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) -#include <QtPlatformSupport/private/qevdevmousemanager_p.h> -#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h> -#include <QtPlatformSupport/private/qevdevtouchmanager_p.h> -#endif - -#if !defined(QT_NO_TSLIB) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) -#include <QtPlatformSupport/private/qtslib_p.h> -#endif - -#include <QtPlatformHeaders/qeglfsfunctions.h> - -#include "qeglplatformintegration_p.h" -#include "qeglplatformcontext_p.h" -#include "qeglplatformwindow_p.h" -#include "qeglplatformscreen_p.h" -#include "qeglplatformcursor_p.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QEGLPlatformIntegration - \brief Base class for EGL-based QPlatformIntegration implementations. - \since 5.2 - \internal - \ingroup qpa - - This class provides most of the necessary platform integration for - an EGL-based Unix system. Platform plugins must subclass this and - reimplement the virtuals for creating platform screens and windows - since they will most likely wish to use a subclass for these. - - The backing store, native interface accessors, font database, - basic capability flags, etc. are provided out of the box, no - further customization is needed. - - \note It is critical that this class' implementation of - initialize() is called. Therefore subclasses should either avoid - to reimplement this function or call the base class - implementation. - */ - -QEGLPlatformIntegration::QEGLPlatformIntegration() - : m_display(EGL_NO_DISPLAY), - m_inputContext(0), - m_fontDb(new QGenericUnixFontDatabase), - m_services(new QGenericUnixServices), - m_kbdMgr(0) -{ -} - -QEGLPlatformIntegration::~QEGLPlatformIntegration() -{ -} - -void QEGLPlatformIntegration::initialize() -{ - m_display = eglGetDisplay(nativeDisplay()); - if (m_display == EGL_NO_DISPLAY) - qFatal("Could not open egl display"); - - EGLint major, minor; - if (!eglInitialize(m_display, &major, &minor)) - qFatal("Could not initialize egl display"); - - m_inputContext = QPlatformInputContextFactory::create(); - - m_vtHandler.reset(new QFbVtHandler); -} - -void QEGLPlatformIntegration::destroy() -{ - foreach (QWindow *w, qGuiApp->topLevelWindows()) - w->destroy(); - - if (m_display != EGL_NO_DISPLAY) - eglTerminate(m_display); -} - -QAbstractEventDispatcher *QEGLPlatformIntegration::createEventDispatcher() const -{ - return createUnixEventDispatcher(); -} - -QPlatformServices *QEGLPlatformIntegration::services() const -{ - return m_services.data(); -} - -QPlatformFontDatabase *QEGLPlatformIntegration::fontDatabase() const -{ - return m_fontDb.data(); -} - -QPlatformBackingStore *QEGLPlatformIntegration::createPlatformBackingStore(QWindow *window) const -{ - QOpenGLCompositorBackingStore *bs = new QOpenGLCompositorBackingStore(window); - if (!window->handle()) - window->create(); - static_cast<QEGLPlatformWindow *>(window->handle())->setBackingStore(bs); - return bs; -} - -QPlatformWindow *QEGLPlatformIntegration::createPlatformWindow(QWindow *window) const -{ - QWindowSystemInterface::flushWindowSystemEvents(); - QEGLPlatformWindow *w = createWindow(window); - w->create(); - if (window->type() != Qt::ToolTip) - w->requestActivateWindow(); - return w; -} - -QPlatformOpenGLContext *QEGLPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const -{ - // If there is a "root" window into which raster and QOpenGLWidget content is - // composited, all other contexts must share with its context. - QOpenGLContext *compositingContext = QOpenGLCompositor::instance()->context(); - QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle(); - QVariant nativeHandle = context->nativeHandle(); - QPlatformOpenGLContext *platformContext = createContext(context->format(), - share, - display(), - &nativeHandle); - context->setNativeHandle(nativeHandle); - return platformContext; -} - -QPlatformOffscreenSurface *QEGLPlatformIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const -{ - QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(surface->screen()->handle()); - return createOffscreenSurface(screen->display(), surface->requestedFormat(), surface); -} - -bool QEGLPlatformIntegration::hasCapability(QPlatformIntegration::Capability cap) const -{ - switch (cap) { - case ThreadedPixmaps: return true; - case OpenGL: return true; - case ThreadedOpenGL: return true; - case WindowManagement: return false; - case RasterGLSurface: return true; - default: return QPlatformIntegration::hasCapability(cap); - } -} - -QPlatformNativeInterface *QEGLPlatformIntegration::nativeInterface() const -{ - return const_cast<QEGLPlatformIntegration *>(this); -} - -enum ResourceType { - EglDisplay, - EglWindow, - EglContext, - EglConfig, - NativeDisplay, - XlibDisplay -}; - -static int resourceType(const QByteArray &key) -{ - static const QByteArray names[] = { // match ResourceType - QByteArrayLiteral("egldisplay"), - QByteArrayLiteral("eglwindow"), - QByteArrayLiteral("eglcontext"), - QByteArrayLiteral("eglconfig"), - QByteArrayLiteral("nativedisplay"), - QByteArrayLiteral("display") - }; - const QByteArray *end = names + sizeof(names) / sizeof(names[0]); - const QByteArray *result = std::find(names, end, key); - if (result == end) - result = std::find(names, end, key.toLower()); - return int(result - names); -} - -void *QEGLPlatformIntegration::nativeResourceForIntegration(const QByteArray &resource) -{ - void *result = 0; - - switch (resourceType(resource)) { - case EglDisplay: - result = display(); - break; - case NativeDisplay: - result = reinterpret_cast<void*>(nativeDisplay()); - break; - default: - break; - } - - return result; -} - -void *QEGLPlatformIntegration::nativeResourceForScreen(const QByteArray &resource, QScreen *) -{ - void *result = 0; - - switch (resourceType(resource)) { - case XlibDisplay: - // Play nice when using the x11 hooks: Be compatible with xcb that allows querying - // the X Display pointer, which is nothing but our native display. - result = reinterpret_cast<void*>(nativeDisplay()); - break; - default: - break; - } - - return result; -} - -void *QEGLPlatformIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window) -{ - void *result = 0; - - switch (resourceType(resource)) { - case EglDisplay: - if (window && window->handle()) - result = static_cast<QEGLPlatformScreen *>(window->handle()->screen())->display(); - else - result = display(); - break; - case EglWindow: - if (window && window->handle()) - result = reinterpret_cast<void*>(static_cast<QEGLPlatformWindow *>(window->handle())->eglWindow()); - break; - default: - break; - } - - return result; -} - -void *QEGLPlatformIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) -{ - void *result = 0; - - switch (resourceType(resource)) { - case EglContext: - if (context->handle()) - result = static_cast<QEGLPlatformContext *>(context->handle())->eglContext(); - break; - case EglConfig: - if (context->handle()) - result = static_cast<QEGLPlatformContext *>(context->handle())->eglConfig(); - break; - case EglDisplay: - if (context->handle()) - result = static_cast<QEGLPlatformContext *>(context->handle())->eglDisplay(); - break; - default: - break; - } - - return result; -} - -static void *eglContextForContext(QOpenGLContext *context) -{ - Q_ASSERT(context); - - QEGLPlatformContext *handle = static_cast<QEGLPlatformContext *>(context->handle()); - if (!handle) - return 0; - - return handle->eglContext(); -} - -QPlatformNativeInterface::NativeResourceForContextFunction QEGLPlatformIntegration::nativeResourceFunctionForContext(const QByteArray &resource) -{ - QByteArray lowerCaseResource = resource.toLower(); - if (lowerCaseResource == "get_egl_context") - return NativeResourceForContextFunction(eglContextForContext); - - return 0; -} - -QFunctionPointer QEGLPlatformIntegration::platformFunction(const QByteArray &function) const -{ -#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) - if (function == QEglFSFunctions::loadKeymapTypeIdentifier()) - return QFunctionPointer(loadKeymapStatic); -#else - Q_UNUSED(function) -#endif - - return 0; -} - -void QEGLPlatformIntegration::loadKeymapStatic(const QString &filename) -{ -#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) - QEGLPlatformIntegration *self = static_cast<QEGLPlatformIntegration *>(QGuiApplicationPrivate::platformIntegration()); - if (self->m_kbdMgr) - self->m_kbdMgr->loadKeymap(filename); - else - qWarning("QEGLPlatformIntegration: Cannot load keymap, no keyboard handler found"); -#else - Q_UNUSED(filename); -#endif -} - -void QEGLPlatformIntegration::createInputHandlers() -{ -#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) - m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this); - new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this); -#ifndef QT_NO_TSLIB - const bool useTslib = qEnvironmentVariableIntValue("QT_QPA_EGLFS_TSLIB"); - if (useTslib) - new QTsLibMouseHandler(QLatin1String("TsLib"), QString() /* spec */); - else -#endif // QT_NO_TSLIB - new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this); -#endif -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h deleted file mode 100644 index 42fbf8c8a167fecd9534ce388c20710fe8947573..0000000000000000000000000000000000000000 --- a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEGLPLATFORMINTEGRATION_H -#define QEGLPLATFORMINTEGRATION_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/QVariant> -#include <qpa/qplatformintegration.h> -#include <qpa/qplatformnativeinterface.h> -#include <EGL/egl.h> - -QT_BEGIN_NAMESPACE - -class QEGLPlatformWindow; -class QEGLPlatformContext; -class QFbVtHandler; -class QEvdevKeyboardManager; - -class QEGLPlatformIntegration : public QPlatformIntegration, public QPlatformNativeInterface -{ -public: - QEGLPlatformIntegration(); - ~QEGLPlatformIntegration(); - - void initialize() Q_DECL_OVERRIDE; - void destroy() Q_DECL_OVERRIDE; - - EGLDisplay display() const { return m_display; } - - QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; - QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; - QPlatformServices *services() const Q_DECL_OVERRIDE; - QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; } - - QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; - QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE; - QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE; - - bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; - - QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; - // QPlatformNativeInterface - void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE; - void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) Q_DECL_OVERRIDE; - void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE; - void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE; - NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE; - - QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE; - - QFbVtHandler *vtHandler() { return m_vtHandler.data(); } - -protected: - virtual QEGLPlatformWindow *createWindow(QWindow *window) const = 0; - virtual QEGLPlatformContext *createContext(const QSurfaceFormat &format, - QPlatformOpenGLContext *shareContext, - EGLDisplay display, - QVariant *nativeHandle) const = 0; - virtual QPlatformOffscreenSurface *createOffscreenSurface(EGLDisplay display, - const QSurfaceFormat &format, - QOffscreenSurface *surface) const = 0; - - virtual EGLNativeDisplayType nativeDisplay() const { return EGL_DEFAULT_DISPLAY; } - - void createInputHandlers(); - -private: - static void loadKeymapStatic(const QString &filename); - - EGLDisplay m_display; - QPlatformInputContext *m_inputContext; - QScopedPointer<QPlatformFontDatabase> m_fontDb; - QScopedPointer<QPlatformServices> m_services; - QScopedPointer<QFbVtHandler> m_vtHandler; - QEvdevKeyboardManager *m_kbdMgr; -}; - -QT_END_NAMESPACE - -#endif // QEGLPLATFORMINTEGRATION_H diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp deleted file mode 100644 index 61f8cdd9b41d9e57d9f43f3e88f951b722cf4ab7..0000000000000000000000000000000000000000 --- a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglplatformscreen_p.h" -#include "qeglplatformwindow_p.h" -#include <QtGui/qwindow.h> -#include <qpa/qwindowsysteminterface.h> -#include <QtPlatformSupport/private/qopenglcompositor_p.h> - -QT_BEGIN_NAMESPACE - -/*! - \class QEGLPlatformScreen - \brief Base class for EGL-based platform screen implementations. - \since 5.2 - \internal - \ingroup qpa - */ - -QEGLPlatformScreen::QEGLPlatformScreen(EGLDisplay dpy) - : m_dpy(dpy), - m_pointerWindow(0) -{ -} - -QEGLPlatformScreen::~QEGLPlatformScreen() -{ - QOpenGLCompositor::destroy(); -} - -void QEGLPlatformScreen::handleCursorMove(const QPoint &pos) -{ - const QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); - const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); - - // Generate enter and leave events like a real windowing system would do. - if (windows.isEmpty()) - return; - - // First window is always fullscreen. - if (windows.count() == 1) { - QWindow *window = windows[0]->sourceWindow(); - if (m_pointerWindow != window) { - m_pointerWindow = window; - QWindowSystemInterface::handleEnterEvent(window, window->mapFromGlobal(pos), pos); - } - return; - } - - QWindow *enter = 0, *leave = 0; - for (int i = windows.count() - 1; i >= 0; --i) { - QWindow *window = windows[i]->sourceWindow(); - const QRect geom = window->geometry(); - if (geom.contains(pos)) { - if (m_pointerWindow != window) { - leave = m_pointerWindow; - m_pointerWindow = window; - enter = window; - } - break; - } - } - - if (enter && leave) - QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos); -} - -QPixmap QEGLPlatformScreen::grabWindow(WId wid, int x, int y, int width, int height) const -{ - QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); - const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); - Q_ASSERT(!windows.isEmpty()); - - QImage img; - - if (static_cast<QEGLPlatformWindow *>(windows.first()->sourceWindow()->handle())->isRaster()) { - // Request the compositor to render everything into an FBO and read it back. This - // is of course slow, but it's safe and reliable. It will not include the mouse - // cursor, which is a plus. - img = compositor->grab(); - } else { - // Just a single OpenGL window without compositing. Do not support this case for now. Doing - // glReadPixels is not an option since it would read from the back buffer which may have - // undefined content when calling right after a swapBuffers (unless preserved swap is - // available and enabled, but we have no support for that). - qWarning("grabWindow: Not supported for non-composited OpenGL content. Use QQuickWindow::grabWindow() instead."); - return QPixmap(); - } - - if (!wid) { - const QSize screenSize = geometry().size(); - if (width < 0) - width = screenSize.width() - x; - if (height < 0) - height = screenSize.height() - y; - return QPixmap::fromImage(img).copy(x, y, width, height); - } - - foreach (QOpenGLCompositorWindow *w, windows) { - const QWindow *window = w->sourceWindow(); - if (window->winId() == wid) { - const QRect geom = window->geometry(); - if (width < 0) - width = geom.width() - x; - if (height < 0) - height = geom.height() - y; - QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height)); - rect &= window->geometry(); - return QPixmap::fromImage(img).copy(rect); - } - } - - return QPixmap(); -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp deleted file mode 100644 index 35f38ac29a0aeeb6a97b9737e76d1c41ecaeb9e6..0000000000000000000000000000000000000000 --- a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qpa/qwindowsysteminterface.h> -#include <QtPlatformSupport/private/qopenglcompositor_p.h> -#include <QtPlatformSupport/private/qopenglcompositorbackingstore_p.h> - -#include "qeglplatformwindow_p.h" -#include "qeglplatformscreen_p.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QEGLPlatformWindow - \brief Base class for EGL-based platform window implementations. - \since 5.2 - \internal - \ingroup qpa - - Lightweight class providing some basic platform window operations - and interfacing with QOpenGLCompositorBackingStore. - - Almost no QPlatformWindow functions are implemented here. This is - intentional because different platform plugins may use different - strategies for their window management (some may force fullscreen - windows, some may not, some may share the underlying native - surface, some may not, etc.) and therefore it is not sensible to - enforce anything for these functions. - - \note Subclasses are responsible for invoking this class' - implementation of create() and are expected to utilize the window - stack management functions (addWindow() etc.) in - QOpenGLCompositor. - */ - -QEGLPlatformWindow::QEGLPlatformWindow(QWindow *w) - : QPlatformWindow(w), - m_backingStore(0), - m_raster(false), - m_winId(0) -{ -} - -static WId newWId() -{ - static WId id = 0; - - if (id == std::numeric_limits<WId>::max()) - qWarning("QEGLPlatformWindow: Out of window IDs"); - - return ++id; -} - -void QEGLPlatformWindow::create() -{ - m_winId = newWId(); - - // Save the original surface type before changing to OpenGLSurface. - m_raster = (window()->surfaceType() == QSurface::RasterSurface); - if (m_raster) // change to OpenGL, but not for RasterGLSurface - window()->setSurfaceType(QSurface::OpenGLSurface); - - if (window()->type() == Qt::Desktop) { - QRect fullscreenRect(QPoint(), screen()->availableGeometry().size()); - QPlatformWindow::setGeometry(fullscreenRect); - QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect); - return; - } -} - -bool QEGLPlatformWindow::isRaster() const -{ - return m_raster || window()->surfaceType() == QSurface::RasterGLSurface; -} - -QWindow *QEGLPlatformWindow::sourceWindow() const -{ - return window(); -} - -const QPlatformTextureList *QEGLPlatformWindow::textures() const -{ - if (m_backingStore) - return m_backingStore->textures(); - - return 0; -} - -void QEGLPlatformWindow::endCompositing() -{ - if (m_backingStore) - m_backingStore->notifyComposited(); -} - -WId QEGLPlatformWindow::winId() const -{ - return m_winId; -} - -void QEGLPlatformWindow::setOpacity(qreal) -{ - if (!isRaster()) - qWarning("QEGLPlatformWindow: Cannot set opacity for non-raster windows"); - - // Nothing to do here. The opacity is stored in the QWindow. -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp index 566f84c9ea2f6f0c1ec73dcca1925d107073a293..d00954375d526e09c92b0269b5683f5ae05131a0 100644 --- a/src/platformsupport/fbconvenience/qfbscreen.cpp +++ b/src/platformsupport/fbconvenience/qfbscreen.cpp @@ -206,10 +206,11 @@ void QFbScreen::generateRects() } #endif } - foreach (const QRect &rect, remainingScreen.rects()) + const QVector<QRect> remainingScreenRects = remainingScreen.rects(); + mCachedRects.reserve(mCachedRects.count() + remainingScreenRects.count()); + foreach (const QRect &rect, remainingScreenRects) mCachedRects += QPair<QRect, int>(rect, -1); mIsUpToDate = true; - return; } QRegion QFbScreen::doRedraw() diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index 112bb8e0a638dcb26ea11c963e7ea45d88a56f78..022bc8bec21edb3ed51e931f12d048750989fe57 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -44,6 +44,7 @@ #include <QtGui/private/qfontengine_ft_p.h> #include <QtGui/private/qguiapplication_p.h> +#include <QtGui/private/qhighdpiscaling_p.h> #include <QtGui/qguiapplication.h> @@ -553,10 +554,8 @@ QFontEngine::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintin break; } - if (QGuiApplication::platformNativeInterface()->nativeResourceForScreen("nofonthinting", - QGuiApplication::primaryScreen())) { + if (QHighDpiScaling::isActive()) return QFontEngine::HintNone; - } int hint_style = 0; if (FcPatternGetInteger (match, FC_HINT_STYLE, 0, &hint_style) == FcResultMatch) { diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h index 822d6f9b9c0ab021807c4fce82fc766660e07cc9..a423ed5ae282510298c2af4ac8d4ce1497feb0db 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h @@ -75,18 +75,18 @@ class QCoreTextFontDatabase : public QPlatformFontDatabase public: QCoreTextFontDatabase(); ~QCoreTextFontDatabase(); - void populateFontDatabase(); + void populateFontDatabase() Q_DECL_OVERRIDE; void populateFamily(const QString &familyName) Q_DECL_OVERRIDE; - QFontEngine *fontEngine(const QFontDef &fontDef, void *handle); - QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); - QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const; - QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName); - void releaseHandle(void *handle); - bool isPrivateFontFamily(const QString &family) const; - QFont defaultFont() const; + QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE; + QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) Q_DECL_OVERRIDE; + QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const Q_DECL_OVERRIDE; + QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) Q_DECL_OVERRIDE; + void releaseHandle(void *handle) Q_DECL_OVERRIDE; + bool isPrivateFontFamily(const QString &family) const Q_DECL_OVERRIDE; + QFont defaultFont() const Q_DECL_OVERRIDE; bool fontsAlwaysScalable() const Q_DECL_OVERRIDE; - QList<int> standardSizes() const; + QList<int> standardSizes() const Q_DECL_OVERRIDE; // For iOS and OS X platform themes QFont *themeFont(QPlatformTheme::Font) const; diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index 88ce2c726dfe719fd5b17c5377f1a0fb37e9baf9..f8ec1d326fbe0c43299d61255e98c16a56b6e5c6 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -64,48 +64,48 @@ public: QCoreTextFontEngine(CGFontRef font, const QFontDef &def); ~QCoreTextFontEngine(); - virtual glyph_t glyphIndex(uint ucs4) const; - virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const; - virtual void recalcAdvances(QGlyphLayout *, ShaperFlags) const; + glyph_t glyphIndex(uint ucs4) const Q_DECL_OVERRIDE; + bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const Q_DECL_OVERRIDE; + void recalcAdvances(QGlyphLayout *, ShaperFlags) const Q_DECL_OVERRIDE; - virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); - virtual glyph_metrics_t boundingBox(glyph_t glyph); + glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) Q_DECL_OVERRIDE; + glyph_metrics_t boundingBox(glyph_t glyph) Q_DECL_OVERRIDE; - virtual QFixed ascent() const; - virtual QFixed descent() const; - virtual QFixed leading() const; - virtual QFixed xHeight() const; - virtual qreal maxCharWidth() const; - virtual QFixed averageCharWidth() const; + QFixed ascent() const Q_DECL_OVERRIDE; + QFixed descent() const Q_DECL_OVERRIDE; + QFixed leading() const Q_DECL_OVERRIDE; + QFixed xHeight() const Q_DECL_OVERRIDE; + qreal maxCharWidth() const Q_DECL_OVERRIDE; + QFixed averageCharWidth() const Q_DECL_OVERRIDE; - virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, - QPainterPath *path, QTextItem::RenderFlags); + void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, + QPainterPath *path, QTextItem::RenderFlags) Q_DECL_OVERRIDE; - virtual bool canRender(const QChar *string, int len) const; + bool canRender(const QChar *string, int len) const Q_DECL_OVERRIDE; - virtual int synthesized() const { return synthesisFlags; } - virtual bool supportsSubPixelPositions() const { return true; } + int synthesized() const Q_DECL_OVERRIDE { return synthesisFlags; } + bool supportsSubPixelPositions() const Q_DECL_OVERRIDE { return true; } void draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight); - virtual FaceId faceId() const; - virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const; - virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); - virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition); - virtual QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t); - virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); - glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat); - virtual QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); - virtual qreal minRightBearing() const; - virtual qreal minLeftBearing() const; - virtual QFixed emSquareSize() const; + FaceId faceId() const Q_DECL_OVERRIDE; + bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const Q_DECL_OVERRIDE; + void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) Q_DECL_OVERRIDE; + QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition) Q_DECL_OVERRIDE; + QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) Q_DECL_OVERRIDE; + QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) Q_DECL_OVERRIDE; + glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat) Q_DECL_OVERRIDE; + QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) Q_DECL_OVERRIDE; + qreal minRightBearing() const Q_DECL_OVERRIDE; + qreal minLeftBearing() const Q_DECL_OVERRIDE; + QFixed emSquareSize() const Q_DECL_OVERRIDE; - bool supportsTransformation(const QTransform &transform) const; + bool supportsTransformation(const QTransform &transform) const Q_DECL_OVERRIDE; - virtual QFontEngine *cloneWithSize(qreal pixelSize) const; - virtual int glyphMargin(QFontEngine::GlyphFormat format) { Q_UNUSED(format); return 0; } + QFontEngine *cloneWithSize(qreal pixelSize) const Q_DECL_OVERRIDE; + int glyphMargin(QFontEngine::GlyphFormat format) Q_DECL_OVERRIDE { Q_UNUSED(format); return 0; } - virtual QFontEngine::Properties properties() const; + QFontEngine::Properties properties() const Q_DECL_OVERRIDE; static bool supportsColorGlyphs() { diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp index 16cb94dded4603c81b065051d2309bb223e574f3..06751de0ef763cf4c140c14598f083a16e00767e 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp @@ -379,17 +379,20 @@ QEvdevKeyboardHandler::KeycodeAction QEvdevKeyboardHandler::processKeycode(quint } if (!skip) { - qCDebug(qLcEvdevKeyMap, "Processing: uni=%04x, qt=%08x, qtmod=%08x", unicode, qtcode & ~modmask, (qtcode & modmask)); - //If NumLockOff and keypad key pressed remap event sent - if (!m_locks[1] && - (qtcode & Qt::KeypadModifier) && + // Up until now qtcode contained both the key and modifiers. Split it. + Qt::KeyboardModifiers qtmods = Qt::KeyboardModifiers(qtcode & modmask); + qtcode &= ~modmask; + + qCDebug(qLcEvdevKeyMap, "Processing: uni=%04x, qt=%08x, qtmod=%08x", unicode, qtcode, int(qtmods)); + + // If NumLockOff and keypad key pressed remap event sent + if (!m_locks[1] && (qtmods & Qt::KeypadModifier) && keycode >= 71 && keycode <= 83 && keycode != 74 && keycode != 78) { unicode = 0xffff; - int oldMask = (qtcode & modmask); switch (keycode) { case 71: //7 --> Home qtcode = Qt::Key_Home; @@ -425,11 +428,14 @@ QEvdevKeyboardHandler::KeycodeAction QEvdevKeyboardHandler::processKeycode(quint qtcode = Qt::Key_Delete; break; } - qtcode ^= oldMask; } - // send the result to the server - processKeyEvent(keycode, unicode, qtcode & ~modmask, Qt::KeyboardModifiers(qtcode & modmask), pressed, autorepeat); + // Map SHIFT + Tab to SHIFT + Backtab, QShortcutMap knows about this translation + if (qtcode == Qt::Key_Tab && (qtmods & Qt::ShiftModifier) == Qt::ShiftModifier) + qtcode = Qt::Key_Backtab; + + // Generate the QPA event. + processKeyEvent(keycode, unicode, qtcode, qtmods, pressed, autorepeat); } } return result; diff --git a/src/platformsupport/input/evdevtablet/qevdevtablet.cpp b/src/platformsupport/input/evdevtablet/qevdevtablet.cpp index c59f0f390aa40f9be0560a9234455a611a8d88db..c6f952c64d93bd08edb9f85b4983b1161053c3e0 100644 --- a/src/platformsupport/input/evdevtablet/qevdevtablet.cpp +++ b/src/platformsupport/input/evdevtablet/qevdevtablet.cpp @@ -292,7 +292,7 @@ void QEvdevTabletHandler::readData() QEvdevTabletHandlerThread::QEvdevTabletHandlerThread(const QString &spec, QObject *parent) - : QThread(parent), m_spec(spec), m_handler(0) + : QDaemonThread(parent), m_spec(spec), m_handler(0) { start(); } diff --git a/src/platformsupport/input/evdevtablet/qevdevtablet_p.h b/src/platformsupport/input/evdevtablet/qevdevtablet_p.h index f9682290d94a5c7ace6ac3cfc3abe94ed7297c06..f546f9a88ae47eef71f46f4e3e2438ec0dbee612 100644 --- a/src/platformsupport/input/evdevtablet/qevdevtablet_p.h +++ b/src/platformsupport/input/evdevtablet/qevdevtablet_p.h @@ -48,6 +48,7 @@ #include <QObject> #include <QString> #include <QThread> +#include <QtCore/private/qthread_p.h> QT_BEGIN_NAMESPACE @@ -68,7 +69,7 @@ private: QEvdevTabletData *d; }; -class QEvdevTabletHandlerThread : public QThread +class QEvdevTabletHandlerThread : public QDaemonThread { public: explicit QEvdevTabletHandlerThread(const QString &spec, QObject *parent = 0); diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp index 885326e5128031731f24ca9ed4c877b117012a59..1ca95074b9a25223c3423bd0ebe7602e860a4c95 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp @@ -418,11 +418,11 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data) m_currentData.y = qBound(hw_range_y_min, data->value, hw_range_y_max); if (m_singleTouch) m_contacts[m_currentSlot].y = m_currentData.y; - if (m_typeB) { - m_contacts[m_currentSlot].y = m_currentData.y; - if (m_contacts[m_currentSlot].state == Qt::TouchPointStationary) - m_contacts[m_currentSlot].state = Qt::TouchPointMoved; - } + if (m_typeB) { + m_contacts[m_currentSlot].y = m_currentData.y; + if (m_contacts[m_currentSlot].state == Qt::TouchPointStationary) + m_contacts[m_currentSlot].state = Qt::TouchPointMoved; + } } else if (data->code == ABS_MT_TRACKING_ID) { m_currentData.trackingId = data->value; if (m_typeB) { @@ -642,7 +642,7 @@ void QEvdevTouchScreenData::reportPoints() QEvdevTouchScreenHandlerThread::QEvdevTouchScreenHandlerThread(const QString &device, const QString &spec, QObject *parent) - : QThread(parent), m_device(device), m_spec(spec), m_handler(0) + : QDaemonThread(parent), m_device(device), m_spec(spec), m_handler(0) { start(); } diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h b/src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h index a6d3a860f50c049476a6c2e49bb8012fcbd1eb7f..8e7dfe59bbd70f17c282adbd4e84513a3885a7b2 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h +++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h @@ -49,6 +49,7 @@ #include <QString> #include <QList> #include <QThread> +#include <QtCore/private/qthread_p.h> #include <qpa/qwindowsysteminterface.h> #if !defined(QT_NO_MTDEV) @@ -80,7 +81,7 @@ private: #endif }; -class QEvdevTouchScreenHandlerThread : public QThread +class QEvdevTouchScreenHandlerThread : public QDaemonThread { public: explicit QEvdevTouchScreenHandlerThread(const QString &device, const QString &spec, QObject *parent = 0); diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp index c040dab5e19a9b6de5c3e849b4468981094dbdbc..d155cecd891df96ed73dcf432587b37a3f4a2d74 100644 --- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp +++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp @@ -1431,7 +1431,9 @@ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QS QSpiObjectReference(connection, QDBusObjectPath(QSPI_OBJECT_PATH_ROOT)))); } else if (function == QLatin1String("GetChildren")) { QSpiObjectReferenceArray children; - for (int i = 0; i < interface->childCount(); ++i) { + const int numChildren = interface->childCount(); + children.reserve(numChildren); + for (int i = 0; i < numChildren; ++i) { QString childPath = pathForInterface(interface->child(i)); QSpiObjectReference ref(connection, QDBusObjectPath(childPath)); children << ref; @@ -1507,7 +1509,7 @@ QSpiRelationArray AtSpiAdaptor::relationSet(QAccessibleInterface *interface, con Q_FOREACH (const RelationPair &pair, relationInterfaces) { // FIXME: this loop seems a bit strange... "related" always have one item when we check. //And why is it a list, when it always have one item? And it seems to assume that the QAccessible::Relation enum maps directly to AtSpi - QList<QSpiObjectReference> related; + QSpiObjectReferenceArray related; QDBusObjectPath path = QDBusObjectPath(pathForInterface(pair.first)); related.append(QSpiObjectReference(connection, path)); @@ -1747,7 +1749,9 @@ QSpiActionArray AtSpiAdaptor::getActions(QAccessibleInterface *interface) const { QAccessibleActionInterface *actionInterface = interface->actionInterface(); QSpiActionArray actions; - Q_FOREACH (const QString &actionName, QAccessibleBridgeUtils::effectiveActionNames(interface)) { + const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface); + actions.reserve(actionNames.size()); + Q_FOREACH (const QString &actionName, actionNames) { QSpiAction action; QStringList keyBindings; diff --git a/src/platformsupport/linuxaccessibility/cache.cpp b/src/platformsupport/linuxaccessibility/cache.cpp index 2ece905fdfc644e0182d8c3a893c2da9e7a58816..0ccd2cba6ec04ae71fcc67e02f28a4f576c5a32d 100644 --- a/src/platformsupport/linuxaccessibility/cache.cpp +++ b/src/platformsupport/linuxaccessibility/cache.cpp @@ -78,8 +78,7 @@ void QSpiDBusCache::emitRemoveAccessible(const QSpiObjectReference& item) QSpiAccessibleCacheArray QSpiDBusCache::GetItems() { - QList <QSpiAccessibleCacheItem> cacheArray; - return cacheArray; + return QSpiAccessibleCacheArray(); } QT_END_NAMESPACE diff --git a/src/platformsupport/linuxaccessibility/struct_marshallers_p.h b/src/platformsupport/linuxaccessibility/struct_marshallers_p.h index 7788ceb7ccc9a242a7c6943e5eb61aad4dd180bd..61d79e6daa08c7ba82018c5a30955f1ceb97244c 100644 --- a/src/platformsupport/linuxaccessibility/struct_marshallers_p.h +++ b/src/platformsupport/linuxaccessibility/struct_marshallers_p.h @@ -46,7 +46,7 @@ // We mean it. // -#include <QtCore/qlist.h> +#include <QtCore/qvector.h> #include <QtCore/qpair.h> #include <QtDBus/QDBusArgument> #include <QtDBus/QDBusConnection> @@ -55,8 +55,8 @@ #ifndef QT_NO_ACCESSIBILITY QT_BEGIN_NAMESPACE -typedef QList <int> QSpiIntList; -typedef QList <uint> QSpiUIntList; +typedef QVector<int> QSpiIntList; +typedef QVector<uint> QSpiUIntList; // FIXME: make this copy on write struct QSpiObjectReference @@ -68,26 +68,29 @@ struct QSpiObjectReference QSpiObjectReference(const QDBusConnection& connection, const QDBusObjectPath& path) : service(connection.baseService()), path(path) {} }; +Q_DECLARE_TYPEINFO(QSpiObjectReference, Q_MOVABLE_TYPE); // QDBusObjectPath is movable, even though it + // cannot be marked that way until Qt 6 QDBusArgument &operator<<(QDBusArgument &argument, const QSpiObjectReference &address); const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiObjectReference &address); -typedef QList <QSpiObjectReference> QSpiObjectReferenceArray; +typedef QVector<QSpiObjectReference> QSpiObjectReferenceArray; struct QSpiAccessibleCacheItem { QSpiObjectReference path; QSpiObjectReference application; QSpiObjectReference parent; - QList <QSpiObjectReference> children; + QSpiObjectReferenceArray children; QStringList supportedInterfaces; QString name; uint role; QString description; QSpiUIntList state; }; +Q_DECLARE_TYPEINFO(QSpiAccessibleCacheItem, Q_MOVABLE_TYPE); -typedef QList <QSpiAccessibleCacheItem> QSpiAccessibleCacheArray; +typedef QVector<QSpiAccessibleCacheItem> QSpiAccessibleCacheArray; QDBusArgument &operator<<(QDBusArgument &argument, const QSpiAccessibleCacheItem &item); const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiAccessibleCacheItem &item); @@ -98,8 +101,9 @@ struct QSpiAction QString description; QString keyBinding; }; +Q_DECLARE_TYPEINFO(QSpiAction, Q_MOVABLE_TYPE); -typedef QList <QSpiAction> QSpiActionArray; +typedef QVector<QSpiAction> QSpiActionArray; QDBusArgument &operator<<(QDBusArgument &argument, const QSpiAction &action); const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiAction &action); @@ -109,14 +113,15 @@ struct QSpiEventListener QString listenerAddress; QString eventName; }; +Q_DECLARE_TYPEINFO(QSpiEventListener, Q_MOVABLE_TYPE); -typedef QList <QSpiEventListener> QSpiEventListenerArray; +typedef QVector<QSpiEventListener> QSpiEventListenerArray; QDBusArgument &operator<<(QDBusArgument &argument, const QSpiEventListener &action); const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiEventListener &action); -typedef QPair < unsigned int, QList < QSpiObjectReference > > QSpiRelationArrayEntry; -typedef QList< QSpiRelationArrayEntry > QSpiRelationArray; +typedef QPair<unsigned int, QSpiObjectReferenceArray> QSpiRelationArrayEntry; +typedef QVector<QSpiRelationArrayEntry> QSpiRelationArray; //a(iisv) struct QSpiTextRange { @@ -125,18 +130,22 @@ struct QSpiTextRange { QString contents; QVariant v; }; -typedef QList <QSpiTextRange> QSpiTextRangeList; +Q_DECLARE_TYPEINFO(QSpiTextRange, Q_MOVABLE_TYPE); + +typedef QVector<QSpiTextRange> QSpiTextRangeList; typedef QMap <QString, QString> QSpiAttributeSet; enum QSpiAppUpdateType { QSPI_APP_UPDATE_ADDED = 0, QSPI_APP_UPDATE_REMOVED = 1 }; +Q_DECLARE_TYPEINFO(QSpiAppUpdateType, Q_PRIMITIVE_TYPE); struct QSpiAppUpdate { int type; /* Is an application added or removed */ QString address; /* D-Bus address of application added or removed */ }; +Q_DECLARE_TYPEINFO(QSpiAppUpdate, Q_MOVABLE_TYPE); QDBusArgument &operator<<(QDBusArgument &argument, const QSpiAppUpdate &update); const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiAppUpdate &update); @@ -150,6 +159,7 @@ struct QSpiDeviceEvent { QString text; bool isText; }; +Q_DECLARE_TYPEINFO(QSpiDeviceEvent, Q_MOVABLE_TYPE); QDBusArgument &operator<<(QDBusArgument &argument, const QSpiDeviceEvent &event); const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiDeviceEvent &event); diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp index ba328bfb411d28a6628e91d0c8cdc19ac5a25788..2e17c3f63c52ccb3441a328f32c524f5b72d9995 100644 --- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp +++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp @@ -678,7 +678,7 @@ QPlatformTheme *QGenericUnixTheme::createUnixTheme(const QString &name) #endif if (name == QLatin1String(QGnomeTheme::name)) return new QGnomeTheme; - return new QGenericUnixTheme; + return Q_NULLPTR; } QStringList QGenericUnixTheme::themeNames() @@ -710,8 +710,7 @@ QStringList QGenericUnixTheme::themeNames() if (!session.isEmpty() && session != QLatin1String("default") && !result.contains(session)) result.push_back(session); } // desktopSettingsAware - if (result.isEmpty()) - result.push_back(QLatin1String(QGenericUnixTheme::name)); + result.append(QLatin1String(QGenericUnixTheme::name)); return result; } diff --git a/src/plugins/bearer/bearer.pro b/src/plugins/bearer/bearer.pro index 7637bf1f5e29935f0b7a214545ea501c846fca57..2239d527379ca6b61059221f599ee465f2f0a0e2 100644 --- a/src/plugins/bearer/bearer.pro +++ b/src/plugins/bearer/bearer.pro @@ -8,7 +8,7 @@ TEMPLATE = subdirs #win32:SUBDIRS += nla win32:SUBDIRS += generic blackberry:SUBDIRS += blackberry -win32:!wince*:SUBDIRS += nativewifi +win32:!wince: SUBDIRS += nativewifi mac:contains(QT_CONFIG, corewlan):SUBDIRS += corewlan mac:SUBDIRS += generic android:!android-no-sdk:SUBDIRS += android diff --git a/src/plugins/bearer/connman/main.cpp b/src/plugins/bearer/connman/main.cpp index a84121e89b507da8d975700848fc8fcaee55eaef..f1e9d763a71eab7acd746e4a5c7f2fea5bcaff60 100644 --- a/src/plugins/bearer/connman/main.cpp +++ b/src/plugins/bearer/connman/main.cpp @@ -36,7 +36,6 @@ #include <QtCore/qdebug.h> -#ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE @@ -78,4 +77,3 @@ QT_END_NAMESPACE #include "main.moc" #endif -#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp index 7911857ff5bdc927914b16edb4faad05db77b8ff..b7cc5f949c1f1689df1cca200e296d434bdc9003 100644 --- a/src/plugins/bearer/connman/qconnmanengine.cpp +++ b/src/plugins/bearer/connman/qconnmanengine.cpp @@ -46,7 +46,6 @@ #include <QtDBus/QDBusInterface> #include <QtDBus/QDBusMessage> #include <QtDBus/QDBusReply> -#ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE @@ -122,8 +121,10 @@ QList<QNetworkConfigurationPrivate *> QConnmanEngine::getConfigurations() QMutexLocker locker(&mutex); QList<QNetworkConfigurationPrivate *> fetchedConfigurations; QNetworkConfigurationPrivate* cpPriv = 0; + const int numFoundConfigurations = foundConfigurations.count(); + fetchedConfigurations.reserve(numFoundConfigurations); - for (int i = 0; i < foundConfigurations.count(); ++i) { + for (int i = 0; i < numFoundConfigurations; ++i) { QNetworkConfigurationPrivate *config = new QNetworkConfigurationPrivate; cpPriv = foundConfigurations.at(i); @@ -556,4 +557,3 @@ void QConnmanEngine::reEvaluateCellular() QT_END_NAMESPACE #endif // QT_NO_DBUS -#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/plugins/bearer/connman/qconnmanengine.h b/src/plugins/bearer/connman/qconnmanengine.h index 2c1f5490e348688a91fd3a52c658107a50a90a14..8c79b22bf9ba2ba7f43e0f147502155a4782fe05 100644 --- a/src/plugins/bearer/connman/qconnmanengine.h +++ b/src/plugins/bearer/connman/qconnmanengine.h @@ -53,7 +53,6 @@ #include <QMap> #include <QVariant> -#ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE @@ -135,7 +134,6 @@ protected: QT_END_NAMESPACE #endif // QT_NO_DBUS -#endif // QT_NO_BEARERMANAGEMENT #endif diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp index 155e6970fa62ed4d2aa1c050e8e52a45c43d4e40..10d8285a4a397d304b2f8d5c01276ce0fc1af30c 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp +++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp @@ -45,7 +45,6 @@ #include "qconnmanservice_linux_p.h" -#ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE @@ -175,11 +174,10 @@ void QConnmanManagerInterface::connectNotify(const QMetaMethod &signal) void QConnmanManagerInterface::onServicesChanged(const ConnmanMapList &changed, const QList<QDBusObjectPath> &removed) { - ConnmanMap connmanobj; servicesList.clear(); //connman list changes order - Q_FOREACH (connmanobj, changed) { + Q_FOREACH (const ConnmanMap &connmanobj, changed) { const QString svcPath(connmanobj.objectPath.path()); - servicesList << svcPath; + servicesList << svcPath; } Q_EMIT servicesChanged(changed, removed); @@ -221,7 +219,7 @@ QStringList QConnmanManagerInterface::getTechnologies() QDBusPendingReply<ConnmanMapList> reply = call(QLatin1String("GetTechnologies")); reply.waitForFinished(); if (!reply.isError()) { - Q_FOREACH (ConnmanMap map, reply.value()) { + Q_FOREACH (const ConnmanMap &map, reply.value()) { if (!technologiesMap.contains(map.objectPath.path())) { technologyAdded(map.objectPath, map.propertyMap); } @@ -237,7 +235,7 @@ QStringList QConnmanManagerInterface::getServices() QDBusPendingReply<ConnmanMapList> reply = call(QLatin1String("GetServices")); reply.waitForFinished(); if (!reply.isError()) { - Q_FOREACH (ConnmanMap map, reply.value()) { + Q_FOREACH (const ConnmanMap &map, reply.value()) { servicesList << map.objectPath.path(); } } @@ -504,5 +502,3 @@ void QConnmanTechnologyInterface::scanReply(QDBusPendingCallWatcher *call) QT_END_NAMESPACE #endif // QT_NO_DBUS -#endif // QT_NO_BEARERMANAGEMENT - diff --git a/src/plugins/bearer/connman/qconnmanservice_linux_p.h b/src/plugins/bearer/connman/qconnmanservice_linux_p.h index 49ca9f391ca3281ad6b7bfae49b7a89716d2f79a..1a10a2260a7030c18a6535b0d8382ab94cc5eb0e 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux_p.h +++ b/src/plugins/bearer/connman/qconnmanservice_linux_p.h @@ -58,7 +58,6 @@ #include <QtDBus/QDBusContext> #include <QMap> -#ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_DBUS #ifndef __CONNMAN_DBUS_H @@ -219,6 +218,5 @@ private: QT_END_NAMESPACE #endif // QT_NO_DBUS -#endif // QT_NO_BEARERMANAGEMENT #endif //QCONNMANSERVICE_H diff --git a/src/plugins/bearer/generic/main.cpp b/src/plugins/bearer/generic/main.cpp index 112c7420e19345bddc222141c565307f69ef88a8..4f798071286224400348659c401684f4522fc6c0 100644 --- a/src/plugins/bearer/generic/main.cpp +++ b/src/plugins/bearer/generic/main.cpp @@ -37,8 +37,6 @@ #include <QtCore/qdebug.h> -#ifndef QT_NO_BEARERMANAGEMENT - QT_BEGIN_NAMESPACE class QGenericEnginePlugin : public QBearerEnginePlugin @@ -72,5 +70,3 @@ QBearerEngine *QGenericEnginePlugin::create(const QString &key) const QT_END_NAMESPACE #include "main.moc" - -#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/plugins/bearer/generic/qgenericengine.cpp b/src/plugins/bearer/generic/qgenericengine.cpp index e1b3d79b3817c44585a13d50d5b9e86bdb6e5304..93b27f16f18c4481f670bd77d5ca2ee7aa09132b 100644 --- a/src/plugins/bearer/generic/qgenericengine.cpp +++ b/src/plugins/bearer/generic/qgenericengine.cpp @@ -50,8 +50,10 @@ #ifdef Q_OS_WINCE typedef ULONG NDIS_OID, *PNDIS_OID; -#include <nuiouser.h> -#endif +# ifndef QT_NO_WINCE_NUIOUSER +# include <nuiouser.h> +# endif +#endif // Q_OS_WINCE #ifdef Q_OS_LINUX #include <sys/socket.h> @@ -61,8 +63,6 @@ typedef ULONG NDIS_OID, *PNDIS_OID; #include <unistd.h> #endif -#ifndef QT_NO_BEARERMANAGEMENT - QT_BEGIN_NAMESPACE #ifndef QT_NO_NETWORKINTERFACE @@ -73,7 +73,7 @@ static QNetworkConfiguration::BearerType qGetInterfaceType(const QString &interf NDIS_MEDIUM medium; NDIS_PHYSICAL_MEDIUM physicalMedium; -#ifdef Q_OS_WINCE +#if defined(Q_OS_WINCE) && !defined(QT_NO_WINCE_NUIOUSER) NDISUIO_QUERY_OID nicGetOid; HANDLE handle = CreateFile((PTCHAR)NDISUIO_DEVICE_NAME, 0, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); @@ -87,7 +87,7 @@ static QNetworkConfiguration::BearerType qGetInterfaceType(const QString &interf bytesWritten = 0; -#ifdef Q_OS_WINCE +#if defined(Q_OS_WINCE) && !defined(QT_NO_WINCE_NUIOUSER) ZeroMemory(&nicGetOid, sizeof(NDISUIO_QUERY_OID)); nicGetOid.Oid = OID_GEN_MEDIA_SUPPORTED; nicGetOid.ptcDeviceName = (PTCHAR)interface.utf16(); @@ -105,7 +105,7 @@ static QNetworkConfiguration::BearerType qGetInterfaceType(const QString &interf bytesWritten = 0; -#ifdef Q_OS_WINCE +#if defined(Q_OS_WINCE) && !defined(QT_NO_WINCE_NUIOUSER) medium = NDIS_MEDIUM( *(LPDWORD)nicGetOid.Data ); ZeroMemory(&nicGetOid, sizeof(NDISUIO_QUERY_OID)); @@ -385,5 +385,3 @@ bool QGenericEngine::requiresPolling() const } QT_END_NAMESPACE - -#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/plugins/bearer/generic/qgenericengine.h b/src/plugins/bearer/generic/qgenericengine.h index 9acd6c4c2e7503e5a77ec6711bf2971ba1382d46..4b99c900511f12089bfc54df50663a93cbd8d31b 100644 --- a/src/plugins/bearer/generic/qgenericengine.h +++ b/src/plugins/bearer/generic/qgenericengine.h @@ -39,8 +39,6 @@ #include <QMap> #include <QTimer> -#ifndef QT_NO_BEARERMANAGEMENT - QT_BEGIN_NAMESPACE class QNetworkConfigurationPrivate; @@ -82,7 +80,5 @@ private: QT_END_NAMESPACE -#endif // QT_NO_BEARERMANAGEMENT - #endif diff --git a/src/plugins/bearer/linux_common/qofonoservice_linux.cpp b/src/plugins/bearer/linux_common/qofonoservice_linux.cpp index 6e427544fa2f0e1ccf3e8c495141923482d1e2e2..e9e91f985500111c2ab4028d0cd0d6a781baeccf 100644 --- a/src/plugins/bearer/linux_common/qofonoservice_linux.cpp +++ b/src/plugins/bearer/linux_common/qofonoservice_linux.cpp @@ -45,7 +45,6 @@ #include "qofonoservice_linux_p.h" -#ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_DBUS QDBusArgument &operator<<(QDBusArgument &argument, const ObjectPathProperties &item) @@ -98,7 +97,7 @@ QStringList QOfonoManagerInterface::getModems() QDBusPendingReply<PathPropertiesList> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetModems"), argumentList); reply.waitForFinished(); if (!reply.isError()) { - foreach (ObjectPathProperties modem, reply.value()) { + foreach (const ObjectPathProperties &modem, reply.value()) { modemList << modem.path.path(); } } @@ -261,7 +260,7 @@ QStringList QOfonoDataConnectionManagerInterface::contexts() QDBusPendingReply<PathPropertiesList > reply = call(QLatin1String("GetContexts")); reply.waitForFinished(); if (!reply.isError()) { - foreach (ObjectPathProperties context, reply.value()) { + foreach (const ObjectPathProperties &context, reply.value()) { contextList << context.path.path(); } } @@ -382,4 +381,3 @@ QString QOfonoConnectionContextInterface::name() QT_END_NAMESPACE #endif // QT_NO_DBUS -#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/plugins/bearer/linux_common/qofonoservice_linux_p.h b/src/plugins/bearer/linux_common/qofonoservice_linux_p.h index b051b8feaada4f8297b0dfbea854fcfcedbbfc21..57ea089ec8ddbf2073eefc205122e9cacacbdd20 100644 --- a/src/plugins/bearer/linux_common/qofonoservice_linux_p.h +++ b/src/plugins/bearer/linux_common/qofonoservice_linux_p.h @@ -57,7 +57,6 @@ #include <QtDBus/QDBusContext> #include <QMap> -#ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_DBUS #define OFONO_SERVICE "org.ofono" @@ -193,6 +192,5 @@ private slots: QT_END_NAMESPACE #endif // QT_NO_DBUS -#endif // QT_NO_BEARERMANAGEMENT #endif //QOFONOSERVICE_H diff --git a/src/plugins/bearer/nativewifi/main.cpp b/src/plugins/bearer/nativewifi/main.cpp index d5669e803a6ebcf5f39b8972ba1769524340ae86..48d79d37ee8fbd35239e82073ccc7112b5f909b5 100644 --- a/src/plugins/bearer/nativewifi/main.cpp +++ b/src/plugins/bearer/nativewifi/main.cpp @@ -56,26 +56,27 @@ static void resolveLibrary() #endif if (!triedResolve.load()) { + QLibrary wlanapiLib(QLatin1String("wlanapi")); local_WlanOpenHandle = (WlanOpenHandleProto) - QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanOpenHandle"); + wlanapiLib.resolve("WlanOpenHandle"); local_WlanRegisterNotification = (WlanRegisterNotificationProto) - QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanRegisterNotification"); + wlanapiLib.resolve("WlanRegisterNotification"); local_WlanEnumInterfaces = (WlanEnumInterfacesProto) - QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanEnumInterfaces"); + wlanapiLib.resolve("WlanEnumInterfaces"); local_WlanGetAvailableNetworkList = (WlanGetAvailableNetworkListProto) - QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanGetAvailableNetworkList"); + wlanapiLib.resolve("WlanGetAvailableNetworkList"); local_WlanQueryInterface = (WlanQueryInterfaceProto) - QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanQueryInterface"); + wlanapiLib.resolve("WlanQueryInterface"); local_WlanConnect = (WlanConnectProto) - QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanConnect"); + wlanapiLib.resolve("WlanConnect"); local_WlanDisconnect = (WlanDisconnectProto) - QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanDisconnect"); + wlanapiLib.resolve("WlanDisconnect"); local_WlanScan = (WlanScanProto) - QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanScan"); + wlanapiLib.resolve("WlanScan"); local_WlanFreeMemory = (WlanFreeMemoryProto) - QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanFreeMemory"); + wlanapiLib.resolve("WlanFreeMemory"); local_WlanCloseHandle = (WlanCloseHandleProto) - QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanCloseHandle"); + wlanapiLib.resolve("WlanCloseHandle"); triedResolve.storeRelease(true); } diff --git a/src/plugins/bearer/nativewifi/qnativewifiengine.cpp b/src/plugins/bearer/nativewifi/qnativewifiengine.cpp index 19852b70a8857b2f45555bb011c9080f29ec5447..7baea55ee7252dec574a89315e1759665cf204f6 100644 --- a/src/plugins/bearer/nativewifi/qnativewifiengine.cpp +++ b/src/plugins/bearer/nativewifi/qnativewifiengine.cpp @@ -606,7 +606,7 @@ bool QNativeWifiEngine::requiresPolling() const { // On Windows XP SP2 and SP3 only connection and disconnection notifications are available. // We need to poll for changes in available wireless networks. - return true; + return QSysInfo::WindowsVersion <= QSysInfo::WV_2003; } QT_END_NAMESPACE diff --git a/src/plugins/bearer/networkmanager/main.cpp b/src/plugins/bearer/networkmanager/main.cpp index 8a872cf08f32e8a2b7140f481de9a5425396941a..0d22846c44873cf8eceb8f75465c3b334d4e89d3 100644 --- a/src/plugins/bearer/networkmanager/main.cpp +++ b/src/plugins/bearer/networkmanager/main.cpp @@ -37,7 +37,6 @@ #include <QtCore/qdebug.h> -#ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE @@ -77,4 +76,3 @@ QT_END_NAMESPACE #include "main.moc" #endif // QT_NO_DBUS -#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index e662d5f2d33e5dca19bcdd5a34cab4e4ed98b427..7258877eb77f9d1a5aa775777fa1972616d9b82d 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -49,7 +49,6 @@ #include <QDBusReply> #include "../linux_common/qofonoservice_linux_p.h" -#ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE @@ -1129,4 +1128,3 @@ void QNetworkManagerEngine::ofonoUnRegistered(const QString &) QT_END_NAMESPACE #endif // QT_NO_DBUS -#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h index 3d90fcd0e5365bed8a3cb9ca749f273fe439fb03..1f578890dcbb65b73cb66334cf15f4a2e7f5cd48 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h @@ -54,7 +54,6 @@ #include <QMap> #include <QVariant> -#ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE @@ -150,7 +149,6 @@ private: QT_END_NAMESPACE #endif // QT_NO_DBUS -#endif // QT_NO_BEARERMANAGEMENT #endif diff --git a/src/plugins/bearer/qbearerengine_impl.h b/src/plugins/bearer/qbearerengine_impl.h index 6db4d8c6b29b73ab5bc28f368be5f0799aec864a..a343474f2c5278413ceafeb8522929f0cca8d511 100644 --- a/src/plugins/bearer/qbearerengine_impl.h +++ b/src/plugins/bearer/qbearerengine_impl.h @@ -36,8 +36,6 @@ #include <QtNetwork/private/qbearerengine_p.h> -#ifndef QT_NO_BEARERMANAGEMENT - QT_BEGIN_NAMESPACE class QBearerEngineImpl : public QBearerEngine @@ -74,6 +72,4 @@ QT_END_NAMESPACE Q_DECLARE_METATYPE(QBearerEngineImpl::ConnectionError) -#endif // QT_NO_BEARERMANAGEMENT - #endif // QBEARERENGINE_IMPL_H diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp index f3f372950430455fbd2943adf88000280185f8d1..5e9e5e70152bf652cd969f5ae30763debdca5eb7 100644 --- a/src/plugins/bearer/qnetworksession_impl.cpp +++ b/src/plugins/bearer/qnetworksession_impl.cpp @@ -42,8 +42,6 @@ #include <QtCore/qmutex.h> #include <QtCore/qstringlist.h> -#ifndef QT_NO_BEARERMANAGEMENT - QT_BEGIN_NAMESPACE static QBearerEngineImpl *getEngineFromId(const QString &id) @@ -423,5 +421,3 @@ void QNetworkSessionPrivateImpl::decrementTimeout() } QT_END_NAMESPACE - -#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/plugins/bearer/qnetworksession_impl.h b/src/plugins/bearer/qnetworksession_impl.h index 87a2b29bd488078231e9d372ecea5e1643f921d7..a26b05ab3ba607d9483610abe3645157242fd575 100644 --- a/src/plugins/bearer/qnetworksession_impl.h +++ b/src/plugins/bearer/qnetworksession_impl.h @@ -50,8 +50,6 @@ #include <QtNetwork/private/qnetworkconfigmanager_p.h> #include <QtNetwork/private/qnetworksession_p.h> -#ifndef QT_NO_BEARERMANAGEMENT - QT_BEGIN_NAMESPACE class QBearerEngineImpl; @@ -123,6 +121,4 @@ private: QT_END_NAMESPACE -#endif // QT_NO_BEARERMANAGEMENT - #endif // QNETWORKSESSION_IMPL_H diff --git a/src/plugins/generic/tuiotouch/qtuiohandler.cpp b/src/plugins/generic/tuiotouch/qtuiohandler.cpp index 5211ed8381b6d78dbc3208e12f2a9b27e97d11e2..dd161570e886f3c16e18b3cc659864ddb8691082 100644 --- a/src/plugins/generic/tuiotouch/qtuiohandler.cpp +++ b/src/plugins/generic/tuiotouch/qtuiohandler.cpp @@ -317,6 +317,7 @@ void QTuioHandler::process2DCurFseq(const QOscMessage &message) return; QList<QWindowSystemInterface::TouchPoint> tpl; + tpl.reserve(m_activeCursors.size() + m_deadCursors.size()); foreach (const QTuioCursor &tc, m_activeCursors) { QWindowSystemInterface::TouchPoint tp = cursorToTouchPoint(tc, win); diff --git a/src/plugins/imageformats/gif/main.cpp b/src/plugins/imageformats/gif/main.cpp index 8181900adb22cca44ee245e6c34f0d8df84bfd5e..62c4f4b5970d270d6fe143510a80cb908512b338 100644 --- a/src/plugins/imageformats/gif/main.cpp +++ b/src/plugins/imageformats/gif/main.cpp @@ -34,8 +34,6 @@ #include <qimageiohandler.h> #include <qstringlist.h> -#ifndef QT_NO_IMAGEFORMATPLUGIN - #include "main.h" #ifdef QT_NO_IMAGEFORMAT_GIF @@ -69,6 +67,4 @@ QImageIOHandler *QGifPlugin::create(QIODevice *device, const QByteArray &format) return handler; } -#endif // QT_NO_IMAGEFORMATPLUGIN - QT_END_NAMESPACE diff --git a/src/plugins/imageformats/gif/main.h b/src/plugins/imageformats/gif/main.h index 1b02d5eaf685e33d36cb0f1914663e4264ba52e7..56e0655b1fa323900dffaad02d972bbe3933d5c0 100644 --- a/src/plugins/imageformats/gif/main.h +++ b/src/plugins/imageformats/gif/main.h @@ -34,8 +34,6 @@ #include <qimageiohandler.h> #include <qstringlist.h> -#ifndef QT_NO_IMAGEFORMATPLUGIN - #ifdef QT_NO_IMAGEFORMAT_GIF #undef QT_NO_IMAGEFORMAT_GIF #endif @@ -56,5 +54,3 @@ public: }; QT_END_NAMESPACE - -#endif // QT_NO_IMAGEFORMATPLUGIN diff --git a/src/plugins/imageformats/ico/main.cpp b/src/plugins/imageformats/ico/main.cpp index 80182fb6659a4db96b1e24cb724003f733f8ce43..03448d4ae1766d74a030f30269ccf796e5afdc10 100644 --- a/src/plugins/imageformats/ico/main.cpp +++ b/src/plugins/imageformats/ico/main.cpp @@ -33,8 +33,6 @@ #include "main.h" -#ifndef QT_NO_IMAGEFORMATPLUGIN - QT_BEGIN_NAMESPACE QImageIOPlugin::Capabilities QICOPlugin::capabilities(QIODevice *device, const QByteArray &format) const @@ -63,5 +61,3 @@ QImageIOHandler *QICOPlugin::create(QIODevice *device, const QByteArray &format) } QT_END_NAMESPACE - -#endif /* QT_NO_IMAGEFORMATPLUGIN */ diff --git a/src/plugins/imageformats/ico/main.h b/src/plugins/imageformats/ico/main.h index a254a626d11b40be1477ce1072517b3b0e3d7323..d17dbe824ddb70ce1fb57ecd4b480ae88661a1e8 100644 --- a/src/plugins/imageformats/ico/main.h +++ b/src/plugins/imageformats/ico/main.h @@ -34,8 +34,6 @@ #include <qimageiohandler.h> #include <qdebug.h> -#ifndef QT_NO_IMAGEFORMATPLUGIN - #ifdef QT_NO_IMAGEFORMAT_ICO #undef QT_NO_IMAGEFORMAT_ICO #endif @@ -53,5 +51,3 @@ public: }; QT_END_NAMESPACE - -#endif diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp index 4cb5e22bf7635b276d9ffb992a8ea776a7c4e081..2ddbc4519b8bbf2a76620fdf9c842288753f6d14 100644 --- a/src/plugins/imageformats/ico/qicohandler.cpp +++ b/src/plugins/imageformats/ico/qicohandler.cpp @@ -96,9 +96,9 @@ public: QImage iconAt(int index); static bool canRead(QIODevice *iodev); - static QList<QImage> read(QIODevice * device); + static QVector<QImage> read(QIODevice *device); - static bool write(QIODevice * device, const QList<QImage> & images); + static bool write(QIODevice *device, const QVector<QImage> &images); private: bool readHeader(); @@ -612,12 +612,14 @@ QImage ICOReader::iconAt(int index) \sa write() */ -QList<QImage> ICOReader::read(QIODevice * device) +QVector<QImage> ICOReader::read(QIODevice *device) { - QList<QImage> images; + QVector<QImage> images; ICOReader reader(device); - for (int i = 0; i < reader.count(); i++) + const int N = reader.count(); + images.reserve(N); + for (int i = 0; i < N; i++) images += reader.iconAt(i); return images; @@ -636,7 +638,7 @@ QList<QImage> ICOReader::read(QIODevice * device) \sa read() */ -bool ICOReader::write(QIODevice * device, const QList<QImage> & images) +bool ICOReader::write(QIODevice *device, const QVector<QImage> &images) { bool retValue = false; @@ -849,7 +851,7 @@ bool QtIcoHandler::read(QImage *image) bool QtIcoHandler::write(const QImage &image) { QIODevice *device = QImageIOHandler::device(); - QList<QImage> imgs; + QVector<QImage> imgs; imgs.append(image); return ICOReader::write(device, imgs); } diff --git a/src/plugins/imageformats/jpeg/main.cpp b/src/plugins/imageformats/jpeg/main.cpp index d009707fa0aeb3c67fe703941b0f92b924af6bcc..c8a575cb437f4890d8bde89e145a85c3736c2dcd 100644 --- a/src/plugins/imageformats/jpeg/main.cpp +++ b/src/plugins/imageformats/jpeg/main.cpp @@ -33,8 +33,6 @@ #include "main.h" -#ifndef QT_NO_IMAGEFORMATPLUGIN - #ifdef QT_NO_IMAGEFORMAT_JPEG #undef QT_NO_IMAGEFORMAT_JPEG #endif @@ -68,5 +66,3 @@ QImageIOHandler *QJpegPlugin::create(QIODevice *device, const QByteArray &format } QT_END_NAMESPACE - -#endif // QT_NO_IMAGEFORMATPLUGIN diff --git a/src/plugins/imageformats/jpeg/main.h b/src/plugins/imageformats/jpeg/main.h index 2d79c846662caff9e4f566e9917b3cfc0eee56bd..77ee33faca655a9be5acc551f62a6f5420dfe2c1 100644 --- a/src/plugins/imageformats/jpeg/main.h +++ b/src/plugins/imageformats/jpeg/main.h @@ -34,8 +34,6 @@ #include <qimageiohandler.h> #include <qstringlist.h> -#ifndef QT_NO_IMAGEFORMATPLUGIN - #ifdef QT_NO_IMAGEFORMAT_JPEG #undef QT_NO_IMAGEFORMAT_JPEG #endif @@ -52,5 +50,3 @@ public: }; QT_END_NAMESPACE - -#endif diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp index 0b5775bc15ea1b5e7e9678415c3844ca75385690..4a276dc834214478be3ac74f41d783f14296d5ea 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp @@ -39,6 +39,10 @@ #include <qwindow.h> #include <qevent.h> +#include <qpa/qplatformcursor.h> +#include <qpa/qplatformscreen.h> +#include <qpa/qwindowsysteminterface.h> + #include "qibusproxy.h" #include "qibusinputcontextproxy.h" #include "qibustypes.h" @@ -48,8 +52,14 @@ #include <QtDBus> +#ifndef IBUS_RELEASE_MASK +#define IBUS_RELEASE_MASK (1 << 30) +#endif + QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(qtQpaInputMethods, "qt.qpa.input.methods") + enum { debug = 0 }; class QIBusPlatformInputContextPrivate @@ -86,6 +96,13 @@ QIBusPlatformInputContext::QIBusPlatformInputContext () } QInputMethod *p = qApp->inputMethod(); connect(p, SIGNAL(cursorRectangleChanged()), this, SLOT(cursorRectChanged())); + m_eventFilterUseSynchronousMode = false; + if (qEnvironmentVariableIsSet("IBUS_ENABLE_SYNC_MODE")) { + bool ok; + int enableSync = qgetenv("IBUS_ENABLE_SYNC_MODE").toInt(&ok); + if (ok && enableSync == 1) + m_eventFilterUseSynchronousMode = true; + } } QIBusPlatformInputContext::~QIBusPlatformInputContext (void) @@ -272,8 +289,7 @@ void QIBusPlatformInputContext::deleteSurroundingText(int offset, uint n_chars) QCoreApplication::sendEvent(input, &event); } -bool -QIBusPlatformInputContext::x11FilterEvent(uint keyval, uint keycode, uint state, bool press) +bool QIBusPlatformInputContext::filterEvent(const QEvent *event) { if (!d->valid) return false; @@ -281,15 +297,89 @@ QIBusPlatformInputContext::x11FilterEvent(uint keyval, uint keycode, uint state, if (!inputMethodAccepted()) return false; - if (!press) - return false; + const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event); + quint32 sym = keyEvent->nativeVirtualKey(); + quint32 code = keyEvent->nativeScanCode(); + quint32 state = keyEvent->nativeModifiers(); + + if (keyEvent->type() != QEvent::KeyPress) + state |= IBUS_RELEASE_MASK; + + code -= 8; // ### + QDBusPendingReply<bool> reply = d->context->ProcessKeyEvent(sym, code, state); + + if (m_eventFilterUseSynchronousMode || reply.isFinished()) { + bool retval = reply.value(); + qCDebug(qtQpaInputMethods) << "filterEvent return" << code << sym << state << retval; + return retval; + } + + Qt::KeyboardModifiers modifiers = keyEvent->modifiers(); + + QVariantList args; + args << QVariant::fromValue(keyEvent->timestamp()); + args << QVariant::fromValue(static_cast<uint>(keyEvent->type())); + args << QVariant::fromValue(keyEvent->key()); + args << QVariant::fromValue(code) << QVariant::fromValue(sym) << QVariant::fromValue(state); + args << QVariant::fromValue(keyEvent->text()); + args << QVariant::fromValue(keyEvent->isAutoRepeat()); + args << QVariant::fromValue(keyEvent->count()); + + QIBusFilterEventWatcher *watcher = new QIBusFilterEventWatcher(reply, this, qApp->focusObject(), modifiers, args); + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, &QIBusPlatformInputContext::filterEventFinished); - keycode -= 8; // ### - QDBusReply<bool> reply = d->context->ProcessKeyEvent(keyval, keycode, state); + return true; +} + +void QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher *call) +{ + QIBusFilterEventWatcher *watcher = (QIBusFilterEventWatcher *) call; + QDBusPendingReply<bool> reply = *call; + + if (reply.isError()) { + call->deleteLater(); + return; + } -// qDebug() << "x11FilterEvent return" << reply.value(); + // Use watcher's window instead of the current focused window + // since there is a time lag until filterEventFinished() returns. + QObject *input = watcher->input(); - return reply.value(); + if (!input) { + call->deleteLater(); + return; + } + + Qt::KeyboardModifiers modifiers = watcher->modifiers(); + QVariantList args = watcher->arguments(); + const ulong time = static_cast<const ulong>(args.at(0).toUInt()); + const QEvent::Type type = static_cast<const QEvent::Type>(args.at(1).toUInt()); + const int qtcode = args.at(2).toInt(); + const quint32 code = args.at(3).toUInt(); + const quint32 sym = args.at(4).toUInt(); + const quint32 state = args.at(5).toUInt(); + const QString string = args.at(6).toString(); + const bool isAutoRepeat = args.at(7).toBool(); + const int count = args.at(8).toInt(); + + // copied from QXcbKeyboard::handleKeyEvent() + bool retval = reply.value(); + qCDebug(qtQpaInputMethods) << "filterEventFinished return" << code << sym << state << retval; + if (!retval) { + QWindow *window = dynamic_cast<QWindow *>(input); + if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu + && window != NULL) { + const QPoint globalPos = window->screen()->handle()->cursor()->pos(); + const QPoint pos = window->mapFromGlobal(globalPos); + QWindowSystemInterface::handleContextMenuEvent(window, false, pos, + globalPos, modifiers); + } + QKeyEvent event(type, qtcode, modifiers, code, sym, + state, string, isAutoRepeat, count); + event.setTimestamp(time); + QCoreApplication::sendEvent(input, &event); + } + call->deleteLater(); } QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate() diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h index 816da8d377ab8505add490c4008043624e09ad36..91f15ea1595cf9797449269ae5e73a18214fec74 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h @@ -35,11 +35,43 @@ #include <qpa/qplatforminputcontext.h> +#include <QtCore/qpointer.h> +#include <QtDBus/qdbuspendingreply.h> +#include <QLoggingCategory> + QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(qtQpaInputMethods) + class QIBusPlatformInputContextPrivate; class QDBusVariant; +class QIBusFilterEventWatcher: public QDBusPendingCallWatcher +{ +public: + explicit QIBusFilterEventWatcher(const QDBusPendingCall &call, + QObject *parent = 0, + QObject *input = 0, + const Qt::KeyboardModifiers modifiers = 0, + const QVariantList arguments = QVariantList()) + : QDBusPendingCallWatcher(call, parent) + , m_input(input) + , m_modifiers(modifiers) + , m_arguments(arguments) + {} + ~QIBusFilterEventWatcher() + {} + + inline QObject *input() const { return m_input; } + inline const Qt::KeyboardModifiers modifiers() const { return m_modifiers; } + inline const QVariantList arguments() const { return m_arguments; } + +private: + QPointer<QObject> m_input; + const Qt::KeyboardModifiers m_modifiers; + const QVariantList m_arguments; +}; + class QIBusPlatformInputContext : public QPlatformInputContext { Q_OBJECT @@ -54,8 +86,7 @@ public: void reset() Q_DECL_OVERRIDE; void commit() Q_DECL_OVERRIDE; void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE; - - Q_INVOKABLE bool x11FilterEvent(uint keyval, uint keycode, uint state, bool press); + bool filterEvent(const QEvent *event) Q_DECL_OVERRIDE; public Q_SLOTS: void commitText(const QDBusVariant &text); @@ -63,9 +94,11 @@ public Q_SLOTS: void cursorRectChanged(); void deleteSurroundingText(int offset, uint n_chars); void surroundingTextRequired(); + void filterEventFinished(QDBusPendingCallWatcher *call); private: QIBusPlatformInputContextPrivate *d; + bool m_eventFilterUseSynchronousMode; }; QT_END_NAMESPACE diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp index d6be6cbb31b42fd97f6d0ae9e2b35d87b452a6eb..f88e5ca5a3311cca535ec7556568cd51669d7419 100644 --- a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp @@ -225,9 +225,10 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, QIBusAttributeList &at QList<QInputMethodEvent::Attribute> QIBusAttributeList::imAttributes() const { QHash<QPair<int, int>, QTextCharFormat> rangeAttrs; + const int numAttributes = attributes.size(); // Merge text fomats for identical ranges into a single QTextFormat. - for (int i = 0; i < attributes.size(); ++i) { + for (int i = 0; i < numAttributes; ++i) { const QIBusAttribute &attr = attributes.at(i); const QTextCharFormat &format = attr.format(); @@ -239,8 +240,9 @@ QList<QInputMethodEvent::Attribute> QIBusAttributeList::imAttributes() const // Assemble list in original attribute order. QList<QInputMethodEvent::Attribute> imAttrs; + imAttrs.reserve(numAttributes); - for (int i = 0; i < attributes.size(); ++i) { + for (int i = 0; i < numAttributes; ++i) { const QIBusAttribute &attr = attributes.at(i); const QTextFormat &format = attr.format(); diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index f8c3e262296dc3865b003115a79dcafb361f5afc..69f8bdbad75489eb60e56b8f707034266e265504 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -42,6 +42,7 @@ #include "QtGui/qaccessible.h" #include <QtCore/qmath.h> #include <QtCore/private/qjnihelpers_p.h> +#include <QtCore/private/qjni_p.h> #include "qdebug.h" @@ -65,6 +66,15 @@ namespace QtAndroidAccessibility static jmethodID m_setTextSelectionMethodID = 0; static jmethodID m_setVisibleToUserMethodID = 0; + void initialize() + { + // API level > 16 is required. + if (QtAndroidPrivate::androidSdkVersion() < 16) + return; + + QJNIObjectPrivate::callStaticMethod<void>(QtAndroid::applicationClass(), + "initializeAccessibility"); + } static void setActive(JNIEnv */*env*/, jobject /*thiz*/, jboolean active) { diff --git a/src/plugins/platforms/android/androidjniaccessibility.h b/src/plugins/platforms/android/androidjniaccessibility.h index 92013531189bd4cb0c468256153dc8a9931326a5..a4cbab7834b0171b6e8f4a1cfc16cc3a30bab6e9 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.h +++ b/src/plugins/platforms/android/androidjniaccessibility.h @@ -40,6 +40,7 @@ QT_BEGIN_NAMESPACE namespace QtAndroidAccessibility { + void initialize(); bool registerNatives(JNIEnv *env); } diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 5c8406ca03e39940b15bc80700e80505d74fac41..d264f74d664285e8bb07899ca5060a9ab7868551 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -650,6 +650,11 @@ jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint right m_composingText.clear(); m_composingTextStart = -1; + if (leftLength < 0) { + rightLength += -leftLength; + leftLength = 0; + } + QInputMethodEvent event; event.setCommitString(QString(), -leftLength, leftLength+rightLength); sendInputMethodEventThreadSafe(&event); @@ -912,7 +917,7 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end) m_blockUpdateSelection = updateSelectionWasBlocked; #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL - QSharedPointer<QInputMethodQueryEvent> query2 = focusObjectInputMethodQuery(); + QSharedPointer<QInputMethodQueryEvent> query2 = focusObjectInputMethodQueryThreadSafe(); if (!query2.isNull()) { qDebug() << "Setting. Prev local cpos:" << localPos << "block pos:" <<blockPosition << "comp.start:" << m_composingTextStart << "rel.start:" << relativeStart << "len:" << length << "cpos attr:" << localPos - localStart; qDebug() << "New cursor pos" << getAbsoluteCursorPosition(query2); diff --git a/src/plugins/platforms/android/qandroidplatformaccessibility.cpp b/src/plugins/platforms/android/qandroidplatformaccessibility.cpp index e3a8b1a8f44154807a8d4e2c56f2d26769a4213c..339023bd9f17ae6a62758cd11f5571818a844faa 100644 --- a/src/plugins/platforms/android/qandroidplatformaccessibility.cpp +++ b/src/plugins/platforms/android/qandroidplatformaccessibility.cpp @@ -33,11 +33,14 @@ #include "qandroidplatformaccessibility.h" +#include "androidjniaccessibility.h" QT_BEGIN_NAMESPACE QAndroidPlatformAccessibility::QAndroidPlatformAccessibility() -{} +{ + QtAndroidAccessibility::initialize(); +} QAndroidPlatformAccessibility::~QAndroidPlatformAccessibility() {} diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp index eb96bf11f06b902720515036d3e5df47bddf7d33..2a127f5c3cd30165d506ec4778f0f717f1f4fb65 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp @@ -148,6 +148,10 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶ m_androidSystemLocale = new QAndroidSystemLocale; +#ifndef QT_NO_ACCESSIBILITY + m_accessibility = new QAndroidPlatformAccessibility(); +#endif // QT_NO_ACCESSIBILITY + QJNIObjectPrivate javaActivity(QtAndroid::activity()); if (javaActivity.isValid()) { QJNIObjectPrivate resources = javaActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;"); @@ -348,8 +352,6 @@ void QAndroidPlatformIntegration::setScreenOrientation(Qt::ScreenOrientation cur #ifndef QT_NO_ACCESSIBILITY QPlatformAccessibility *QAndroidPlatformIntegration::accessibility() const { - if (!m_accessibility) - m_accessibility = new QAndroidPlatformAccessibility(); return m_accessibility; } #endif diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.h b/src/plugins/platforms/cocoa/qcocoaaccessibility.h index 061dfac1567b8c2b07aeff8a72642d5b8e8132a9..18ff9aeb29c865b27a95d095cee2f7f4394705e9 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.h +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.h @@ -45,10 +45,10 @@ class QCocoaAccessibility : public QPlatformAccessibility public: QCocoaAccessibility(); ~QCocoaAccessibility(); - void notifyAccessibilityUpdate(QAccessibleEvent *event); - void setRootObject(QObject *o); - void initialize(); - void cleanup(); + void notifyAccessibilityUpdate(QAccessibleEvent *event) Q_DECL_OVERRIDE; + void setRootObject(QObject *o) Q_DECL_OVERRIDE; + void initialize() Q_DECL_OVERRIDE; + void cleanup() Q_DECL_OVERRIDE; }; namespace QCocoaAccessible { diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.mm b/src/plugins/platforms/cocoa/qcocoaapplication.mm index 227ab05c25287571ad81f541346f79c9e07e0ea8..d9919f1120adea5211bb6aefd88efaa25e1615c7 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplication.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplication.mm @@ -79,12 +79,12 @@ QT_USE_NAMESPACE - (void)QT_MANGLE_NAMESPACE(qt_setDockMenu):(NSMenu *)newMenu { - [[QCocoaApplicationDelegate sharedDelegate] setDockMenu:newMenu]; + [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] setDockMenu:newMenu]; } - (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader) { - return [[QCocoaApplicationDelegate sharedDelegate] menuLoader]; + return [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] menuLoader]; } - (int)QT_MANGLE_NAMESPACE(qt_validModesForFontPanel):(NSFontPanel *)fontPanel @@ -147,9 +147,9 @@ static const QByteArray q_macLocalEventType = QByteArrayLiteral("mac_generic_NSE @end -@implementation QNSApplication +@implementation QT_MANGLE_NAMESPACE(QNSApplication) -- (void)qt_sendEvent_original:(NSEvent *)event +- (void)QT_MANGLE_NAMESPACE(qt_sendEvent_original):(NSEvent *)event { Q_UNUSED(event); // This method will only be used as a signature @@ -157,14 +157,14 @@ static const QByteArray q_macLocalEventType = QByteArrayLiteral("mac_generic_NSE // containing the original [NSApplication sendEvent:] implementation } -- (void)qt_sendEvent_replacement:(NSEvent *)event +- (void)QT_MANGLE_NAMESPACE(qt_sendEvent_replacement):(NSEvent *)event { // This method (or its implementation to be precise) will // be called instead of sendEvent if redirection occurs. // 'self' will then be an instance of NSApplication // (and not QNSApplication) if (![NSApp QT_MANGLE_NAMESPACE(qt_filterEvent):event]) - [self qt_sendEvent_original:event]; + [self QT_MANGLE_NAMESPACE(qt_sendEvent_original):event]; } - (void)sendEvent:(NSEvent *)event @@ -187,7 +187,7 @@ void qt_redirectNSApplicationSendEvent() // can be unloaded. return; - if ([NSApp isMemberOfClass:[QNSApplication class]]) { + if ([NSApp isMemberOfClass:[QT_MANGLE_NAMESPACE(QNSApplication) class]]) { // No need to change implementation since Qt // already controls a subclass of NSApplication return; @@ -200,9 +200,9 @@ void qt_redirectNSApplicationSendEvent() qt_cocoa_change_implementation( [NSApplication class], @selector(sendEvent:), - [QNSApplication class], - @selector(qt_sendEvent_replacement:), - @selector(qt_sendEvent_original:)); + [QT_MANGLE_NAMESPACE(QNSApplication) class], + @selector(QT_MANGLE_NAMESPACE(qt_sendEvent_replacement):), + @selector(QT_MANGLE_NAMESPACE(qt_sendEvent_original):)); } void qt_resetNSApplicationSendEvent() diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index 67d9de859faff1815f5d1672a88855ff6284d925..cac50825af06da334fbec5523c606a1fc9213fcc 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -131,8 +131,8 @@ QT_END_NAMESPACE @synchronized(self) { if (sharedCocoaApplicationDelegate == nil) { sharedCocoaApplicationDelegate = [super allocWithZone:zone]; - return sharedCocoaApplicationDelegate; qAddPostRoutine(cleanupCocoaApplicationDelegate); + return sharedCocoaApplicationDelegate; } } return nil; diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h index 3737584c4c4b5e52613836c10336a512c4382110..5a199de4a5c8eda30da9abfb54a9fe65b36223c5 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -49,12 +49,12 @@ public: QCocoaBackingStore(QWindow *window); ~QCocoaBackingStore(); - QPaintDevice *paintDevice(); - void flush(QWindow *widget, const QRegion ®ion, const QPoint &offset); - QImage toImage() const; - void resize (const QSize &size, const QRegion &); - bool scroll(const QRegion &area, int dx, int dy); - void beginPaint(const QRegion ®ion); + QPaintDevice *paintDevice() Q_DECL_OVERRIDE; + void flush(QWindow *widget, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; + QImage toImage() const Q_DECL_OVERRIDE; + void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE; + bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE; + void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE; qreal getBackingStoreDevicePixelRatio(); private: diff --git a/src/plugins/platforms/cocoa/qcocoaclipboard.h b/src/plugins/platforms/cocoa/qcocoaclipboard.h index e3df9a99b1623939f6e235451d842aa6797ff14d..e53942b06893a14c12e14bc92eafe99abe543945 100644 --- a/src/plugins/platforms/cocoa/qcocoaclipboard.h +++ b/src/plugins/platforms/cocoa/qcocoaclipboard.h @@ -47,10 +47,10 @@ class QCocoaClipboard : public QObject, public QPlatformClipboard public: QCocoaClipboard(); - QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard); - void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard); - bool supportsMode(QClipboard::Mode mode) const; - bool ownsMode(QClipboard::Mode mode) const; + QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; + void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; + bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; + bool ownsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; private Q_SLOTS: void handleApplicationStateChanged(Qt::ApplicationState state); diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h index 318370533093d893fea3115805a15c29eab80ddf..705f97cd2ac4329d1361c34d4e03c7c4f0b2004c 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h @@ -43,14 +43,14 @@ class QCocoaColorDialogHelper : public QPlatformColorDialogHelper { public: QCocoaColorDialogHelper(); - virtual ~QCocoaColorDialogHelper(); + ~QCocoaColorDialogHelper(); - void exec(); - bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent); - void hide(); + void exec() Q_DECL_OVERRIDE; + bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) Q_DECL_OVERRIDE; + void hide() Q_DECL_OVERRIDE; - void setCurrentColor(const QColor&); - QColor currentColor() const; + void setCurrentColor(const QColor&) Q_DECL_OVERRIDE; + QColor currentColor() const Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoacursor.h b/src/plugins/platforms/cocoa/qcocoacursor.h index cc6cbaf59ea9b2face89dbe2e2e6127f3ae6d034..d104939f0ce15f324cfc6c3d1c147c318055b10a 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.h +++ b/src/plugins/platforms/cocoa/qcocoacursor.h @@ -47,9 +47,9 @@ public: QCocoaCursor(); ~QCocoaCursor(); - virtual void changeCursor(QCursor *cursor, QWindow *window); - virtual QPoint pos() const; - virtual void setPos(const QPoint &position); + void changeCursor(QCursor *cursor, QWindow *window) Q_DECL_OVERRIDE; + QPoint pos() const Q_DECL_OVERRIDE; + void setPos(const QPoint &position) Q_DECL_OVERRIDE; private: QHash<Qt::CursorShape, NSCursor *> m_cursors; NSCursor *convertCursor(QCursor *cursor); diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index d1d63302491c3b587064e6710340cdb1334635db..2098f0dc8cde95f773f8b43dbbac4df9f6986201 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -72,7 +72,7 @@ void QCocoaCursor::setPos(const QPoint &position) pos.x = position.x(); pos.y = position.y(); - CGEventRef e = CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, 0); + CGEventRef e = CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, kCGMouseButtonLeft); CGEventPost(kCGHIDEventTap, e); CFRelease(e); } diff --git a/src/plugins/platforms/cocoa/qcocoadrag.h b/src/plugins/platforms/cocoa/qcocoadrag.h index e087fcee2663a0d7253e6ed0b88816570b48105c..c1eeb346790e5a88e9edadfb876fd92fd1e52bbf 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.h +++ b/src/plugins/platforms/cocoa/qcocoadrag.h @@ -47,13 +47,13 @@ class QCocoaDrag : public QPlatformDrag { public: QCocoaDrag(); - virtual ~QCocoaDrag(); + ~QCocoaDrag(); - virtual QMimeData *platformDropData(); - virtual Qt::DropAction drag(QDrag *m_drag); + QMimeData *platformDropData() Q_DECL_OVERRIDE; + Qt::DropAction drag(QDrag *m_drag) Q_DECL_OVERRIDE; - virtual Qt::DropAction defaultAction(Qt::DropActions possibleActions, - Qt::KeyboardModifiers modifiers) const; + Qt::DropAction defaultAction(Qt::DropActions possibleActions, + Qt::KeyboardModifiers modifiers) const Q_DECL_OVERRIDE; /** * to meet NSView dragImage:at guarantees, we need to record the original diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h index 36943a563e15a97d4878df71b7eab889d79d8748..576bb3af0882ff48d5649e454182cd94f822a552 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h @@ -50,20 +50,19 @@ public: QCocoaFileDialogHelper(); virtual ~QCocoaFileDialogHelper(); - void exec(); - void execModalForWindow(QWindow *parent); + void exec() Q_DECL_OVERRIDE; - bool defaultNameFilterDisables() const; + bool defaultNameFilterDisables() const Q_DECL_OVERRIDE; - bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent); - void hide(); + bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) Q_DECL_OVERRIDE; + void hide() Q_DECL_OVERRIDE; void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE; QUrl directory() const Q_DECL_OVERRIDE; void selectFile(const QUrl &filename) Q_DECL_OVERRIDE; QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE; - void setFilter(); - void selectNameFilter(const QString &filter); - QString selectedNameFilter() const; + void setFilter() Q_DECL_OVERRIDE; + void selectNameFilter(const QString &filter) Q_DECL_OVERRIDE; + QString selectedNameFilter() const Q_DECL_OVERRIDE; public: bool showCocoaFilePanel(Qt::WindowModality windowModality, QWindow *parent); diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index fad3f28053d698c193f42e0170ad72ef8b969640..93ee4e862409d12806b9717721a66b123c24c89d 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -253,22 +253,17 @@ static QString strippedText(QString s) || [self panel:nil shouldShowFilename:filepath]; [self updateProperties]; + QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder(); [mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]]; [mSavePanel setNameFieldStringValue:selectable ? QCFString::toNSString(info.fileName()) : @""]; NSWindow *nsparent = static_cast<NSWindow *>(qGuiApp->platformNativeInterface()->nativeResourceForWindow("nswindow", parent)); - qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); - QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder(); - [mSavePanel beginSheetModalForWindow:nsparent completionHandler:^(NSInteger result){ - [[NSApplication sharedApplication] stopModalWithCode:result]; + mReturnCode = result; + if (mHelper) + mHelper->QNSOpenSavePanelDelegate_panelClosed(result == NSOKButton); }]; - - mReturnCode = [[NSApplication sharedApplication] runModalForWindow:nsparent]; - QAbstractEventDispatcher::instance()->interrupt(); - if (mHelper) - mHelper->QNSOpenSavePanelDelegate_panelClosed(mReturnCode == NSOKButton); } - (BOOL)isHiddenFile:(NSString *)filename isDir:(BOOL)isDir @@ -710,15 +705,14 @@ void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate() bool QCocoaFileDialogHelper::showCocoaFilePanel(Qt::WindowModality windowModality, QWindow *parent) { - Q_UNUSED(parent) - createNSOpenSavePanelDelegate(); if (!mDelegate) return false; if (windowModality == Qt::NonModal) [mDelegate showModelessPanel]; - // no need to show a Qt::ApplicationModal dialog here, since it will be done in exec; - // Qt::WindowModal will be done in execModalForWindow. + else if (windowModality == Qt::WindowModal && parent) + [mDelegate showWindowModalSheet:parent]; + // no need to show a Qt::ApplicationModal dialog here, since it will be done in _q_platformRunNativeAppModalPanel() return true; } @@ -750,14 +744,6 @@ void QCocoaFileDialogHelper::exec() } -void QCocoaFileDialogHelper::execModalForWindow(QWindow *parent) -{ - if (!parent) - return exec(); - - [mDelegate showWindowModalSheet:parent]; -} - bool QCocoaFileDialogHelper::defaultNameFilterDisables() const { return true; diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h index 5a241bc2422af8e388dcf9be4f3665dc448ec926..23266cfa79be1fd4cd6b13d2cfe26351e8fb7ba1 100644 --- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h @@ -45,13 +45,13 @@ public: QCocoaFontDialogHelper(); ~QCocoaFontDialogHelper(); - void exec(); + void exec() Q_DECL_OVERRIDE; - bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent); - void hide(); + bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) Q_DECL_OVERRIDE; + void hide() Q_DECL_OVERRIDE; - void setCurrentFont(const QFont &); - QFont currentFont() const; + void setCurrentFont(const QFont &) Q_DECL_OVERRIDE; + QFont currentFont() const Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h index 2c8a3e39f3bf34437c9b00213a623ba0d5792a19..fa6db018a7377a3d04e4fd59dd491fc579edadf3 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.h +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h @@ -50,22 +50,22 @@ public: QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, const QVariant &nativeHandle); ~QCocoaGLContext(); - QSurfaceFormat format() const; + QSurfaceFormat format() const Q_DECL_OVERRIDE; - void swapBuffers(QPlatformSurface *surface); + void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE; - bool makeCurrent(QPlatformSurface *surface); - void doneCurrent(); + bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE; + void doneCurrent() Q_DECL_OVERRIDE; - void (*getProcAddress(const QByteArray &procName)) (); + void (*getProcAddress(const QByteArray &procName)) () Q_DECL_OVERRIDE; void update(); static NSOpenGLPixelFormat *createNSOpenGLPixelFormat(const QSurfaceFormat &format); NSOpenGLContext *nsOpenGLContext() const; - bool isSharing() const; - bool isValid() const; + bool isSharing() const Q_DECL_OVERRIDE; + bool isValid() const Q_DECL_OVERRIDE; void windowWasHidden(); diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index c2f0c730fe5b97546d02472644f08503469d7595..bb493ef2beabc881ff66f9dca0cb3935968fb546 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -269,10 +269,14 @@ bool operator<(const KeyPair &entry, const Qt::Key &key) return entry.qtKey < key; } -static bool qtKey2CocoaKeySortLessThan(const KeyPair &entry1, const KeyPair &entry2) +struct qtKey2CocoaKeySortLessThan { - return entry1.qtKey < entry2.qtKey; -} + typedef bool result_type; + Q_DECL_CONSTEXPR result_type operator()(const KeyPair &entry1, const KeyPair &entry2) const Q_DECL_NOTHROW + { + return entry1.qtKey < entry2.qtKey; + } +}; static const int NumEntries = 59; static const KeyPair entries[NumEntries] = { @@ -352,7 +356,7 @@ QChar qt_mac_qtKey2CocoaKey(Qt::Key key) mustInit = false; for (int i=0; i<NumEntries; ++i) rev_entries[i] = entries[i]; - std::sort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan); + std::sort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan()); } const QVector<KeyPair>::iterator i = std::lower_bound(rev_entries.begin(), rev_entries.end(), key); @@ -775,7 +779,7 @@ QString qt_mac_removeAmpersandEscapes(QString s) returned if it can't be obtained. It is the caller's responsibility to CGContextRelease the context when finished using it. - \warning This function is only available on Mac OS X. + \warning This function is only available on OS X. \warning This function is duplicated in qmacstyle_mac.mm */ CGContextRef qt_mac_cg_context(QPaintDevice *pdev) diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.h b/src/plugins/platforms/cocoa/qcocoainputcontext.h index abe45344a9a7d1218844f0a99d9b65d634ec51da..c7df823dc4edba7762c9bc6cf2edd45ab8cce7f7 100644 --- a/src/plugins/platforms/cocoa/qcocoainputcontext.h +++ b/src/plugins/platforms/cocoa/qcocoainputcontext.h @@ -46,9 +46,9 @@ public: explicit QCocoaInputContext(); ~QCocoaInputContext(); - virtual bool isValid() const { return true; } + bool isValid() const Q_DECL_OVERRIDE { return true; } - virtual void reset(); + void reset() Q_DECL_OVERRIDE; private Q_SLOTS: void connectSignals(); diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index cc235135f11010590ef7512be14112548320e4a1..3b8730151e281b0465c8450f3938bc96433e7760 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -60,19 +60,19 @@ public: // ---------------------------------------------------- // Virtual methods overridden from QPlatformScreen - QPixmap grabWindow(WId window, int x, int y, int width, int height) const; - QRect geometry() const { return m_geometry; } - QRect availableGeometry() const { return m_availableGeometry; } - int depth() const { return m_depth; } - QImage::Format format() const { return m_format; } - qreal devicePixelRatio() const; - QSizeF physicalSize() const { return m_physicalSize; } - QDpi logicalDpi() const { return m_logicalDpi; } - qreal refreshRate() const { return m_refreshRate; } - QString name() const { return m_name; } - QPlatformCursor *cursor() const { return m_cursor; } - QWindow *topLevelAt(const QPoint &point) const; - QList<QPlatformScreen *> virtualSiblings() const { return m_siblings; } + QPixmap grabWindow(WId window, int x, int y, int width, int height) const Q_DECL_OVERRIDE; + QRect geometry() const Q_DECL_OVERRIDE { return m_geometry; } + QRect availableGeometry() const Q_DECL_OVERRIDE { return m_availableGeometry; } + int depth() const Q_DECL_OVERRIDE { return m_depth; } + QImage::Format format() const Q_DECL_OVERRIDE { return m_format; } + qreal devicePixelRatio() const Q_DECL_OVERRIDE; + QSizeF physicalSize() const Q_DECL_OVERRIDE { return m_physicalSize; } + QDpi logicalDpi() const Q_DECL_OVERRIDE { return m_logicalDpi; } + qreal refreshRate() const Q_DECL_OVERRIDE { return m_refreshRate; } + QString name() const Q_DECL_OVERRIDE { return m_name; } + QPlatformCursor *cursor() const Q_DECL_OVERRIDE { return m_cursor; } + QWindow *topLevelAt(const QPoint &point) const Q_DECL_OVERRIDE; + QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; } // ---------------------------------------------------- // Additional methods @@ -102,29 +102,29 @@ public: static QCocoaIntegration *instance(); - bool hasCapability(QPlatformIntegration::Capability cap) const; - QPlatformWindow *createPlatformWindow(QWindow *window) const; + bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; + QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; #ifndef QT_NO_OPENGL - QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE; #endif - QPlatformBackingStore *createPlatformBackingStore(QWindow *widget) const; + QPlatformBackingStore *createPlatformBackingStore(QWindow *widget) const Q_DECL_OVERRIDE; - QAbstractEventDispatcher *createEventDispatcher() const; + QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; - QCoreTextFontDatabase *fontDatabase() const; - QCocoaNativeInterface *nativeInterface() const; - QCocoaInputContext *inputContext() const; - QCocoaAccessibility *accessibility() const; - QCocoaClipboard *clipboard() const; - QCocoaDrag *drag() const; + QCoreTextFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; + QCocoaNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; + QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE; + QCocoaAccessibility *accessibility() const Q_DECL_OVERRIDE; + QCocoaClipboard *clipboard() const Q_DECL_OVERRIDE; + QCocoaDrag *drag() const Q_DECL_OVERRIDE; - QStringList themeNames() const; - QPlatformTheme *createPlatformTheme(const QString &name) const; - QCocoaServices *services() const; - QVariant styleHint(StyleHint hint) const; + QStringList themeNames() const Q_DECL_OVERRIDE; + QPlatformTheme *createPlatformTheme(const QString &name) const Q_DECL_OVERRIDE; + QCocoaServices *services() const Q_DECL_OVERRIDE; + QVariant styleHint(StyleHint hint) const Q_DECL_OVERRIDE; - Qt::KeyboardModifiers queryKeyboardModifiers() const; - QList<int> possibleKeys(const QKeyEvent *event) const; + Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE; + QList<int> possibleKeys(const QKeyEvent *event) const Q_DECL_OVERRIDE; void updateScreens(); QCocoaScreen *screenAtIndex(int index); @@ -138,13 +138,13 @@ public: QCocoaWindow *activePopupWindow() const; QList<QCocoaWindow *> *popupWindowStack(); - void setApplicationIcon(const QIcon &icon) const; + void setApplicationIcon(const QIcon &icon) const Q_DECL_OVERRIDE; private: static QCocoaIntegration *mInstance; QScopedPointer<QCoreTextFontDatabase> mFontDb; - QScopedPointer<QCocoaInputContext> mInputContext; + QScopedPointer<QPlatformInputContext> mInputContext; #ifndef QT_NO_ACCESSIBILITY QScopedPointer<QCocoaAccessibility> mAccessibility; #endif diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 04d576904449b986e02ab9c03c1e14de7c2df113..545e920057a690a72395b8b34a9faf26d201d432 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -48,6 +48,7 @@ #include "qcocoaaccessibility.h" #include <qpa/qplatformaccessibility.h> +#include <qpa/qplatforminputcontextfactory_p.h> #include <QtCore/qcoreapplication.h> #include <IOKit/graphics/IOGraphicsLib.h> @@ -247,7 +248,6 @@ QCocoaIntegration *QCocoaIntegration::mInstance = 0; QCocoaIntegration::QCocoaIntegration() : mFontDb(new QCoreTextFontDatabase()) - , mInputContext(new QCocoaInputContext) #ifndef QT_NO_ACCESSIBILITY , mAccessibility(new QCocoaAccessibility) #endif @@ -261,6 +261,10 @@ QCocoaIntegration::QCocoaIntegration() qWarning("Creating multiple Cocoa platform integrations is not supported"); mInstance = this; + mInputContext.reset(QPlatformInputContextFactory::create()); + if (mInputContext.isNull()) + mInputContext.reset(new QCocoaInputContext()); + initResources(); QMacAutoReleasePool pool; @@ -462,7 +466,7 @@ QCocoaNativeInterface *QCocoaIntegration::nativeInterface() const return mNativeInterface.data(); } -QCocoaInputContext *QCocoaIntegration::inputContext() const +QPlatformInputContext *QCocoaIntegration::inputContext() const { return mInputContext.data(); } diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index 59807deb5a6c8e876abf548ae1b5aac66751571a..eccc5230b5d4962066e9708135e68d08ed86e55d 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -49,29 +49,29 @@ public: QCocoaMenu(); ~QCocoaMenu(); - inline virtual void setTag(quintptr tag) - { m_tag = tag; } - inline virtual quintptr tag() const - { return m_tag; } - - void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before); - void removeMenuItem(QPlatformMenuItem *menuItem); - void syncMenuItem(QPlatformMenuItem *menuItem); - void setEnabled(bool enabled); - bool isEnabled() const; - void setVisible(bool visible); - void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item); - void dismiss(); - - void syncSeparatorsCollapsible(bool enable); + void setTag(quintptr tag) Q_DECL_OVERRIDE + { m_tag = tag; } + quintptr tag() const Q_DECL_OVERRIDE + { return m_tag; } + + void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) Q_DECL_OVERRIDE; + void removeMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; + void syncMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; + void setEnabled(bool enabled) Q_DECL_OVERRIDE; + bool isEnabled() const Q_DECL_OVERRIDE; + void setVisible(bool visible) Q_DECL_OVERRIDE; + void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) Q_DECL_OVERRIDE; + void dismiss() Q_DECL_OVERRIDE; + + void syncSeparatorsCollapsible(bool enable) Q_DECL_OVERRIDE; void syncModalState(bool modal); - virtual void setIcon(const QIcon &icon) { Q_UNUSED(icon) } + void setIcon(const QIcon &icon) Q_DECL_OVERRIDE { Q_UNUSED(icon) } - void setText(const QString &text); - void setMinimumWidth(int width); - void setFont(const QFont &font); + void setText(const QString &text) Q_DECL_OVERRIDE; + void setMinimumWidth(int width) Q_DECL_OVERRIDE; + void setFont(const QFont &font) Q_DECL_OVERRIDE; inline NSMenu *nsMenu() const { return m_nativeMenu; } @@ -80,8 +80,8 @@ public: inline bool isVisible() const { return m_visible; } - virtual QPlatformMenuItem *menuItemAt(int position) const; - virtual QPlatformMenuItem *menuItemForTag(quintptr tag) const; + QPlatformMenuItem *menuItemAt(int position) const Q_DECL_OVERRIDE; + QPlatformMenuItem *menuItemForTag(quintptr tag) const Q_DECL_OVERRIDE; QList<QCocoaMenuItem *> items() const; QList<QCocoaMenuItem *> merged() const; diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index eb231f064ea032e67874e01ab9071a06cc4538c8..57739f3a586f1d77bd830b15cb206552d264cd02 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -162,6 +162,8 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); // Whatever the current first responder is, let's give it a chance // and do not touch the Qt's focusObject (which is different from some native view // having a focus inside NSSave/OpenPanel. + *target = nil; + *action = menuItem.action; return YES; } diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h index b5ee21ca52e436b1b0b72154d533cfe5994490e2..d5f75abf349bd191e5745966cefb2f1211847337 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.h +++ b/src/plugins/platforms/cocoa/qcocoamenubar.h @@ -48,13 +48,13 @@ class QCocoaMenuBar : public QPlatformMenuBar Q_OBJECT public: QCocoaMenuBar(); - virtual ~QCocoaMenuBar(); + ~QCocoaMenuBar(); - virtual void insertMenu(QPlatformMenu *menu, QPlatformMenu* before); - virtual void removeMenu(QPlatformMenu *menu); - virtual void syncMenu(QPlatformMenu *menuItem); - virtual void handleReparent(QWindow *newParentWindow); - virtual QPlatformMenu *menuForTag(quintptr tag) const; + void insertMenu(QPlatformMenu *menu, QPlatformMenu* before) Q_DECL_OVERRIDE; + void removeMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; + void syncMenu(QPlatformMenu *menuItem) Q_DECL_OVERRIDE; + void handleReparent(QWindow *newParentWindow) Q_DECL_OVERRIDE; + QPlatformMenu *menuForTag(quintptr tag) const Q_DECL_OVERRIDE; inline NSMenu *nsMenu() const { return m_nativeMenu; } diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h index 5c85824ab8c1b149531ed6185abe7be5b7f5d598..289f38fd18b5c9ccd44965283e82765e96682345 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.h +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h @@ -60,27 +60,27 @@ class QCocoaMenuItem : public QPlatformMenuItem { public: QCocoaMenuItem(); - virtual ~QCocoaMenuItem(); + ~QCocoaMenuItem(); - inline virtual void setTag(quintptr tag) + void setTag(quintptr tag) Q_DECL_OVERRIDE { m_tag = tag; } - inline virtual quintptr tag() const + quintptr tag() const Q_DECL_OVERRIDE { return m_tag; } - void setText(const QString &text); - void setIcon(const QIcon &icon); - void setMenu(QPlatformMenu *menu); - void setVisible(bool isVisible); - void setIsSeparator(bool isSeparator); - void setFont(const QFont &font); - void setRole(MenuRole role); - void setShortcut(const QKeySequence& shortcut); - void setCheckable(bool checkable) { Q_UNUSED(checkable) } - void setChecked(bool isChecked); - void setEnabled(bool isEnabled); - void setIconSize(int size); - - void setNativeContents(WId item); + void setText(const QString &text) Q_DECL_OVERRIDE; + void setIcon(const QIcon &icon) Q_DECL_OVERRIDE; + void setMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; + void setVisible(bool isVisible) Q_DECL_OVERRIDE; + void setIsSeparator(bool isSeparator) Q_DECL_OVERRIDE; + void setFont(const QFont &font) Q_DECL_OVERRIDE; + void setRole(MenuRole role) Q_DECL_OVERRIDE; + void setShortcut(const QKeySequence& shortcut) Q_DECL_OVERRIDE; + void setCheckable(bool checkable) Q_DECL_OVERRIDE { Q_UNUSED(checkable) } + void setChecked(bool isChecked) Q_DECL_OVERRIDE; + void setEnabled(bool isEnabled) Q_DECL_OVERRIDE; + void setIconSize(int size) Q_DECL_OVERRIDE; + + void setNativeContents(WId item) Q_DECL_OVERRIDE; inline QString text() const { return m_text; } inline NSMenuItem * nsItem() { return m_native; } diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h index 0b95fea7aeb2af080abbe135b76363b81d6d38a1..d018c05635746476750aed55c579d8bdc7773b98 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h @@ -54,9 +54,9 @@ public: QCocoaNativeInterface(); #ifndef QT_NO_OPENGL - void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context); + void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context) Q_DECL_OVERRIDE; #endif - void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window); + void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) Q_DECL_OVERRIDE; NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE; @@ -67,6 +67,8 @@ public: static void *nsOpenGLContextForContext(QOpenGLContext* context); #endif + QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE; + public Q_SLOTS: void onAppFocusWindowChanged(QWindow *window); diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index c8b54c922472ef73b2a301649eea4ff9f86d03da..41ea1fa49cd45582c549f7b7a92b9fa33e593e30 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -58,6 +58,8 @@ #include <qpa/qplatformprintersupport.h> #endif +#include <QtPlatformHeaders/qcocoawindowfunctions.h> + #include <Cocoa/Cocoa.h> QT_BEGIN_NAMESPACE @@ -217,6 +219,14 @@ void *QCocoaNativeInterface::nsOpenGLContextForContext(QOpenGLContext* context) } #endif +QFunctionPointer QCocoaNativeInterface::platformFunction(const QByteArray &function) const +{ + if (function == QCocoaWindowFunctions::bottomLeftClippedByNSWindowOffsetIdentifier()) + return QFunctionPointer(QCocoaWindowFunctions::BottomLeftClippedByNSWindowOffset(QCocoaWindow::bottomLeftClippedByNSWindowOffsetStatic)); + + return Q_NULLPTR; +} + void QCocoaNativeInterface::addToMimeList(void *macPasteboardMime) { qt_mac_addToGlobalMimeList(reinterpret_cast<QMacInternalPasteboardMime *>(macPasteboardMime)); diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm index 4d319e149b9fa77fe29dcb80b06ebaa14d15face..b0d04f6f82e0323fdabeec7b7423364f2b5f4f10 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm +++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm @@ -100,7 +100,7 @@ QCocoaPrintDevice::~QCocoaPrintDevice() { if (m_ppd) ppdClose(m_ppd); - foreach (PMPaper paper, m_macPapers.values()) + foreach (PMPaper paper, m_macPapers) PMRelease(paper); // Releasing the session appears to also release the printer if (m_session) @@ -154,7 +154,7 @@ QPageSize QCocoaPrintDevice::createPageSize(const PMPaper &paper) const void QCocoaPrintDevice::loadPageSizes() const { m_pageSizes.clear(); - foreach (PMPaper paper, m_macPapers.values()) + foreach (PMPaper paper, m_macPapers) PMRelease(paper); m_macPapers.clear(); m_printableMargins.clear(); diff --git a/src/plugins/platforms/cocoa/qcocoaservices.h b/src/plugins/platforms/cocoa/qcocoaservices.h index 331fe810fa37d924ef1f0574afe1ce9a6ebd9a56..1a447c624235b7c41cfc7ddfcc724e0a36be01a3 100644 --- a/src/plugins/platforms/cocoa/qcocoaservices.h +++ b/src/plugins/platforms/cocoa/qcocoaservices.h @@ -41,8 +41,8 @@ QT_BEGIN_NAMESPACE class QCocoaServices : public QPlatformServices { public: - bool openUrl(const QUrl &url); - bool openDocument(const QUrl &url); + bool openUrl(const QUrl &url) Q_DECL_OVERRIDE; + bool openDocument(const QUrl &url) Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h index b5f038094fc0422b9cc6bbd17f9498c3d9db553d..cdfd92c0aa6e4c01c80cba5f11a8c8701289eed3 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h @@ -51,17 +51,17 @@ class Q_GUI_EXPORT QCocoaSystemTrayIcon : public QPlatformSystemTrayIcon public: QCocoaSystemTrayIcon() : m_sys(0) {} - virtual void init(); - virtual void cleanup(); - virtual void updateIcon(const QIcon &icon); - virtual void updateToolTip(const QString &toolTip); - virtual void updateMenu(QPlatformMenu *menu); - virtual QRect geometry() const; - virtual void showMessage(const QString &title, const QString &msg, - const QIcon& icon, MessageIcon iconType, int secs); + void init() Q_DECL_OVERRIDE; + void cleanup() Q_DECL_OVERRIDE; + void updateIcon(const QIcon &icon) Q_DECL_OVERRIDE; + void updateToolTip(const QString &toolTip) Q_DECL_OVERRIDE; + void updateMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; + QRect geometry() const Q_DECL_OVERRIDE; + void showMessage(const QString &title, const QString &msg, + const QIcon& icon, MessageIcon iconType, int secs) Q_DECL_OVERRIDE; - virtual bool isSystemTrayAvailable() const; - virtual bool supportsMessages() const; + bool isSystemTrayAvailable() const Q_DECL_OVERRIDE; + bool supportsMessages() const Q_DECL_OVERRIDE; private: QSystemTrayIconSys *m_sys; diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index f50f55262375ee36611bfbadcdbbcb7f344a5d28..a3ffb5be66d69709b855b00e45e51a0e62289452 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -252,6 +252,7 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon) } NSImage *nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(fullHeightPixmap)); + [nsimage setTemplate:icon.isMask()]; [(NSImageView*)[[m_sys->item item] view] setImage: nsimage]; [nsimage release]; } @@ -446,6 +447,7 @@ QT_END_NAMESPACE -(void)dealloc { [[NSStatusBar systemStatusBar] removeStatusItem:item]; + [[NSNotificationCenter defaultCenter] removeObserver:imageCell]; [imageCell release]; [item release]; [super dealloc]; diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h index 203f05c8bb0467dbd4b27507ff2c612794734034..0cd7b7d4c82e224645c61fda2eddcb8cd7908d84 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.h +++ b/src/plugins/platforms/cocoa/qcocoatheme.h @@ -46,25 +46,25 @@ public: QCocoaTheme(); ~QCocoaTheme(); - virtual QPlatformMenuItem* createPlatformMenuItem() const; - virtual QPlatformMenu* createPlatformMenu() const; - virtual QPlatformMenuBar* createPlatformMenuBar() const; + QPlatformMenuItem* createPlatformMenuItem() const Q_DECL_OVERRIDE; + QPlatformMenu* createPlatformMenu() const Q_DECL_OVERRIDE; + QPlatformMenuBar* createPlatformMenuBar() const Q_DECL_OVERRIDE; #ifndef QT_NO_SYSTEMTRAYICON - QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const; + QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const Q_DECL_OVERRIDE; #endif - bool usePlatformNativeDialog(DialogType dialogType) const; - QPlatformDialogHelper *createPlatformDialogHelper(DialogType dialogType) const; + bool usePlatformNativeDialog(DialogType dialogType) const Q_DECL_OVERRIDE; + QPlatformDialogHelper *createPlatformDialogHelper(DialogType dialogType) const Q_DECL_OVERRIDE; - const QPalette *palette(Palette type = SystemPalette) const; - const QFont *font(Font type = SystemFont) const; - QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const; + const QPalette *palette(Palette type = SystemPalette) const Q_DECL_OVERRIDE; + const QFont *font(Font type = SystemFont) const Q_DECL_OVERRIDE; + QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const Q_DECL_OVERRIDE; QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size, - QPlatformTheme::IconOptions options = 0) const; + QPlatformTheme::IconOptions options = 0) const Q_DECL_OVERRIDE; - QVariant themeHint(ThemeHint hint) const; + QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE; QString standardButtonText(int button) const Q_DECL_OVERRIDE; static const char *name; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index e2ab71a890fb1988994536ce83aad477510a6afd..9f74828f2d0593619852eef16ae3d6aea7b922a5 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -142,37 +142,37 @@ public: QCocoaWindow(QWindow *tlw); ~QCocoaWindow(); - void setGeometry(const QRect &rect); - QRect geometry() const; + void setGeometry(const QRect &rect) Q_DECL_OVERRIDE; + QRect geometry() const Q_DECL_OVERRIDE; void setCocoaGeometry(const QRect &rect); void clipChildWindows(); void clipWindow(const NSRect &clipRect); void show(bool becauseOfAncestor = false); void hide(bool becauseOfAncestor = false); - void setVisible(bool visible); - void setWindowFlags(Qt::WindowFlags flags); - void setWindowState(Qt::WindowState state); - void setWindowTitle(const QString &title); - void setWindowFilePath(const QString &filePath); - void setWindowIcon(const QIcon &icon); - void setAlertState(bool enabled); - bool isAlertState() const; - void raise(); - void lower(); - bool isExposed() const; + void setVisible(bool visible) Q_DECL_OVERRIDE; + void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE; + void setWindowState(Qt::WindowState state) Q_DECL_OVERRIDE; + void setWindowTitle(const QString &title) Q_DECL_OVERRIDE; + void setWindowFilePath(const QString &filePath) Q_DECL_OVERRIDE; + void setWindowIcon(const QIcon &icon) Q_DECL_OVERRIDE; + void setAlertState(bool enabled) Q_DECL_OVERRIDE; + bool isAlertState() const Q_DECL_OVERRIDE; + void raise() Q_DECL_OVERRIDE; + void lower() Q_DECL_OVERRIDE; + bool isExposed() const Q_DECL_OVERRIDE; bool isOpaque() const; - void propagateSizeHints(); - void setOpacity(qreal level); - void setMask(const QRegion ®ion); - bool setKeyboardGrabEnabled(bool grab); - bool setMouseGrabEnabled(bool grab); - QMargins frameMargins() const; - QSurfaceFormat format() const; + void propagateSizeHints() Q_DECL_OVERRIDE; + void setOpacity(qreal level) Q_DECL_OVERRIDE; + void setMask(const QRegion ®ion) Q_DECL_OVERRIDE; + bool setKeyboardGrabEnabled(bool grab) Q_DECL_OVERRIDE; + bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE; + QMargins frameMargins() const Q_DECL_OVERRIDE; + QSurfaceFormat format() const Q_DECL_OVERRIDE; - void requestActivateWindow(); + void requestActivateWindow() Q_DECL_OVERRIDE; - WId winId() const; - void setParent(const QPlatformWindow *window); + WId winId() const Q_DECL_OVERRIDE; + void setParent(const QPlatformWindow *window) Q_DECL_OVERRIDE; NSView *contentView() const; void setContentView(NSView *contentView); @@ -202,8 +202,8 @@ public: bool setWindowModified(bool modified) Q_DECL_OVERRIDE; - void setFrameStrutEventsEnabled(bool enabled); - bool frameStrutEventsEnabled() const + void setFrameStrutEventsEnabled(bool enabled) Q_DECL_OVERRIDE; + bool frameStrutEventsEnabled() const Q_DECL_OVERRIDE { return m_frameStrutEventsEnabled; } void setMenubar(QCocoaMenuBar *mb); @@ -220,13 +220,16 @@ public: void applyContentBorderThickness(NSWindow *window); void updateNSToolbar(); - qreal devicePixelRatio() const; + qreal devicePixelRatio() const Q_DECL_OVERRIDE; bool isWindowExposable(); void exposeWindow(); void obscureWindow(); void updateExposedGeometry(); QWindow *childWindowAt(QPoint windowPoint); bool shouldRefuseKeyWindowAndFirstResponder(); + + static QPoint bottomLeftClippedByNSWindowOffsetStatic(QWindow *window); + QPoint bottomLeftClippedByNSWindowOffset() const; protected: void recreateWindow(const QPlatformWindow *parentWindow); QCocoaNSWindow *createNSWindow(); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index e5fedcd051bb63d065b307b6f1f98ba0eddbe741..e1d09c0400fcb672787e4278bf6939eb6e8502b3 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -749,7 +749,7 @@ void QCocoaWindow::setVisible(bool visible) } removeMonitor(); - if (window()->type() == Qt::Popup) + if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) QCocoaIntegration::instance()->popupWindowStack()->removeAll(this); if (parentCocoaWindow && window()->type() == Qt::Popup) { @@ -1839,6 +1839,25 @@ bool QCocoaWindow::shouldRefuseKeyWindowAndFirstResponder() return false; } +QPoint QCocoaWindow::bottomLeftClippedByNSWindowOffsetStatic(QWindow *window) +{ + if (window->handle()) + return static_cast<QCocoaWindow *>(window->handle())->bottomLeftClippedByNSWindowOffset(); + return QPoint(); +} + +QPoint QCocoaWindow::bottomLeftClippedByNSWindowOffset() const +{ + if (!m_contentView) + return QPoint(); + NSPoint origin = [m_contentView isFlipped] ? + NSMakePoint(0, [m_contentView frame].size.height) : + NSMakePoint(0, 0); + NSPoint windowPoint = [m_contentView convertPoint:origin toView:nil]; + + return QPoint(-std::min((int)windowPoint.x, 0), -std::min((int)windowPoint.y,0)); +} + QMargins QCocoaWindow::frameMargins() const { NSRect frameW = [m_nsWindow frame]; diff --git a/src/plugins/platforms/cocoa/qmultitouch_mac.mm b/src/plugins/platforms/cocoa/qmultitouch_mac.mm index 6e7ebcc37ce368a5569f7130d39fd5ee7c39a851..6099add6bbbf5356d08ae308188c1c975065fd04 100644 --- a/src/plugins/platforms/cocoa/qmultitouch_mac.mm +++ b/src/plugins/platforms/cocoa/qmultitouch_mac.mm @@ -173,7 +173,7 @@ QCocoaTouch::getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch) if (_touchCount != _currentTouches.size()) { // Remove all instances, and basically start from scratch: touchPoints.clear(); - foreach (QCocoaTouch *qcocoaTouch, _currentTouches.values()) { + foreach (QCocoaTouch *qcocoaTouch, _currentTouches) { if (!_updateInternalStateOnly) { qcocoaTouch->_touchPoint.state = Qt::TouchPointReleased; touchPoints.insert(qcocoaTouch->_touchPoint.id, qcocoaTouch->_touchPoint); @@ -190,7 +190,7 @@ QCocoaTouch::getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch) // touch now (and refake a begin for it later, if needed). if (_updateInternalStateOnly && !wasUpdateInternalStateOnly && !_currentTouches.isEmpty()) { - QCocoaTouch *qcocoaTouch = _currentTouches.values().first(); + QCocoaTouch *qcocoaTouch = _currentTouches.cbegin().value(); qcocoaTouch->_touchPoint.state = Qt::TouchPointReleased; touchPoints.insert(qcocoaTouch->_touchPoint.id, qcocoaTouch->_touchPoint); // Since this last touch also will end up being the first diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 32bc15d0927d19ad9b52779581714a7c0396e565..05ab8ae2c705fb6cd8b91dc57d41ef58f29b9f71 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -57,7 +57,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); CGImageRef m_maskImage; uchar *m_maskData; bool m_shouldInvalidateWindowShadow; - QWindow *m_window; + QPointer<QWindow> m_window; QCocoaWindow *m_platformWindow; NSTrackingArea *m_trackingArea; Qt::MouseButtons m_buttons; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index c71c9f0680afe1adc111f102a5daad40b4db9e2d..4309702fd51f1b635e7a21b345318584aa27b524 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -613,7 +613,7 @@ QT_WARNING_POP - (BOOL)becomeFirstResponder { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return NO; if (!m_platformWindow->windowIsPopupType()) QWindowSystemInterface::handleWindowActivated([self topLevelWindow]); @@ -624,7 +624,7 @@ QT_WARNING_POP { if (m_platformWindow->shouldRefuseKeyWindowAndFirstResponder()) return NO; - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return NO; if ((m_window->flags() & Qt::ToolTip) == Qt::ToolTip) return NO; @@ -634,7 +634,7 @@ QT_WARNING_POP - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { Q_UNUSED(theEvent) - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return NO; return YES; } @@ -773,7 +773,7 @@ QT_WARNING_POP - (void)mouseDown:(NSEvent *)theEvent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super mouseDown:theEvent]; m_sendUpAsRightButton = false; @@ -824,7 +824,7 @@ QT_WARNING_POP - (void)mouseDragged:(NSEvent *)theEvent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super mouseDragged:theEvent]; if (!(m_buttons & (m_sendUpAsRightButton ? Qt::RightButton : Qt::LeftButton))) qWarning("QNSView mouseDragged: Internal mouse button tracking invalid (missing Qt::LeftButton)"); @@ -833,7 +833,7 @@ QT_WARNING_POP - (void)mouseUp:(NSEvent *)theEvent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super mouseUp:theEvent]; if (m_sendUpAsRightButton) { m_buttons &= ~Qt::RightButton; @@ -889,7 +889,7 @@ QT_WARNING_POP - (void)mouseMovedImpl:(NSEvent *)theEvent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return; QPointF windowPoint; @@ -922,7 +922,7 @@ QT_WARNING_POP Q_UNUSED(theEvent) m_platformWindow->m_windowUnderMouse = true; - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return; // Top-level windows generate enter events for sub-windows. @@ -941,7 +941,7 @@ QT_WARNING_POP Q_UNUSED(theEvent); m_platformWindow->m_windowUnderMouse = false; - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return; // Top-level windows generate leave events for sub-windows. @@ -954,7 +954,7 @@ QT_WARNING_POP - (void)rightMouseDown:(NSEvent *)theEvent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super rightMouseDown:theEvent]; m_buttons |= Qt::RightButton; m_sendUpAsRightButton = true; @@ -963,7 +963,7 @@ QT_WARNING_POP - (void)rightMouseDragged:(NSEvent *)theEvent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super rightMouseDragged:theEvent]; if (!(m_buttons & Qt::RightButton)) qWarning("QNSView rightMouseDragged: Internal mouse button tracking invalid (missing Qt::RightButton)"); @@ -972,7 +972,7 @@ QT_WARNING_POP - (void)rightMouseUp:(NSEvent *)theEvent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super rightMouseUp:theEvent]; m_buttons &= ~Qt::RightButton; m_sendUpAsRightButton = false; @@ -981,7 +981,7 @@ QT_WARNING_POP - (void)otherMouseDown:(NSEvent *)theEvent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super otherMouseDown:theEvent]; m_buttons |= cocoaButton2QtButton([theEvent buttonNumber]); [self handleMouseEvent:theEvent]; @@ -989,7 +989,7 @@ QT_WARNING_POP - (void)otherMouseDragged:(NSEvent *)theEvent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super otherMouseDragged:theEvent]; if (!(m_buttons & ~(Qt::LeftButton | Qt::RightButton))) qWarning("QNSView otherMouseDragged: Internal mouse button tracking invalid (missing Qt::MiddleButton or Qt::ExtraButton*)"); @@ -998,7 +998,7 @@ QT_WARNING_POP - (void)otherMouseUp:(NSEvent *)theEvent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super otherMouseUp:theEvent]; m_buttons &= ~cocoaButton2QtButton([theEvent buttonNumber]); [self handleMouseEvent:theEvent]; @@ -1077,7 +1077,7 @@ Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHash, tabletDeviceDataHash) - (void)tabletPoint: (NSEvent *)theEvent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super tabletPoint:theEvent]; [self handleTabletEvent: theEvent]; @@ -1125,7 +1125,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) - (void)tabletProximity: (NSEvent *)theEvent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super tabletProximity:theEvent]; ulong timestamp = [theEvent timestamp] * 1000; @@ -1297,7 +1297,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) #ifndef QT_NO_WHEELEVENT - (void)scrollWheel:(NSEvent *)theEvent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super scrollWheel:theEvent]; QPoint angleDelta; @@ -1436,7 +1436,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) if (eventType == QEvent::KeyPress) { if (m_composingText.isEmpty()) - m_sendKeyEvent = !QWindowSystemInterface::tryHandleShortcutEvent(focusWindow, timestamp, keyCode, modifiers, text); + m_sendKeyEvent = !QWindowSystemInterface::tryHandleShortcutEvent(focusWindow, timestamp, keyCode, modifiers, text, [nsevent isARepeat], 1); QObject *fo = QGuiApplication::focusObject(); if (m_sendKeyEvent && fo) { @@ -1470,14 +1470,14 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) - (void)keyDown:(NSEvent *)nsevent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super keyDown:nsevent]; [self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)]; } - (void)keyUp:(NSEvent *)nsevent { - if (m_window->flags() & Qt::WindowTransparentForInput) + if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super keyUp:nsevent]; [self handleKeyEvent:nsevent eventType:int(QEvent::KeyRelease)]; } @@ -1918,8 +1918,9 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers: [[NSApp currentEvent] modifierFlags]]; QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect()); - if ([sender draggingSource] != nil) { - QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); + QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); + if (nativeDrag->currentDrag()) { + // The drag was started from within the application response = QWindowSystemInterface::handleDrag(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); [self updateCursorFromDragResponse:response drag:nativeDrag]; } else { @@ -1955,8 +1956,9 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]); QPlatformDropQtResponse response(false, Qt::IgnoreAction); - if ([sender draggingSource] != nil) { - QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); + QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); + if (nativeDrag->currentDrag()) { + // The drag was started from within the application response = QWindowSystemInterface::handleDrop(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); } else { QCocoaDropData mimeData([sender draggingPasteboard]); diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm index 1131fb5fc6e41996613cf2f22f4beaa1b9369dde..a6b445691640ec431c6047f1b40d8baa6a78edf6 100644 --- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm @@ -559,7 +559,7 @@ QCoreGraphicsPaintEngine::begin(QPaintDevice *pdev) if ((w->windowType() == Qt::Desktop)) { if (!unclipped) - qWarning("QCoreGraphicsPaintEngine::begin: Does not support clipped desktop on Mac OS X"); + qWarning("QCoreGraphicsPaintEngine::begin: Does not support clipped desktop on OS X"); // ## need to do [qt_mac_window_for(w) makeKeyAndOrderFront]; (need to rename the file) } else if (unclipped) { qWarning("QCoreGraphicsPaintEngine::begin: Does not support unclipped painting"); diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm index cb3e6e2cc57926baaa2181f7405d0d05dd200f64..edd1d656f061a68a96b40080b1e9325e7cb6b9f7 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm @@ -211,6 +211,9 @@ int QMacPrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const case QPaintDevice::PdmDevicePixelRatio: val = 1; break; + case QPaintDevice::PdmDevicePixelRatioScaled: + val = 1 * QPaintDevice::devicePixelRatioFScale(); + break; default: val = 0; qWarning("QPrinter::metric: Invalid metric command"); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp index fee9ad88fadfd9eb626135b553ae1b4bb3891e2b..40709fc3d0b3b0028bfb6127714bf7e96872ff75 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp @@ -113,6 +113,9 @@ int QWindowsDirect2DPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) case QPaintDevice::PdmDevicePixelRatio: return 1; break; + case QPaintDevice::PdmDevicePixelRatioScaled: + return 1 * devicePixelRatioFScale(); + break; case QPaintDevice::PdmWidthMM: case QPaintDevice::PdmHeightMM: return -1; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp index 18a66e34f5c8e480074b9972b6c712de39941308..f3df1f8445927e5fccce1ff6ce896ac35fbc420b 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp @@ -208,6 +208,7 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr } QList<drmModeModeInfo> modes; + modes.reserve(connector->count_modes); qCDebug(qLcEglfsKmsDebug) << connectorName << "mode count:" << connector->count_modes; for (int i = 0; i < connector->count_modes; i++) { const drmModeModeInfo &mode = connector->modes[i]; @@ -282,7 +283,8 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr selected_mode, false, drmModeGetCrtc(m_dri_fd, crtc_id), - modes + modes, + connectorProperty(connector, QByteArrayLiteral("DPMS")) }; m_crtc_allocator |= (1 << output.crtc_id); @@ -291,6 +293,22 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr return new QEglFSKmsScreen(m_integration, this, output, pos); } +drmModePropertyPtr QEglFSKmsDevice::connectorProperty(drmModeConnectorPtr connector, const QByteArray &name) +{ + drmModePropertyPtr prop; + + for (int i = 0; i < connector->count_props; i++) { + prop = drmModeGetProperty(m_dri_fd, connector->props[i]); + if (!prop) + continue; + if (strcmp(prop->name, name.constData()) == 0) + return prop; + drmModeFreeProperty(prop); + } + + return Q_NULLPTR; +} + void QEglFSKmsDevice::pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) { Q_UNUSED(fd); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h index 23fca934e5bc3456694b6c94d66d3666b2d1eec7..411f9a72003d2d43bf9bbf8983384d488120a2ef 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h @@ -78,6 +78,7 @@ private: int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector); QEglFSKmsScreen *screenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, QPoint pos); + drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const QByteArray &name); static void pageFlipHandler(int fd, unsigned int sequence, diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp index 45224ccb87b688ec661df53d5512f6b47d5395a4..d1814fb85dbc04ce798cc6add77d89d2ec76f086 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp @@ -36,8 +36,8 @@ #include "qeglfskmsdevice.h" #include "qeglfskmsscreen.h" #include "qeglfskmscursor.h" +#include "qeglfscursor.h" -#include <QtPlatformSupport/private/qeglplatformcursor_p.h> #include <QtPlatformSupport/private/qdevicediscovery_p.h> #include <QtCore/QLoggingCategory> #include <QtCore/QJsonDocument> @@ -176,7 +176,7 @@ QPlatformCursor *QEglFSKmsIntegration::createCursor(QPlatformScreen *screen) con if (m_hwCursor) return Q_NULLPTR; else - return new QEGLPlatformCursor(screen); + return new QEglFSCursor(screen); } void QEglFSKmsIntegration::waitForVSync(QPlatformSurface *surface) const diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp index 5e49c224a0dfbcf567f0d945e8abdfec56c69b05..227c8f9a620a3b0724ba592c877c72d84bdb6bfa 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp @@ -35,11 +35,11 @@ #include "qeglfskmsscreen.h" #include "qeglfskmsdevice.h" #include "qeglfskmscursor.h" +#include "qeglfsintegration.h" #include <QtCore/QLoggingCategory> #include <QtGui/private/qguiapplication_p.h> -#include <QtPlatformSupport/private/qeglplatformintegration_p.h> #include <QtPlatformSupport/private/qfbvthandler_p.h> QT_BEGIN_NAMESPACE @@ -50,7 +50,7 @@ class QEglFSKmsInterruptHandler : public QObject { public: QEglFSKmsInterruptHandler(QEglFSKmsScreen *screen) : m_screen(screen) { - m_vtHandler = static_cast<QEGLPlatformIntegration *>(QGuiApplicationPrivate::platformIntegration())->vtHandler(); + m_vtHandler = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration())->vtHandler(); connect(m_vtHandler, &QFbVtHandler::interrupted, this, &QEglFSKmsInterruptHandler::restoreVideoMode); connect(m_vtHandler, &QFbVtHandler::suspendRequested, this, &QEglFSKmsInterruptHandler::handleSuspendRequest); } @@ -119,6 +119,7 @@ QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration, , m_output(output) , m_pos(position) , m_cursor(Q_NULLPTR) + , m_powerState(PowerStateOn) , m_interruptHandler(new QEglFSKmsInterruptHandler(this)) { m_siblings << this; @@ -126,6 +127,10 @@ QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration, QEglFSKmsScreen::~QEglFSKmsScreen() { + if (m_output.dpms_prop) { + drmModeFreeProperty(m_output.dpms_prop); + m_output.dpms_prop = Q_NULLPTR; + } restoreMode(); if (m_output.saved_crtc) { drmModeFreeCrtc(m_output.saved_crtc); @@ -266,10 +271,12 @@ void QEglFSKmsScreen::flip() &m_output.connector_id, 1, &m_output.modes[m_output.mode]); - if (ret) + if (ret) { qErrnoWarning("Could not set DRM mode!"); - else + } else { m_output.mode_set = true; + setPowerState(PowerStateOn); + } } int ret = drmModePageFlip(m_device->fd(), @@ -314,4 +321,19 @@ qreal QEglFSKmsScreen::refreshRate() const return refresh > 0 ? refresh : 60; } +QPlatformScreen::PowerState QEglFSKmsScreen::powerState() const +{ + return m_powerState; +} + +void QEglFSKmsScreen::setPowerState(QPlatformScreen::PowerState state) +{ + if (!m_output.dpms_prop) + return; + + drmModeConnectorSetProperty(m_device->fd(), m_output.connector_id, + m_output.dpms_prop->prop_id, (int)state); + m_powerState = state; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h index 4c1b0d02ad2fbda40027a8b4af7b54e17c789629..2ce8700478282090a3a67b7ffce50544c1043231 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h @@ -60,6 +60,7 @@ struct QEglFSKmsOutput bool mode_set; drmModeCrtcPtr saved_crtc; QList<drmModeModeInfo> modes; + drmModePropertyPtr dpms_prop; }; class QEglFSKmsScreen : public QEglFSScreen @@ -103,6 +104,9 @@ public: QEglFSKmsOutput &output() { return m_output; } void restoreMode(); + QPlatformScreen::PowerState powerState() const Q_DECL_OVERRIDE; + void setPowerState(QPlatformScreen::PowerState state) Q_DECL_OVERRIDE; + private: QEglFSKmsIntegration *m_integration; QEglFSKmsDevice *m_device; @@ -117,6 +121,8 @@ private: QList<QPlatformScreen *> m_siblings; + PowerState m_powerState; + struct FrameBuffer { FrameBuffer() : fb(0) {} uint32_t fb; diff --git a/src/plugins/platforms/eglfs/eglfs_device_lib.pro b/src/plugins/platforms/eglfs/eglfs_device_lib.pro index 729290706df9e4fc3468bbe842c7d9491ce173e9..22a32663c7a78f40dd6e27cef00830b653adb79a 100644 --- a/src/plugins/platforms/eglfs/eglfs_device_lib.pro +++ b/src/plugins/platforms/eglfs/eglfs_device_lib.pro @@ -26,6 +26,7 @@ DEFINES += QT_BUILD_EGL_DEVICE_LIB SOURCES += $$PWD/qeglfsintegration.cpp \ $$PWD/qeglfswindow.cpp \ $$PWD/qeglfsscreen.cpp \ + $$PWD/qeglfscursor.cpp \ $$PWD/qeglfshooks.cpp \ $$PWD/qeglfscontext.cpp \ $$PWD/qeglfsoffscreenwindow.cpp \ @@ -34,6 +35,7 @@ SOURCES += $$PWD/qeglfsintegration.cpp \ HEADERS += $$PWD/qeglfsintegration.h \ $$PWD/qeglfswindow.h \ $$PWD/qeglfsscreen.h \ + $$PWD/qeglfscursor.h \ $$PWD/qeglfshooks.h \ $$PWD/qeglfscontext.h \ $$PWD/qeglfsoffscreenwindow.h \ diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp index 9216b7a85debb46df22461c9900c9c5788637f56..e2223aba4380781af7d67f5bde1e92c1c21c9065 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp @@ -32,15 +32,13 @@ ****************************************************************************/ #include <QtGui/QSurface> -#include <QtDebug> - -#include <QtPlatformSupport/private/qeglplatformcursor_p.h> #include <QtPlatformSupport/private/qeglconvenience_p.h> #include <QtPlatformSupport/private/qeglpbuffer_p.h> +#include "qeglfscontext.h" #include "qeglfswindow.h" #include "qeglfshooks.h" -#include "qeglfscontext.h" +#include "qeglfscursor.h" QT_BEGIN_NAMESPACE @@ -91,7 +89,7 @@ void QEglFSContext::swapBuffers(QPlatformSurface *surface) // draw the cursor if (surface->surface()->surfaceClass() == QSurface::Window) { QPlatformWindow *window = static_cast<QPlatformWindow *>(surface); - if (QEGLPlatformCursor *cursor = qobject_cast<QEGLPlatformCursor *>(window->screen()->cursor())) + if (QEglFSCursor *cursor = qobject_cast<QEglFSCursor *>(window->screen()->cursor())) cursor->paintOnScreen(); } diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp b/src/plugins/platforms/eglfs/qeglfscursor.cpp similarity index 89% rename from src/platformsupport/eglconvenience/qeglplatformcursor.cpp rename to src/plugins/platforms/eglfs/qeglfscursor.cpp index 09243487c700ddf230fa858d73c0c5763b9447b2..d81aa2eaf2beaad992f0a11666cd87bd2eb09a76 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp +++ b/src/plugins/platforms/eglfs/qeglfscursor.cpp @@ -31,33 +31,24 @@ ** ****************************************************************************/ +#include "qeglfscursor.h" +#include "qeglfsintegration.h" +#include "qeglfsscreen.h" + #include <qpa/qwindowsysteminterface.h> #include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLShaderProgram> #include <QtCore/QJsonDocument> #include <QtCore/QJsonArray> #include <QtCore/QJsonObject> -#include <QtDebug> #include <QtGui/private/qguiapplication_p.h> -#include "qeglplatformcursor_p.h" -#include "qeglplatformintegration_p.h" -#include "qeglplatformscreen_p.h" - QT_BEGIN_NAMESPACE -/*! - \class QEGLPlatformCursor - \brief Mouse cursor implementation using OpenGL. - \since 5.2 - \internal - \ingroup qpa - */ - -QEGLPlatformCursor::QEGLPlatformCursor(QPlatformScreen *screen) +QEglFSCursor::QEglFSCursor(QPlatformScreen *screen) : m_visible(true), - m_screen(static_cast<QEGLPlatformScreen *>(screen)), + m_screen(static_cast<QEglFSScreen *>(screen)), m_program(0), m_vertexCoordEntry(0), m_textureCoordEntry(0), @@ -81,35 +72,35 @@ QEGLPlatformCursor::QEGLPlatformCursor(QPlatformScreen *screen) setCurrentCursor(&cursor); #endif - m_deviceListener = new QEGLPlatformCursorDeviceListener(this); + m_deviceListener = new QEglFSCursorDeviceListener(this); connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged, - m_deviceListener, &QEGLPlatformCursorDeviceListener::onDeviceListChanged); + m_deviceListener, &QEglFSCursorDeviceListener::onDeviceListChanged); updateMouseStatus(); } -QEGLPlatformCursor::~QEGLPlatformCursor() +QEglFSCursor::~QEglFSCursor() { resetResources(); delete m_deviceListener; } -void QEGLPlatformCursor::updateMouseStatus() +void QEglFSCursor::updateMouseStatus() { m_visible = m_deviceListener->hasMouse(); } -bool QEGLPlatformCursorDeviceListener::hasMouse() const +bool QEglFSCursorDeviceListener::hasMouse() const { return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0; } -void QEGLPlatformCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type) +void QEglFSCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type) { if (type == QInputDeviceManager::DeviceTypePointer) m_cursor->updateMouseStatus(); } -void QEGLPlatformCursor::resetResources() +void QEglFSCursor::resetResources() { if (QOpenGLContext::currentContext()) { delete m_program; @@ -122,7 +113,7 @@ void QEGLPlatformCursor::resetResources() m_cursorAtlas.texture = 0; } -void QEGLPlatformCursor::createShaderPrograms() +void QEglFSCursor::createShaderPrograms() { static const char *textureVertexProgram = "attribute highp vec2 vertexCoordEntry;\n" @@ -150,7 +141,7 @@ void QEGLPlatformCursor::createShaderPrograms() m_textureEntry = m_program->uniformLocation("texture"); } -void QEGLPlatformCursor::createCursorTexture(uint *texture, const QImage &image) +void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image) { if (!*texture) glGenTextures(1, texture); @@ -164,7 +155,7 @@ void QEGLPlatformCursor::createCursorTexture(uint *texture, const QImage &image) GL_RGBA, GL_UNSIGNED_BYTE, image.constBits()); } -void QEGLPlatformCursor::initCursorAtlas() +void QEglFSCursor::initCursorAtlas() { static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR"); if (json.isEmpty()) @@ -202,7 +193,7 @@ void QEGLPlatformCursor::initCursorAtlas() } #ifndef QT_NO_CURSOR -void QEGLPlatformCursor::changeCursor(QCursor *cursor, QWindow *window) +void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window) { Q_UNUSED(window); const QRect oldCursorRect = cursorRect(); @@ -210,7 +201,7 @@ void QEGLPlatformCursor::changeCursor(QCursor *cursor, QWindow *window) update(oldCursorRect | cursorRect()); } -bool QEGLPlatformCursor::setCurrentCursor(QCursor *cursor) +bool QEglFSCursor::setCurrentCursor(QCursor *cursor) { if (!m_visible) return false; @@ -263,7 +254,7 @@ private: QRegion m_region; }; -bool QEGLPlatformCursor::event(QEvent *e) +bool QEglFSCursor::event(QEvent *e) { if (e->type() == QEvent::User + 1) { CursorUpdateEvent *ev = static_cast<CursorUpdateEvent *>(e); @@ -275,7 +266,7 @@ bool QEGLPlatformCursor::event(QEvent *e) return QPlatformCursor::event(e); } -void QEGLPlatformCursor::update(const QRegion &rgn) +void QEglFSCursor::update(const QRegion &rgn) { if (!m_updateRequested) { // Must not flush the window system events directly from here since we are likely to @@ -286,17 +277,17 @@ void QEGLPlatformCursor::update(const QRegion &rgn) } } -QRect QEGLPlatformCursor::cursorRect() const +QRect QEglFSCursor::cursorRect() const { return QRect(m_cursor.pos - m_cursor.hotSpot, m_cursor.size); } -QPoint QEGLPlatformCursor::pos() const +QPoint QEglFSCursor::pos() const { return m_cursor.pos; } -void QEGLPlatformCursor::setPos(const QPoint &pos) +void QEglFSCursor::setPos(const QPoint &pos) { QGuiApplicationPrivate::inputDeviceManager()->setCursorPos(pos); const QRect oldCursorRect = cursorRect(); @@ -305,7 +296,7 @@ void QEGLPlatformCursor::setPos(const QPoint &pos) m_screen->handleCursorMove(m_cursor.pos); } -void QEGLPlatformCursor::pointerEvent(const QMouseEvent &event) +void QEglFSCursor::pointerEvent(const QMouseEvent &event) { if (event.type() != QEvent::MouseMove) return; @@ -315,7 +306,7 @@ void QEGLPlatformCursor::pointerEvent(const QMouseEvent &event) m_screen->handleCursorMove(m_cursor.pos); } -void QEGLPlatformCursor::paintOnScreen() +void QEglFSCursor::paintOnScreen() { if (!m_visible) return; @@ -331,7 +322,7 @@ void QEGLPlatformCursor::paintOnScreen() draw(r); } -void QEGLPlatformCursor::draw(const QRectF &r) +void QEglFSCursor::draw(const QRectF &r) { if (!m_program) { // one time initialization diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h b/src/plugins/platforms/eglfs/qeglfscursor.h similarity index 87% rename from src/platformsupport/eglconvenience/qeglplatformcursor_p.h rename to src/plugins/platforms/eglfs/qeglfscursor.h index b89dd1ca4388bb2ed1b8728d4bfb7c7440510d3f..048f276137af2acf8ed713c659fe296dfd169a71 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h +++ b/src/plugins/platforms/eglfs/qeglfscursor.h @@ -31,8 +31,8 @@ ** ****************************************************************************/ -#ifndef QEGLPLATFORMCURSOR_H -#define QEGLPLATFORMCURSOR_H +#ifndef QEGLFSCURSOR_H +#define QEGLFSCURSOR_H // // W A R N I N G @@ -45,6 +45,7 @@ // We mean it. // +#include "qeglfsglobal.h" #include <qpa/qplatformcursor.h> #include <qpa/qplatformscreen.h> #include <QtGui/QOpenGLFunctions> @@ -53,30 +54,30 @@ QT_BEGIN_NAMESPACE class QOpenGLShaderProgram; -class QEGLPlatformCursor; -class QEGLPlatformScreen; +class QEglFSCursor; +class QEglFSScreen; -class QEGLPlatformCursorDeviceListener : public QObject +class QEglFSCursorDeviceListener : public QObject { Q_OBJECT public: - QEGLPlatformCursorDeviceListener(QEGLPlatformCursor *cursor) : m_cursor(cursor) { } + QEglFSCursorDeviceListener(QEglFSCursor *cursor) : m_cursor(cursor) { } bool hasMouse() const; public slots: void onDeviceListChanged(QInputDeviceManager::DeviceType type); private: - QEGLPlatformCursor *m_cursor; + QEglFSCursor *m_cursor; }; -class QEGLPlatformCursor : public QPlatformCursor, protected QOpenGLFunctions +class Q_EGLFS_EXPORT QEglFSCursor : public QPlatformCursor, protected QOpenGLFunctions { Q_OBJECT public: - QEGLPlatformCursor(QPlatformScreen *screen); - ~QEGLPlatformCursor(); + QEglFSCursor(QPlatformScreen *screen); + ~QEglFSCursor(); #ifndef QT_NO_CURSOR void changeCursor(QCursor *cursor, QWindow *widget) Q_DECL_OVERRIDE; @@ -128,15 +129,15 @@ private: } m_cursorAtlas; bool m_visible; - QEGLPlatformScreen *m_screen; + QEglFSScreen *m_screen; QOpenGLShaderProgram *m_program; int m_vertexCoordEntry; int m_textureCoordEntry; int m_textureEntry; - QEGLPlatformCursorDeviceListener *m_deviceListener; + QEglFSCursorDeviceListener *m_deviceListener; bool m_updateRequested; }; QT_END_NAMESPACE -#endif // QEGLPLATFORMCURSOR_H +#endif // QEGLFSCURSOR_H diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp index 359b90f20504ffc9a5ecba09fefd1932ea0597e6..d27c949c8db7127e5317dc285b5fa575a0c1fa40 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp @@ -33,8 +33,8 @@ #include "qeglfsdeviceintegration.h" #include "qeglfsintegration.h" +#include "qeglfscursor.h" #include <QtPlatformSupport/private/qeglconvenience_p.h> -#include <QtPlatformSupport/private/qeglplatformcursor_p.h> #include <QGuiApplication> #include <private/qguiapplication_p.h> #include <QScreen> @@ -99,6 +99,7 @@ QStringList QEGLDeviceIntegrationFactory::keys(const QString &pluginPath) qCDebug(qLcEglDevDebug) << "EGL device integration plugin keys:" << list; return list; #else + Q_UNUSED(pluginPath); return QStringList(); #endif } @@ -117,6 +118,9 @@ QEGLDeviceIntegration *QEGLDeviceIntegrationFactory::create(const QString &key, qCDebug(qLcEglDevDebug) << "Using EGL device integration" << key; else qCWarning(qLcEglDevDebug) << "Failed to load EGL device integration" << key; +#else + Q_UNUSED(key); + Q_UNUSED(pluginPath); #endif return integration; } @@ -282,7 +286,7 @@ bool QEGLDeviceIntegration::hasCapability(QPlatformIntegration::Capability cap) QPlatformCursor *QEGLDeviceIntegration::createCursor(QPlatformScreen *screen) const { - return new QEGLPlatformCursor(screen); + return new QEglFSCursor(screen); } void QEGLDeviceIntegration::waitForVSync(QPlatformSurface *surface) const diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index d1688df8f57fb1444f8405d812cfb1277e932735..aec5a5e179b08d4199f7123acca1f7a2b495dac8 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -39,19 +39,41 @@ #include <QtGui/QOpenGLContext> #include <QtGui/QScreen> #include <QtGui/QOffscreenSurface> -#include <qpa/qplatformcursor.h> +#include <QtGui/QWindow> +#include <qpa/qwindowsysteminterface.h> +#include <qpa/qplatforminputcontextfactory_p.h> #include "qeglfsintegration.h" #include "qeglfswindow.h" #include "qeglfshooks.h" #include "qeglfscontext.h" #include "qeglfsoffscreenwindow.h" +#include "qeglfscursor.h" #include <QtPlatformSupport/private/qeglconvenience_p.h> #include <QtPlatformSupport/private/qeglplatformcontext_p.h> #include <QtPlatformSupport/private/qeglpbuffer_p.h> + +#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h> +#include <QtPlatformSupport/private/qgenericunixservices_p.h> +#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h> +#include <QtPlatformSupport/private/qfbvthandler_p.h> +#include <QtPlatformSupport/private/qopenglcompositorbackingstore_p.h> + #include <QtPlatformHeaders/QEGLNativeContext> +#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) +#include <QtPlatformSupport/private/qevdevmousemanager_p.h> +#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h> +#include <QtPlatformSupport/private/qevdevtouchmanager_p.h> +#endif + +#if !defined(QT_NO_TSLIB) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) +#include <QtPlatformSupport/private/qtslib_p.h> +#endif + +#include <QtPlatformHeaders/qeglfsfunctions.h> + #include <EGL/egl.h> static void initResources() @@ -64,21 +86,18 @@ static void initResources() QT_BEGIN_NAMESPACE QEglFSIntegration::QEglFSIntegration() + : m_display(EGL_NO_DISPLAY), + m_inputContext(0), + m_fontDb(new QGenericUnixFontDatabase), + m_services(new QGenericUnixServices), + m_kbdMgr(0), + m_disableInputHandlers(false) { - mDisableInputHandlers = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DISABLE_INPUT"); + m_disableInputHandlers = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DISABLE_INPUT"); initResources(); } -bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) const -{ - // We assume that devices will have more and not less capabilities - if (qt_egl_device_integration()->hasCapability(cap)) - return true; - - return QEGLPlatformIntegration::hasCapability(cap); -} - void QEglFSIntegration::addScreen(QPlatformScreen *screen) { screenAdded(screen); @@ -93,9 +112,19 @@ void QEglFSIntegration::initialize() { qt_egl_device_integration()->platformInit(); - QEGLPlatformIntegration::initialize(); + m_display = eglGetDisplay(nativeDisplay()); + if (m_display == EGL_NO_DISPLAY) + qFatal("Could not open egl display"); + + EGLint major, minor; + if (!eglInitialize(m_display, &major, &minor)) + qFatal("Could not initialize egl display"); + + m_inputContext = QPlatformInputContextFactory::create(); + + m_vtHandler.reset(new QFbVtHandler); - if (!mDisableInputHandlers) + if (!m_disableInputHandlers) createInputHandlers(); if (qt_egl_device_integration()->usesDefaultScreen()) @@ -106,51 +135,278 @@ void QEglFSIntegration::initialize() void QEglFSIntegration::destroy() { + foreach (QWindow *w, qGuiApp->topLevelWindows()) + w->destroy(); + qt_egl_device_integration()->screenDestroy(); - QEGLPlatformIntegration::destroy(); + + if (m_display != EGL_NO_DISPLAY) + eglTerminate(m_display); + qt_egl_device_integration()->platformDestroy(); } -EGLNativeDisplayType QEglFSIntegration::nativeDisplay() const +QAbstractEventDispatcher *QEglFSIntegration::createEventDispatcher() const { - return qt_egl_device_integration()->platformDisplay(); + return createUnixEventDispatcher(); +} + +QPlatformServices *QEglFSIntegration::services() const +{ + return m_services.data(); } -QEGLPlatformWindow *QEglFSIntegration::createWindow(QWindow *window) const +QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const { - return new QEglFSWindow(window); + return m_fontDb.data(); } -QEGLPlatformContext *QEglFSIntegration::createContext(const QSurfaceFormat &format, - QPlatformOpenGLContext *shareContext, - EGLDisplay display, - QVariant *nativeHandle) const +QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *window) const { + QOpenGLCompositorBackingStore *bs = new QOpenGLCompositorBackingStore(window); + if (!window->handle()) + window->create(); + static_cast<QEglFSWindow *>(window->handle())->setBackingStore(bs); + return bs; +} + +QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const +{ + QWindowSystemInterface::flushWindowSystemEvents(); + QEglFSWindow *w = new QEglFSWindow(window); + w->create(); + if (window->type() != Qt::ToolTip) + w->requestActivateWindow(); + return w; +} + +QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const +{ + // If there is a "root" window into which raster and QOpenGLWidget content is + // composited, all other contexts must share with its context. + QOpenGLContext *compositingContext = QOpenGLCompositor::instance()->context(); + EGLDisplay dpy = context->screen() ? static_cast<QEglFSScreen *>(context->screen()->handle())->display() : display(); + QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle(); + QVariant nativeHandle = context->nativeHandle(); + QEglFSContext *ctx; - QSurfaceFormat adjustedFormat = qt_egl_device_integration()->surfaceFormatFor(format); - if (!nativeHandle || nativeHandle->isNull()) { - EGLConfig config = QEglFSIntegration::chooseConfig(display, adjustedFormat); - ctx = new QEglFSContext(adjustedFormat, shareContext, display, &config, QVariant()); + QSurfaceFormat adjustedFormat = qt_egl_device_integration()->surfaceFormatFor(context->format()); + if (nativeHandle.isNull()) { + EGLConfig config = QEglFSIntegration::chooseConfig(dpy, adjustedFormat); + ctx = new QEglFSContext(adjustedFormat, share, dpy, &config, QVariant()); } else { - ctx = new QEglFSContext(adjustedFormat, shareContext, display, 0, *nativeHandle); + ctx = new QEglFSContext(adjustedFormat, share, dpy, 0, nativeHandle); } - *nativeHandle = QVariant::fromValue<QEGLNativeContext>(QEGLNativeContext(ctx->eglContext(), display)); + nativeHandle = QVariant::fromValue<QEGLNativeContext>(QEGLNativeContext(ctx->eglContext(), dpy)); + + context->setNativeHandle(nativeHandle); return ctx; } -QPlatformOffscreenSurface *QEglFSIntegration::createOffscreenSurface(EGLDisplay display, - const QSurfaceFormat &format, - QOffscreenSurface *surface) const +QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const { - QSurfaceFormat fmt = qt_egl_device_integration()->surfaceFormatFor(format); + EGLDisplay dpy = surface->screen() ? static_cast<QEglFSScreen *>(surface->screen()->handle())->display() : display(); + QSurfaceFormat fmt = qt_egl_device_integration()->surfaceFormatFor(surface->requestedFormat()); if (qt_egl_device_integration()->supportsPBuffers()) - return new QEGLPbuffer(display, fmt, surface); + return new QEGLPbuffer(dpy, fmt, surface); else - return new QEglFSOffscreenWindow(display, fmt, surface); - + return new QEglFSOffscreenWindow(dpy, fmt, surface); // Never return null. Multiple QWindows are not supported by this plugin. } +bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) const +{ + // We assume that devices will have more and not less capabilities + if (qt_egl_device_integration()->hasCapability(cap)) + return true; + + switch (cap) { + case ThreadedPixmaps: return true; + case OpenGL: return true; + case ThreadedOpenGL: return true; + case WindowManagement: return false; + case RasterGLSurface: return true; + default: return QPlatformIntegration::hasCapability(cap); + } +} + +QPlatformNativeInterface *QEglFSIntegration::nativeInterface() const +{ + return const_cast<QEglFSIntegration *>(this); +} + +enum ResourceType { + EglDisplay, + EglWindow, + EglContext, + EglConfig, + NativeDisplay, + XlibDisplay +}; + +static int resourceType(const QByteArray &key) +{ + static const QByteArray names[] = { // match ResourceType + QByteArrayLiteral("egldisplay"), + QByteArrayLiteral("eglwindow"), + QByteArrayLiteral("eglcontext"), + QByteArrayLiteral("eglconfig"), + QByteArrayLiteral("nativedisplay"), + QByteArrayLiteral("display") + }; + const QByteArray *end = names + sizeof(names) / sizeof(names[0]); + const QByteArray *result = std::find(names, end, key); + if (result == end) + result = std::find(names, end, key.toLower()); + return int(result - names); +} + +void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource) +{ + void *result = 0; + + switch (resourceType(resource)) { + case EglDisplay: + result = display(); + break; + case NativeDisplay: + result = reinterpret_cast<void*>(nativeDisplay()); + break; + default: + break; + } + + return result; +} + +void *QEglFSIntegration::nativeResourceForScreen(const QByteArray &resource, QScreen *) +{ + void *result = 0; + + switch (resourceType(resource)) { + case XlibDisplay: + // Play nice when using the x11 hooks: Be compatible with xcb that allows querying + // the X Display pointer, which is nothing but our native display. + result = reinterpret_cast<void*>(nativeDisplay()); + break; + default: + break; + } + + return result; +} + +void *QEglFSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window) +{ + void *result = 0; + + switch (resourceType(resource)) { + case EglDisplay: + if (window && window->handle()) + result = static_cast<QEglFSScreen *>(window->handle()->screen())->display(); + else + result = display(); + break; + case EglWindow: + if (window && window->handle()) + result = reinterpret_cast<void*>(static_cast<QEglFSWindow *>(window->handle())->eglWindow()); + break; + default: + break; + } + + return result; +} + +void *QEglFSIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) +{ + void *result = 0; + + switch (resourceType(resource)) { + case EglContext: + if (context->handle()) + result = static_cast<QEglFSContext *>(context->handle())->eglContext(); + break; + case EglConfig: + if (context->handle()) + result = static_cast<QEglFSContext *>(context->handle())->eglConfig(); + break; + case EglDisplay: + if (context->handle()) + result = static_cast<QEglFSContext *>(context->handle())->eglDisplay(); + break; + default: + break; + } + + return result; +} + +static void *eglContextForContext(QOpenGLContext *context) +{ + Q_ASSERT(context); + + QEglFSContext *handle = static_cast<QEglFSContext *>(context->handle()); + if (!handle) + return 0; + + return handle->eglContext(); +} + +QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::nativeResourceFunctionForContext(const QByteArray &resource) +{ + QByteArray lowerCaseResource = resource.toLower(); + if (lowerCaseResource == "get_egl_context") + return NativeResourceForContextFunction(eglContextForContext); + + return 0; +} + +QFunctionPointer QEglFSIntegration::platformFunction(const QByteArray &function) const +{ +#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) + if (function == QEglFSFunctions::loadKeymapTypeIdentifier()) + return QFunctionPointer(loadKeymapStatic); +#else + Q_UNUSED(function) +#endif + + return 0; +} + +void QEglFSIntegration::loadKeymapStatic(const QString &filename) +{ +#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) + QEglFSIntegration *self = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration()); + if (self->m_kbdMgr) + self->m_kbdMgr->loadKeymap(filename); + else + qWarning("QEglFSIntegration: Cannot load keymap, no keyboard handler found"); +#else + Q_UNUSED(filename); +#endif +} + +void QEglFSIntegration::createInputHandlers() +{ +#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) + m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this); + new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this); +#ifndef QT_NO_TSLIB + const bool useTslib = qEnvironmentVariableIntValue("QT_QPA_EGLFS_TSLIB"); + if (useTslib) + new QTsLibMouseHandler(QLatin1String("TsLib"), QString() /* spec */); + else +#endif // QT_NO_TSLIB + new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this); +#endif +} + +EGLNativeDisplayType QEglFSIntegration::nativeDisplay() const +{ + return qt_egl_device_integration()->platformDisplay(); +} + EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format) { class Chooser : public QEglConfigChooser { diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h index 11b643d540613c51cd2f296633746ff4a71b8388..98c7ee9f78a1986ddb41243438727672d17e7f0c 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsintegration.h @@ -34,41 +34,72 @@ #ifndef QEGLFSINTEGRATION_H #define QEGLFSINTEGRATION_H -#include <QtPlatformSupport/private/qeglplatformintegration_p.h> +#include <QtCore/QVariant> +#include <qpa/qplatformintegration.h> +#include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformscreen.h> #include <EGL/egl.h> #include "qeglfsglobal.h" QT_BEGIN_NAMESPACE -class Q_EGLFS_EXPORT QEglFSIntegration : public QEGLPlatformIntegration +class QEglFSWindow; +class QEglFSContext; +class QFbVtHandler; +class QEvdevKeyboardManager; + +class Q_EGLFS_EXPORT QEglFSIntegration : public QPlatformIntegration, public QPlatformNativeInterface { public: QEglFSIntegration(); - void addScreen(QPlatformScreen *screen); - void removeScreen(QPlatformScreen *screen); - void initialize() Q_DECL_OVERRIDE; void destroy() Q_DECL_OVERRIDE; + EGLDisplay display() const { return m_display; } + + QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; + QPlatformServices *services() const Q_DECL_OVERRIDE; + QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; } + + QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE; + QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE; + bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; - static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format); + QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; -protected: - QEGLPlatformWindow *createWindow(QWindow *window) const Q_DECL_OVERRIDE; - QEGLPlatformContext *createContext(const QSurfaceFormat &format, - QPlatformOpenGLContext *shareContext, - EGLDisplay display, - QVariant *nativeHandle) const Q_DECL_OVERRIDE; - QPlatformOffscreenSurface *createOffscreenSurface(EGLDisplay display, - const QSurfaceFormat &format, - QOffscreenSurface *surface) const Q_DECL_OVERRIDE; - EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE; + // QPlatformNativeInterface + void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE; + void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) Q_DECL_OVERRIDE; + void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE; + void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE; + NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE; + + QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE; + + QFbVtHandler *vtHandler() { return m_vtHandler.data(); } + + void addScreen(QPlatformScreen *screen); + void removeScreen(QPlatformScreen *screen); + + static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format); private: - bool mDisableInputHandlers; + EGLNativeDisplayType nativeDisplay() const; + void createInputHandlers(); + static void loadKeymapStatic(const QString &filename); + + EGLDisplay m_display; + QPlatformInputContext *m_inputContext; + QScopedPointer<QPlatformFontDatabase> m_fontDb; + QScopedPointer<QPlatformServices> m_services; + QScopedPointer<QFbVtHandler> m_vtHandler; + QEvdevKeyboardManager *m_kbdMgr; + bool m_disableInputHandlers; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index 1b6e2307f8a1035c8783897336d6ee2f77817d7d..22ec42445137e81314400a1bf05401e2359cddeb 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -32,7 +32,10 @@ ****************************************************************************/ #include <QtCore/qtextstream.h> -#include <QtGui/qpa/qplatformcursor.h> +#include <QtGui/qwindow.h> +#include <qpa/qwindowsysteminterface.h> +#include <qpa/qplatformcursor.h> +#include <QtPlatformSupport/private/qopenglcompositor_p.h> #include "qeglfsscreen.h" #include "qeglfswindow.h" @@ -41,7 +44,8 @@ QT_BEGIN_NAMESPACE QEglFSScreen::QEglFSScreen(EGLDisplay dpy) - : QEGLPlatformScreen(dpy), + : m_dpy(dpy), + m_pointerWindow(0), m_surface(EGL_NO_SURFACE), m_cursor(0) { @@ -51,6 +55,7 @@ QEglFSScreen::QEglFSScreen(EGLDisplay dpy) QEglFSScreen::~QEglFSScreen() { delete m_cursor; + QOpenGLCompositor::destroy(); } QRect QEglFSScreen::geometry() const @@ -103,4 +108,89 @@ void QEglFSScreen::setPrimarySurface(EGLSurface surface) m_surface = surface; } +void QEglFSScreen::handleCursorMove(const QPoint &pos) +{ + const QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); + + // Generate enter and leave events like a real windowing system would do. + if (windows.isEmpty()) + return; + + // First window is always fullscreen. + if (windows.count() == 1) { + QWindow *window = windows[0]->sourceWindow(); + if (m_pointerWindow != window) { + m_pointerWindow = window; + QWindowSystemInterface::handleEnterEvent(window, window->mapFromGlobal(pos), pos); + } + return; + } + + QWindow *enter = 0, *leave = 0; + for (int i = windows.count() - 1; i >= 0; --i) { + QWindow *window = windows[i]->sourceWindow(); + const QRect geom = window->geometry(); + if (geom.contains(pos)) { + if (m_pointerWindow != window) { + leave = m_pointerWindow; + m_pointerWindow = window; + enter = window; + } + break; + } + } + + if (enter && leave) + QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos); +} + +QPixmap QEglFSScreen::grabWindow(WId wid, int x, int y, int width, int height) const +{ + QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); + Q_ASSERT(!windows.isEmpty()); + + QImage img; + + if (static_cast<QEglFSWindow *>(windows.first()->sourceWindow()->handle())->isRaster()) { + // Request the compositor to render everything into an FBO and read it back. This + // is of course slow, but it's safe and reliable. It will not include the mouse + // cursor, which is a plus. + img = compositor->grab(); + } else { + // Just a single OpenGL window without compositing. Do not support this case for now. Doing + // glReadPixels is not an option since it would read from the back buffer which may have + // undefined content when calling right after a swapBuffers (unless preserved swap is + // available and enabled, but we have no support for that). + qWarning("grabWindow: Not supported for non-composited OpenGL content. Use QQuickWindow::grabWindow() instead."); + return QPixmap(); + } + + if (!wid) { + const QSize screenSize = geometry().size(); + if (width < 0) + width = screenSize.width() - x; + if (height < 0) + height = screenSize.height() - y; + return QPixmap::fromImage(img).copy(x, y, width, height); + } + + foreach (QOpenGLCompositorWindow *w, windows) { + const QWindow *window = w->sourceWindow(); + if (window->winId() == wid) { + const QRect geom = window->geometry(); + if (width < 0) + width = geom.width() - x; + if (height < 0) + height = geom.height() - y; + QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height)); + rect &= window->geometry(); + return QPixmap::fromImage(img).copy(rect); + } + } + + return QPixmap(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h index 07b6ff63ef34fb3ca041c2c0ba716e4c83420e5f..dc291285ad33d97ad59775fef5f085a097c11c62 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.h +++ b/src/plugins/platforms/eglfs/qeglfsscreen.h @@ -35,7 +35,6 @@ #define QEGLFSSCREEN_H #include "qeglfsglobal.h" -#include <QtPlatformSupport/private/qeglplatformscreen_p.h> #include <EGL/egl.h> QT_BEGIN_NAMESPACE @@ -43,7 +42,7 @@ QT_BEGIN_NAMESPACE class QEglFSWindow; class QOpenGLContext; -class Q_EGLFS_EXPORT QEglFSScreen : public QEGLPlatformScreen +class Q_EGLFS_EXPORT QEglFSScreen : public QPlatformScreen { public: QEglFSScreen(EGLDisplay display); @@ -62,16 +61,23 @@ public: qreal refreshRate() const Q_DECL_OVERRIDE; + QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE; + EGLSurface primarySurface() const { return m_surface; } -protected: - void setPrimarySurface(EGLSurface surface); + EGLDisplay display() const { return m_dpy; } + + void handleCursorMove(const QPoint &pos); private: - friend class QEglFSWindow; + void setPrimarySurface(EGLSurface surface); + EGLDisplay m_dpy; + QWindow *m_pointerWindow; EGLSurface m_surface; QPlatformCursor *m_cursor; + + friend class QEglFSWindow; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index c0d51c94a51e126f9a43ab3f7b2160802d2d8653..c3b9dd6ef0b88bdcb201ebbfa1a4c4443820643d 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -37,21 +37,23 @@ #include <private/qguiapplication_p.h> #include <QtGui/private/qopenglcontext_p.h> #include <QtGui/QOpenGLContext> -#include <QtPlatformSupport/private/qeglplatformcursor_p.h> #include <QtPlatformSupport/private/qeglconvenience_p.h> +#include <QtPlatformSupport/private/qopenglcompositorbackingstore_p.h> #include "qeglfswindow.h" +#include "qeglfscursor.h" #include "qeglfshooks.h" -#include <QtDebug> - QT_BEGIN_NAMESPACE QEglFSWindow::QEglFSWindow(QWindow *w) - : QEGLPlatformWindow(w) - , m_surface(0) - , m_window(0) - , m_flags(0) + : QPlatformWindow(w), + m_backingStore(0), + m_raster(false), + m_winId(0), + m_surface(0), + m_window(0), + m_flags(0) { } @@ -60,12 +62,34 @@ QEglFSWindow::~QEglFSWindow() destroy(); } +static WId newWId() +{ + static WId id = 0; + + if (id == std::numeric_limits<WId>::max()) + qWarning("QEGLPlatformWindow: Out of window IDs"); + + return ++id; +} + void QEglFSWindow::create() { if (m_flags.testFlag(Created)) return; - QEGLPlatformWindow::create(); + m_winId = newWId(); + + // Save the original surface type before changing to OpenGLSurface. + m_raster = (window()->surfaceType() == QSurface::RasterSurface); + if (m_raster) // change to OpenGL, but not for RasterGLSurface + window()->setSurfaceType(QSurface::OpenGLSurface); + + if (window()->type() == Qt::Desktop) { + QRect fullscreenRect(QPoint(), screen()->availableGeometry().size()); + QPlatformWindow::setGeometry(fullscreenRect); + QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect); + return; + } m_flags = Created; @@ -120,7 +144,7 @@ void QEglFSWindow::destroy() { QEglFSScreen *screen = this->screen(); if (m_flags.testFlag(HasNativeWindow)) { - QEGLPlatformCursor *cursor = qobject_cast<QEGLPlatformCursor *>(screen->cursor()); + QEglFSCursor *cursor = qobject_cast<QEglFSCursor *>(screen->cursor()); if (cursor) cursor->resetResources(); @@ -265,4 +289,41 @@ QEglFSScreen *QEglFSWindow::screen() const return static_cast<QEglFSScreen *>(QPlatformWindow::screen()); } +bool QEglFSWindow::isRaster() const +{ + return m_raster || window()->surfaceType() == QSurface::RasterGLSurface; +} + +QWindow *QEglFSWindow::sourceWindow() const +{ + return window(); +} + +const QPlatformTextureList *QEglFSWindow::textures() const +{ + if (m_backingStore) + return m_backingStore->textures(); + + return 0; +} + +void QEglFSWindow::endCompositing() +{ + if (m_backingStore) + m_backingStore->notifyComposited(); +} + +WId QEglFSWindow::winId() const +{ + return m_winId; +} + +void QEglFSWindow::setOpacity(qreal) +{ + if (!isRaster()) + qWarning("QEglFSWindow: Cannot set opacity for non-raster windows"); + + // Nothing to do here. The opacity is stored in the QWindow. +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h index f9d207c15340565157b17514b3b19ef2e232a627..53b9e18dc1af912b923a548d5bb4d7efb3242879 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ b/src/plugins/platforms/eglfs/qeglfswindow.h @@ -37,17 +37,23 @@ #include "qeglfsintegration.h" #include "qeglfsscreen.h" #include "qeglfsglobal.h" -#include <QtPlatformSupport/private/qeglplatformwindow_p.h> + +#include <qpa/qplatformwindow.h> +#include <QtPlatformSupport/private/qopenglcompositor_p.h> +#include <EGL/egl.h> QT_BEGIN_NAMESPACE -class Q_EGLFS_EXPORT QEglFSWindow : public QEGLPlatformWindow +class QOpenGLCompositorBackingStore; +class QPlatformTextureList; + +class Q_EGLFS_EXPORT QEglFSWindow : public QPlatformWindow, public QOpenGLCompositorWindow { public: QEglFSWindow(QWindow *w); ~QEglFSWindow(); - void create() Q_DECL_OVERRIDE; + void create(); void destroy(); void setGeometry(const QRect &) Q_DECL_OVERRIDE; @@ -58,13 +64,15 @@ public: void lower() Q_DECL_OVERRIDE; void propagateSizeHints() Q_DECL_OVERRIDE { } - void setOpacity(qreal) Q_DECL_OVERRIDE { } void setMask(const QRegion &) Q_DECL_OVERRIDE { } bool setKeyboardGrabEnabled(bool) Q_DECL_OVERRIDE { return false; } bool setMouseGrabEnabled(bool) Q_DECL_OVERRIDE { return false; } + void setOpacity(qreal) Q_DECL_OVERRIDE; + WId winId() const Q_DECL_OVERRIDE; QSurfaceFormat format() const Q_DECL_OVERRIDE; - EGLNativeWindowType eglWindow() const Q_DECL_OVERRIDE; + + EGLNativeWindowType eglWindow() const; EGLSurface surface() const; QEglFSScreen *screen() const; @@ -73,11 +81,22 @@ public: virtual void invalidateSurface() Q_DECL_OVERRIDE; virtual void resetSurface(); -protected: + QOpenGLCompositorBackingStore *backingStore() { return m_backingStore; } + void setBackingStore(QOpenGLCompositorBackingStore *backingStore) { m_backingStore = backingStore; } + bool isRaster() const; + + QWindow *sourceWindow() const Q_DECL_OVERRIDE; + const QPlatformTextureList *textures() const Q_DECL_OVERRIDE; + void endCompositing() Q_DECL_OVERRIDE; + +private: + QOpenGLCompositorBackingStore *m_backingStore; + bool m_raster; + WId m_winId; + EGLSurface m_surface; EGLNativeWindowType m_window; -private: EGLConfig m_config; QSurfaceFormat m_format; diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 8e4b4c58758bcad273d0d03a891d7c9b20ac62d3..bd4b8778edfb1f5879a46d956e680d736fa28fba 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -198,7 +198,7 @@ namespace bool debugStackUsage = false; } -extern "C" int __attribute__((weak)) main(int argc, char *argv[]) +extern "C" int qt_main_wrapper(int argc, char *argv[]) { @autoreleasepool { size_t defaultStackSize = 512 * kBytesPerKiloByte; // Same as secondary threads @@ -233,18 +233,7 @@ enum SetJumpResult kJumpedFromUserMainTrampoline, }; -// We define qtmn so that user_main_trampoline() will not cause -// missing symbols in the case of hybrid applications that don't -// use our main wrapper. Since the symbol is weak, it will not -// get used or cause a clash in the normal Qt application usecase, -// where we rename main to qtmn before linking. -extern "C" int __attribute__((weak)) qtmn(int argc, char *argv[]) -{ - Q_UNUSED(argc); - Q_UNUSED(argv); - - Q_UNREACHABLE(); -} +extern "C" int main(int argc, char *argv[]); static void __attribute__((noinline, noreturn)) user_main_trampoline() { @@ -263,7 +252,7 @@ static void __attribute__((noinline, noreturn)) user_main_trampoline() qFatal("Could not convert argv[%d] to C string", i); } - int exitCode = qtmn(argc, argv); + int exitCode = main(argc, argv); delete[] argv; qEventDispatcherDebug() << "Returned from main with exit code " << exitCode; diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm index 44a79011601ed78b1a4f51c50ca61eee0158c809..f0b6afce2dd3d1fbe02a283f3b364b625adc8ef8 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm +++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm @@ -429,11 +429,11 @@ void QIOSFileEngineAssetsLibrary::setFileName(const QString &file) // QUrl::fromLocalFile() will remove double slashes. Since the asset url is // passed around as a file name in the app (and converted to/from a file url, e.g // in QFileDialog), we need to ensure that m_assetUrl ends up being valid. - int index = file.indexOf(QLatin1String("asset.JPG?")); + int index = file.indexOf(QLatin1String("/asset")); if (index == -1) m_assetUrl = QLatin1String("assets-library://"); else - m_assetUrl = QLatin1String("assets-library://asset/") + file.mid(index); + m_assetUrl = QLatin1String("assets-library:/") + file.mid(index); } QStringList QIOSFileEngineAssetsLibrary::entryList(QDir::Filters filters, const QStringList &filterNames) const diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index b45f6293106c674096a1527cd2f9b5166cc40619..c53eee1afd662987befd0ab875ff3e06ec82839e 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -80,6 +80,8 @@ public: void clearAccessibleCache(); + QSurfaceFormat format() const Q_DECL_OVERRIDE; + private: void applicationStateChanged(Qt::ApplicationState state); void applyGeometry(const QRect &rect); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 80fba00ffb5416c81f5eb10ec3c464f47c8da99d..3045a15380175d5e6fd44daf147a65ad89f3a81e 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -93,6 +93,13 @@ QIOSWindow::~QIOSWindow() [m_view release]; } + +QSurfaceFormat QIOSWindow::format() const +{ + return window()->requestedFormat(); +} + + bool QIOSWindow::blockedByModal() { QWindow *modalWindow = QGuiApplication::modalWindow(); diff --git a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp index e5c853dad83043a123b07fe72af848d888545785..04e264860ef3d4b37664102ef9374853be32b37c 100644 --- a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp +++ b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp @@ -124,4 +124,25 @@ void QQnxAbstractVirtualKeyboard::setLocale(const QLocale &locale) emit localeChanged(locale); } +QQnxAbstractVirtualKeyboard::EnterKeyType + QQnxAbstractVirtualKeyboard::qtEnterKeyTypeToQnx(Qt::EnterKeyType type) +{ + switch (type) { + case Qt::EnterKeyDone: + return Done; + case Qt::EnterKeyGo: + return Go; + case Qt::EnterKeyNext: + return Next; + case Qt::EnterKeySearch: + return Search; + case Qt::EnterKeySend: + return Send; + case Qt::EnterKeyDefault: + case Qt::EnterKeyReturn: + case Qt::EnterKeyPrevious: // unsupported + return DefaultReturn; + } +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h index 8bf83130000821404dc37f0dfaf51631f7e5871d..2fa2ed729107ba08d01f9204e9ec544e1d5f88eb 100644 --- a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h +++ b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h @@ -74,6 +74,8 @@ public: KeyboardMode keyboardMode() const { return m_keyboardMode; } EnterKeyType enterKeyType() const { return m_enterKeyType; } + static EnterKeyType qtEnterKeyTypeToQnx(Qt::EnterKeyType type); + Q_SIGNALS: void heightChanged(int height); void visibilityChanged(bool visible); diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp index 3506de4bc0c18620f49f72437f5d2e398fced1de..ed0db82685abacae04868bdcf8d46171b25bbe47 100644 --- a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp +++ b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp @@ -1384,13 +1384,17 @@ void QQnxInputContext::setFocusObject(QObject *object) if (hasSession()) dispatchFocusLossEvent(); } else { - QInputMethodQueryEvent query(Qt::ImHints); + QInputMethodQueryEvent query(Qt::ImHints | Qt::ImEnterKeyType); QCoreApplication::sendEvent(object, &query); int inputHints = query.value(Qt::ImHints).toInt(); + Qt::EnterKeyType qtEnterKeyType = Qt::EnterKeyType(query.value(Qt::ImEnterKeyType).toInt()); dispatchFocusGainEvent(inputHints); m_virtualKeyboard.setInputHints(inputHints); + m_virtualKeyboard.setEnterKeyType( + QQnxAbstractVirtualKeyboard::qtEnterKeyTypeToQnx(qtEnterKeyType) + ); if (!m_inputPanelVisible) showInputPanel(); diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp index 91ecffa2aa0b316a9e457b342ba5e0d2efc18da5..3860cdf0dbacd8ac9040938066a918b3c5c55b47 100644 --- a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp +++ b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp @@ -172,11 +172,15 @@ void QQnxInputContext::setFocusObject(QObject *object) if (m_inputPanelVisible) hideInputPanel(); } else { - QInputMethodQueryEvent query(Qt::ImHints); + QInputMethodQueryEvent query(Qt::ImHints | Qt::ImEnterKeyType); QCoreApplication::sendEvent(object, &query); int inputHints = query.value(Qt::ImHints).toInt(); + Qt::EnterKeyType qtEnterKeyType = Qt::EnterKeyType(query.value(Qt::ImEnterKeyType).toInt()); m_virtualKeyboard.setInputHints(inputHints); + m_virtualKeyboard.setEnterKeyType( + QQnxAbstractVirtualKeyboard::qtEnterKeyTypeToQnx(qtEnterKeyType) + ); if (!m_inputPanelVisible) showInputPanel(); diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index 693749da558d289b25aa52616212387a3772f8a7..1c825dbbdd799c9dffd52524663c5808a42990c9 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -559,7 +559,9 @@ void QQnxIntegration::removeDisplay(QQnxScreen *screen) void QQnxIntegration::destroyDisplays() { qIntegrationDebug() << Q_FUNC_INFO; - qDeleteAll(m_screens); + Q_FOREACH (QQnxScreen *screen, m_screens) { + QPlatformIntegration::destroyScreen(screen); + } m_screens.clear(); } diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json index 23607523bded1154ae560f3f7920513cb505c2a7..7521d25760723eb02781226235aa7cff8b2c944e 100644 --- a/src/plugins/platforms/windows/openglblacklists/default.json +++ b/src/plugins/platforms/windows/openglblacklists/default.json @@ -17,6 +17,31 @@ "features": [ "disable_desktopgl" ] - } + }, + { + "id": 2, + "description": "Intel Q965/Q963 - GMA 3000 has insufficient support of opengl and directx", + "vendor_id": "0x8086", + "device_id": [ "0x2992" ], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl", + "disable_angle" + ] + }, + { + "id": 3, + "description": "No OpenGL on Intel G33/G31 (QTBUG-47522)", + "vendor_id": "0x8086", + "device_id": [ "0x29C2" ], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl", + ] + } ] } diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp index 16c278d9dfb6e0f249f31765bea192feef174d10..3f19e4401a752c6e658b94342afaf0f9c4b863e2 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp +++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp @@ -35,10 +35,10 @@ #include "qwindowswindow.h" #include "qwindowsnativeimage.h" #include "qwindowscontext.h" -#include "qwindowsscaling.h" #include <QtGui/QWindow> #include <QtGui/QPainter> +#include <private/qhighdpiscaling_p.h> #include <QtCore/QDebug> @@ -68,10 +68,12 @@ QPaintDevice *QWindowsBackingStore::paintDevice() return &m_image->image(); } -void QWindowsBackingStore::flushDp(QWindow *window, const QRect &br, const QPoint &offset) +void QWindowsBackingStore::flush(QWindow *window, const QRegion ®ion, + const QPoint &offset) { Q_ASSERT(window); + const QRect br = region.boundingRect(); if (QWindowsContext::verbose > 1) qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window << offset << br; QWindowsWindow *rw = QWindowsWindow::baseWindowOf(window); @@ -81,9 +83,8 @@ void QWindowsBackingStore::flushDp(QWindow *window, const QRect &br, const QPoin const Qt::WindowFlags flags = window->flags(); if ((flags & Qt::FramelessWindowHint) && QWindowsWindow::setWindowLayered(rw->handle(), flags, hasAlpha, rw->opacity()) && hasAlpha) { // Windows with alpha: Use blend function to update. - const QMargins marginsDP = rw->frameMarginsDp(); - const QRect r = rw->geometryDp() + marginsDP; - const QPoint frameOffset(marginsDP.left(), marginsDP.top()); + QRect r = QHighDpi::toNativePixels(window->frameGeometry(), window); + QPoint frameOffset(QHighDpi::toNativePixels(QPoint(window->frameMargins().left(), window->frameMargins().top()), window)); QRect dirtyRect = br.translated(offset + frameOffset); SIZE size = {r.width(), r.height()}; @@ -127,15 +128,14 @@ void QWindowsBackingStore::flushDp(QWindow *window, const QRect &br, const QPoin } } -void QWindowsBackingStore::resize(const QSize &sizeDip, const QRegion ®ionDip) +void QWindowsBackingStore::resize(const QSize &size, const QRegion ®ion) { - const QSize size = sizeDip * QWindowsScaling::factor(); if (m_image.isNull() || m_image->image().size() != size) { #ifndef QT_NO_DEBUG_OUTPUT if (QWindowsContext::verbose && lcQpaBackingStore().isDebugEnabled()) { qCDebug(lcQpaBackingStore) - << __FUNCTION__ << ' ' << window() << ' ' << size << ' ' << sizeDip << ' ' - << regionDip << " from: " << (m_image.isNull() ? QSize() : m_image->image().size()); + << __FUNCTION__ << ' ' << window() << ' ' << size << ' ' << region + << " from: " << (m_image.isNull() ? QSize() : m_image->image().size()); } #endif const QImage::Format format = window()->format().hasAlpha() ? @@ -144,10 +144,10 @@ void QWindowsBackingStore::resize(const QSize &sizeDip, const QRegion ®ionDip QWindowsNativeImage *oldwni = m_image.data(); QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format); - if (oldwni && !regionDip.isEmpty()) { + if (oldwni && !region.isEmpty()) { const QImage &oldimg(oldwni->image()); QImage &newimg(newwni->image()); - QRegion staticRegion = QWindowsScaling::mapToNative(regionDip); + QRegion staticRegion(region); staticRegion &= QRect(0, 0, oldimg.width(), oldimg.height()); staticRegion &= QRect(0, 0, newimg.width(), newimg.height()); QPainter painter(&newimg); @@ -156,38 +156,36 @@ void QWindowsBackingStore::resize(const QSize &sizeDip, const QRegion ®ionDip painter.drawImage(rect, oldimg, rect); } - if (QWindowsScaling::isActive()) - newwni->setDevicePixelRatio(QWindowsScaling::factor()); m_image.reset(newwni); } } Q_GUI_EXPORT void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset); -bool QWindowsBackingStore::scroll(const QRegion &areaDip, int dxDip, int dyDip) +bool QWindowsBackingStore::scroll(const QRegion &area, int dx, int dy) { if (m_image.isNull() || m_image->image().isNull()) return false; - const QPoint dp = QPoint(dxDip, dyDip) * QWindowsScaling::factor(); - const QVector<QRect> rects = areaDip.rects(); + const QVector<QRect> rects = area.rects(); + const QPoint offset(dx, dy); for (int i = 0; i < rects.size(); ++i) - qt_scrollRectInImage(m_image->image(), QWindowsScaling::mapToNative(rects.at(i)), dp); + qt_scrollRectInImage(m_image->image(), rects.at(i), offset); return true; } -void QWindowsBackingStore::beginPaint(const QRegion ®ionDip) +void QWindowsBackingStore::beginPaint(const QRegion ®ion) { if (QWindowsContext::verbose > 1) - qCDebug(lcQpaBackingStore) <<__FUNCTION__ << regionDip; + qCDebug(lcQpaBackingStore) <<__FUNCTION__ << region; if (m_image->image().hasAlphaChannel()) { QPainter p(&m_image->image()); p.setCompositionMode(QPainter::CompositionMode_Source); const QColor blank = Qt::transparent; - foreach (const QRect &r, regionDip.rects()) - p.fillRect(QWindowsScaling::mapToNative(r), blank); + foreach (const QRect &r, region.rects()) + p.fillRect(r, blank); } } diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.h b/src/plugins/platforms/windows/qwindowsbackingstore.h index 41ad29babc79aed0103dd1a13afa31d1b1cb7020..4badcf1b0930209ecb75c057b5dbcafb5de11496 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.h +++ b/src/plugins/platforms/windows/qwindowsbackingstore.h @@ -35,7 +35,6 @@ #define QWINDOWSBACKINGSTORE_H #include "qtwindows_additional.h" -#include "qwindowsscaling.h" #include <qpa/qplatformbackingstore.h> #include <QtCore/QScopedPointer> @@ -53,12 +52,7 @@ public: ~QWindowsBackingStore(); QPaintDevice *paintDevice() Q_DECL_OVERRIDE; - void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE - { - flushDp(window, QWindowsScaling::mapToNative(region.boundingRect()), - offset * QWindowsScaling::factor()); - } - void flushDp(QWindow *window, const QRect &boundingRect, const QPoint &offset); + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; void resize(const QSize &size, const QRegion &r) Q_DECL_OVERRIDE; bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE; void beginPaint(const QRegion &) Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index a532e9239778482927243d9416450952e8587d55..27323a2fd64b2a4fbc5fadf289fdd22e1ddcea64 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -51,7 +51,6 @@ #endif #include "qwindowsscreen.h" #include "qwindowstheme.h" -#include "qwindowsscaling.h" #include <QtGui/QWindow> #include <qpa/qwindowsysteminterface.h> @@ -1228,9 +1227,7 @@ bool QWindowsContext::handleContextMenuEvent(QWindow *window, const MSG &msg) } } - QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered, - pos / QWindowsScaling::factor(), - globalPos / QWindowsScaling::factor(), + QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered, pos, globalPos, QWindowsKeyMapper::queryKeyboardModifiers()); return true; } diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 5f443f26755b144f2442952ca14ddce26a68e1bf..1fbef61029fddb6e88b91b2402fcf3ca8f9941b5 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -36,7 +36,6 @@ #include "qwindowscontext.h" #include "qwindowswindow.h" #include "qwindowsscreen.h" -#include "qwindowsscaling.h" #include <QtGui/QBitmap> #include <QtGui/QImage> @@ -646,13 +645,12 @@ QWindowsCursor::CursorState QWindowsCursor::cursorState() QPoint QWindowsCursor::pos() const { - return mousePosition() / QWindowsScaling::factor(); + return mousePosition(); } void QWindowsCursor::setPos(const QPoint &pos) { - const QPoint posDp = pos * QWindowsScaling::factor(); - SetCursorPos(posDp.x() , posDp.y()); + SetCursorPos(pos.x() , pos.y()); } /*! diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index e10add9c7c30075f779c59dff6f4f4fb5aac5aea..d24cba3c68d832b7732ec0a0f81f682685e97dde 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -33,7 +33,7 @@ #include "qwindowsdrag.h" #include "qwindowscontext.h" -#include "qwindowsscaling.h" +#include "qwindowsscreen.h" #ifndef QT_NO_CLIPBOARD # include "qwindowsclipboard.h" #endif @@ -43,7 +43,6 @@ #include "qwindowswindow.h" #include "qwindowsmousehandler.h" #include "qwindowscursor.h" -#include "qwindowsscaling.h" #include <QtGui/QMouseEvent> #include <QtGui/QPixmap> @@ -52,6 +51,7 @@ #include <QtGui/QGuiApplication> #include <qpa/qwindowsysteminterface_p.h> #include <QtGui/private/qguiapplication_p.h> +#include <QtGui/private/qhighdpiscaling_p.h> #include <QtCore/QDebug> #include <QtCore/QBuffer> @@ -280,6 +280,13 @@ QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e) } #endif // !QT_NO_DEBUG_OUTPUT +static qreal dragScaleFactor() +{ + const QWindowsScreenManager &screenManager = QWindowsContext::instance()->screenManager(); + const QWindowsScreen *screen = screenManager.screenAtDp(QWindowsCursor::mousePosition()); + return screen ? QHighDpiScaling::factor(screen) : qreal(1); +} + /*! \brief Blend custom pixmap with cursors. */ @@ -289,19 +296,22 @@ void QWindowsOleDropSource::createCursors() const QDrag *drag = m_drag->currentDrag(); const QPixmap pixmap = drag->pixmap(); const bool hasPixmap = !pixmap.isNull(); - const int scaleFactor = QWindowsScaling::factor(); - const QSize pixmapSizeDp = pixmap.size() * scaleFactor; + + const qreal scaleFactor = dragScaleFactor(); const bool scalePixmap = hasPixmap && m_mode != TouchDrag // Touch drag: pixmap is shown in a separate QWindow, which will be scaled. && (scaleFactor != 1 && scaleFactor != qRound(pixmap.devicePixelRatio())); - const QPixmap drawPixmap = scalePixmap - ? pixmap.scaled(pixmapSizeDp, Qt::KeepAspectRatio, Qt::SmoothTransformation) : pixmap; - + const QPixmap scaledPixmap = scalePixmap + ? pixmap.scaled((QSizeF(pixmap.size()) * scaleFactor).toSize(), + Qt::KeepAspectRatio, Qt::SmoothTransformation) + : pixmap; Qt::DropAction actions[] = { Qt::MoveAction, Qt::CopyAction, Qt::LinkAction, Qt::IgnoreAction }; int actionCount = int(sizeof(actions) / sizeof(actions[0])); if (!hasPixmap) --actionCount; // No Qt::IgnoreAction unless pixmap - const QPoint hotSpot = drag->hotSpot() * scaleFactor; + const QPoint hotSpot = scalePixmap + ? (QPointF(drag->hotSpot()) * scaleFactor).toPoint() + : drag->hotSpot(); for (int cnum = 0; cnum < actionCount; ++cnum) { const Qt::DropAction action = actions[cnum]; QPixmap cursorPixmap = drag->dragCursor(action); @@ -321,14 +331,14 @@ void QWindowsOleDropSource::createCursors() if (hasPixmap) { const int x1 = qMin(-hotSpot.x(), 0); - const int x2 = qMax(pixmapSizeDp.width() - hotSpot.x(), cursorPixmap.width()); + const int x2 = qMax(scaledPixmap.width() - hotSpot.x(), cursorPixmap.width()); const int y1 = qMin(-hotSpot.y(), 0); - const int y2 = qMax(pixmapSizeDp.height() - hotSpot.y(), cursorPixmap.height()); + const int y2 = qMax(scaledPixmap.height() - hotSpot.y(), cursorPixmap.height()); QPixmap newCursor(x2 - x1 + 1, y2 - y1 + 1); newCursor.fill(Qt::transparent); QPainter p(&newCursor); const QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y())); - p.drawPixmap(pmDest, drawPixmap); + p.drawPixmap(pmDest, scaledPixmap); p.drawPixmap(qMax(0, hotSpot.x()),qMax(0, hotSpot.y()), cursorPixmap); newPixmap = newCursor; newHotSpot = QPoint(qMax(0, hotSpot.x()), qMax(0, hotSpot.y())); @@ -454,7 +464,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect) if (!m_touchDragWindow) m_touchDragWindow = new QWindowsDragCursorWindow; m_touchDragWindow->setPixmap(e.pixmap); - m_touchDragWindow->setFramePosition((QWindowsCursor::mousePosition() - e.hotSpot) / QWindowsScaling::factor()); + m_touchDragWindow->setFramePosition(QWindowsCursor::mousePosition() - e.hotSpot); if (!m_touchDragWindow->isVisible()) m_touchDragWindow->show(); break; @@ -530,9 +540,7 @@ void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState, QGuiApplicationPrivate::mouse_buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState); const QPlatformDragQtResponse response = - QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(), - m_lastPoint / QWindowsScaling::factor(), - actions); + QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(), m_lastPoint, actions); m_answerRect = response.answerRect(); const Qt::DropAction action = response.acceptedAction(); @@ -625,9 +633,8 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, const QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(m_window, windowsDrag->dropData(), - m_lastPoint / QWindowsScaling::factor(), - translateToQDragDropActions(m_chosenEffect)); - + m_lastPoint, + translateToQDragDropActions(*pdwEffect)); if (response.isAccepted()) { const Qt::DropAction action = response.acceptedAction(); if (action == Qt::MoveAction || action == Qt::TargetMoveAction) { diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index a544b9d81e746787e751a64355c3a311cd44bad8..1c5b114efd450b24c62679ba15d4d8542cacd604 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1169,23 +1169,19 @@ QT_WARNING_POP CustomFontFileLoader fontFileLoader; fontFileLoader.addKey(this, fontData); - IDWriteFactory *factory = 0; - HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, - __uuidof(IDWriteFactory), - reinterpret_cast<IUnknown **>(&factory)); - if (FAILED(hres)) { - qErrnoWarning(hres, "%s: DWriteCreateFactory failed", __FUNCTION__); + QSharedPointer<QWindowsFontEngineData> fontEngineData = sharedFontData(); + if (!initDirectWrite(fontEngineData.data())) return 0; - } IDWriteFontFile *fontFile = 0; void *key = this; - hres = factory->CreateCustomFontFileReference(&key, sizeof(void *), - fontFileLoader.loader(), &fontFile); + HRESULT hres = fontEngineData->directWriteFactory->CreateCustomFontFileReference(&key, + sizeof(void *), + fontFileLoader.loader(), + &fontFile); if (FAILED(hres)) { qErrnoWarning(hres, "%s: CreateCustomFontFileReference failed", __FUNCTION__); - factory->Release(); return 0; } @@ -1196,30 +1192,31 @@ QT_WARNING_POP fontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, &numberOfFaces); if (!isSupportedFontType) { fontFile->Release(); - factory->Release(); return 0; } IDWriteFontFace *directWriteFontFace = 0; - hres = factory->CreateFontFace(fontFaceType, 1, &fontFile, 0, DWRITE_FONT_SIMULATIONS_NONE, - &directWriteFontFace); + hres = fontEngineData->directWriteFactory->CreateFontFace(fontFaceType, + 1, + &fontFile, + 0, + DWRITE_FONT_SIMULATIONS_NONE, + &directWriteFontFace); if (FAILED(hres)) { qErrnoWarning(hres, "%s: CreateFontFace failed", __FUNCTION__); fontFile->Release(); - factory->Release(); return 0; } fontFile->Release(); fontEngine = new QWindowsFontEngineDirectWrite(directWriteFontFace, pixelSize, - sharedFontData()); + fontEngineData); // Get font family from font data fontEngine->fontDef.family = font.familyName(); directWriteFontFace->Release(); - factory->Release(); } #endif diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index ef2ad110ca8d7277305ef9d610265ecac86d9aea..16b9118e81db5c7ba7f9741a82ed0e66b029fd7d 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -671,7 +671,7 @@ void QWindowsFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qre bool QWindowsFontEngine::hasUnreliableGlyphOutline() const { - return hasUnreliableOutline; + return hasUnreliableOutline || QFontEngine::hasUnreliableGlyphOutline(); } qreal QWindowsFontEngine::minLeftBearing() const diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 0cce171340d3185dfa7b9c14a751ef26c65fec31..485b876fc71e1aa4f558900f9779cc9ade8c4d5d 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -36,7 +36,6 @@ #include "qwindowswindow.h" #include "qwindowsintegration.h" #include "qwindowsmousehandler.h" -#include "qwindowsscaling.h" #include <QtCore/QDebug> #include <QtCore/QObject> @@ -243,10 +242,9 @@ void QWindowsInputContext::cursorRectChanged() if (!m_compositionContext.hwnd) return; const QInputMethod *inputMethod = QGuiApplication::inputMethod(); - const QRect cursorRectangleDip = inputMethod->cursorRectangle().toRect(); - if (!cursorRectangleDip.isValid()) + const QRect cursorRectangle = inputMethod->cursorRectangle().toRect(); + if (!cursorRectangle.isValid()) return; - const QRect cursorRectangle = QWindowsScaling::mapToNative(cursorRectangleDip); qCDebug(lcQpaInputMethods) << __FUNCTION__<< cursorRectangle; diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 9b0f126241148c6d827d6ae53ebf86bc739ca0aa..05c7e6b24067938f3099ab110047e4c09efd6eb5 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -33,7 +33,6 @@ ****************************************************************************/ #include "qwindowsintegration.h" -#include "qwindowsscaling.h" #include "qwindowswindow.h" #include "qwindowscontext.h" #include "qwindowsopenglcontext.h" @@ -64,6 +63,7 @@ # include "qwindowssessionmanager.h" #endif #include <QtGui/private/qguiapplication_p.h> +#include <QtGui/private/qhighdpiscaling_p.h> #include <QtGui/qpa/qplatforminputcontextfactory_p.h> #include <QtCore/private/qeventdispatcher_win_p.h> @@ -223,12 +223,8 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mL m_context.setProcessDpiAwareness(dpiAwareness); dpiAwarenessSet = true; } - // Determine suitable scale factor, don't mix Windows and Qt scaling - if (dpiAwareness != QtWindows::ProcessDpiUnaware) - QWindowsScaling::setFactor(QWindowsScaling::determineUiScaleFactor()); qCDebug(lcQpaWindows) - << __FUNCTION__ << "DpiAwareness=" << dpiAwareness <<",Scaling=" - << QWindowsScaling::factor(); + << __FUNCTION__ << "DpiAwareness=" << dpiAwareness; QTouchDevice *touchDevice = m_context.touchDevice(); if (touchDevice) { @@ -307,7 +303,7 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const { QWindowsWindowData requested; requested.flags = window->flags(); - requested.geometry = QWindowsScaling::mapToNative(window->geometry()); + requested.geometry = QHighDpi::toNativePixels(window->geometry(), window); // Apply custom margins (see QWindowsWindow::setCustomMargins())). const QVariant customMarginsV = window->property("_q_windowsCustomMargins"); if (customMarginsV.isValid()) @@ -327,7 +323,7 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const window->setFlags(obtained.flags); // Trigger geometry change signals of QWindow. if ((obtained.flags & Qt::Desktop) != Qt::Desktop && requested.geometry != obtained.geometry) - QWindowSystemInterface::handleGeometryChange(window, QWindowsScaling::mapFromNative(obtained.geometry)); + QWindowSystemInterface::handleGeometryChange(window, obtained.geometry); } return obtained; diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index d47c7df9e0928cf52769d63e40ec1f14a2c5150a..3636bb78938d3097c74a5c67eaf8ed431068db65 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -35,12 +35,12 @@ #include "qwindowscontext.h" #include "qwindowswindow.h" #include "qwindowsguieventdispatcher.h" -#include "qwindowsscaling.h" #include "qwindowsinputcontext.h" #include <QtGui/QWindow> #include <qpa/qwindowsysteminterface.h> #include <private/qguiapplication_p.h> +#include <private/qhighdpiscaling_p.h> #include <QtGui/QKeyEvent> #if defined(WM_APPCOMMAND) @@ -792,10 +792,12 @@ static void showSystemMenu(QWindow* w) #undef enabled #undef disabled #endif // !Q_OS_WINCE - const QPoint topLeft = topLevel->geometry().topLeft() * QWindowsScaling::factor(); + const QPoint pos = QHighDpi::toNativePixels(topLevel->geometry().topLeft(), topLevel); const int ret = TrackPopupMenuEx(menu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD, - topLeft.x(), topLeft.y(), topLevelHwnd, 0); + pos.x(), pos.y(), + topLevelHwnd, + 0); if (ret) qWindowsWndProc(topLevelHwnd, WM_SYSCOMMAND, ret, 0); } diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index d8ccccdf4501cce41e7b7caab2b50b2485669195..f86ab9fee3d34bda5f5e5098464d6dfcd6e1d669 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -995,6 +995,7 @@ QVector<FORMATETC> QWindowsMimeImage::formatsForMime(const QString &mimeType, co if (!image.isNull() && image.hasAlphaChannel()) formatetcs += setCf(CF_DIBV5); formatetcs += setCf(CF_DIB); + formatetcs += setCf(CF_PNG); // QTBUG-86848, Paste into GIMP queries for PNG. } return formatetcs; } @@ -1025,13 +1026,15 @@ bool QWindowsMimeImage::canConvertFromMime(const FORMATETC &formatetc, const QMi return false; // QTBUG-11463, deny CF_DIB support for images with alpha to prevent loss of // transparency in conversion. - return cf == CF_DIBV5 || (cf == CF_DIB && !image.hasAlphaChannel()); + return cf == CF_DIBV5 + || (cf == CF_DIB && !image.hasAlphaChannel()) + || cf == int(CF_PNG); } bool QWindowsMimeImage::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const { int cf = getCf(formatetc); - if ((cf == CF_DIB || cf == CF_DIBV5) && mimeData->hasImage()) { + if ((cf == CF_DIB || cf == CF_DIBV5 || cf == int(CF_PNG)) && mimeData->hasImage()) { QImage img = qvariant_cast<QImage>(mimeData->imageData()); if (img.isNull()) return false; @@ -1042,6 +1045,12 @@ bool QWindowsMimeImage::convertFromMime(const FORMATETC &formatetc, const QMimeD const QByteArray ba = writeDib(img); if (!ba.isEmpty()) return setData(ba, pmedium); + } else if (cf == int(CF_PNG)) { + QBuffer buffer(&ba); + const bool written = buffer.open(QIODevice::WriteOnly) && img.save(&buffer, "PNG"); + buffer.close(); + if (written) + return setData(ba, pmedium); } else { QDataStream s(&ba, QIODevice::WriteOnly); s.setByteOrder(QDataStream::LittleEndian);// Intel byte order #### diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index db635b602bd51db9d459341a2c8805f52144b43f..a8aea05fd8d32faa66ae151fa29c959ba97d2000 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -211,10 +211,8 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, const QPoint globalPosition = winEventPosition; const QPoint clientPosition = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPosition); const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons(); - QWindowSystemInterface::handleFrameStrutMouseEvent(window, - clientPosition / QWindowsScaling::factor(), - globalPosition / QWindowsScaling::factor(), - buttons, + QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition, + globalPosition, buttons, QWindowsKeyMapper::queryKeyboardModifiers(), source); return false; // Allow further event processing (dragging of windows). @@ -279,7 +277,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, // ChildWindowFromPointEx() may not find the Qt window (failing with ERROR_ACCESS_DENIED) if (!currentWindowUnderMouse) { const QRect clientRect(QPoint(0, 0), window->size()); - if (clientRect.contains(winEventPosition / QWindowsScaling::factor())) + if (clientRect.contains(winEventPosition)) currentWindowUnderMouse = window; } @@ -366,10 +364,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, m_windowUnderMouse = currentWindowUnderMouse; } - QWindowSystemInterface::handleMouseEvent(window, - winEventPosition / QWindowsScaling::factor(), - globalPosition / QWindowsScaling::factor(), - buttons, + QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons, QWindowsKeyMapper::queryKeyboardModifiers(), source); m_previousCaptureWindow = hasCapture ? window : 0; @@ -404,11 +399,9 @@ static void redirectWheelEvent(QWindow *window, const QPoint &globalPos, int del } if (handleEvent) { - const QPoint posDip = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos) / QWindowsScaling::factor(); QWindowSystemInterface::handleWheelEvent(receiver, - posDip, globalPos / QWindowsScaling::factor(), - delta / QWindowsScaling::factor(), - orientation, mods); + QWindowsGeometryHint::mapFromGlobal(receiver, globalPos), + globalPos, delta, orientation, mods); } } @@ -495,7 +488,6 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND hwnd, Q_ASSERT(QWindowsContext::user32dll.getTouchInputInfo); QWindowsContext::user32dll.getTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT)); - const qreal screenPosFactor = 0.01 / qreal(QWindowsScaling::factor()); for (int i = 0; i < winTouchPointCount; ++i) { const TOUCHINPUT &winTouchInput = winTouchInputs[i]; int id = m_touchInputIDToTouchPointID.value(winTouchInput.dwID, -1); @@ -509,9 +501,9 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND hwnd, if (m_lastTouchPositions.contains(id)) touchPoint.normalPosition = m_lastTouchPositions.value(id); - const QPointF screenPos = QPointF(winTouchInput.x, winTouchInput.y) * screenPosFactor; + const QPointF screenPos = QPointF(winTouchInput.x, winTouchInput.y) / qreal(100.); if (winTouchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA) - touchPoint.area.setSize(QSizeF(winTouchInput.cxContact, winTouchInput.cyContact) * screenPosFactor); + touchPoint.area.setSize(QSizeF(winTouchInput.cxContact, winTouchInput.cyContact) / qreal(100.)); touchPoint.area.moveCenter(screenPos); QPointF normalPosition = QPointF(screenPos.x() / screenGeometry.width(), screenPos.y() / screenGeometry.height()); diff --git a/src/plugins/platforms/windows/qwindowsnativeimage.h b/src/plugins/platforms/windows/qwindowsnativeimage.h index 6f9ce93ef0443f2c565eb61f603662311e9040f3..80a1de1ea5bb0c141a2726242b3f157c065ff903 100644 --- a/src/plugins/platforms/windows/qwindowsnativeimage.h +++ b/src/plugins/platforms/windows/qwindowsnativeimage.h @@ -57,8 +57,6 @@ public: HDC hdc() const { return m_hdc; } - void setDevicePixelRatio(qreal scaleFactor) { m_image.setDevicePixelRatio(scaleFactor); } - static QImage::Format systemFormat(); private: diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index 2e6a43f596bc4b55b3694c8a4c4cf609a9deaa70..52e83395d188e928a245749e66966bbda7603c4b 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -224,7 +224,7 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c #elif defined(Q_OS_WINCE) return QWindowsOpenGLTester::Gles; #else - QOpenGLConfig::Gpu qgpu = QOpenGLConfig::Gpu::fromDevice(gpu.deviceId, gpu.vendorId, gpu.driverVersion); + QOpenGLConfig::Gpu qgpu = QOpenGLConfig::Gpu::fromDevice(gpu.vendorId, gpu.deviceId, gpu.driverVersion, gpu.description); SupportedRenderersCache *srCache = supportedRenderersCache(); SupportedRenderersCache::const_iterator it = srCache->find(qgpu); if (it != srCache->cend()) @@ -250,19 +250,19 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c qCDebug(lcQpaGl) << "GPU features:" << features; if (features.contains(QStringLiteral("disable_desktopgl"))) { // Qt-specific - qCWarning(lcQpaGl) << "Disabling Desktop GL: " << gpu; + qCDebug(lcQpaGl) << "Disabling Desktop GL: " << gpu; result &= ~QWindowsOpenGLTester::DesktopGl; } if (features.contains(QStringLiteral("disable_angle"))) { // Qt-specific keyword - qCWarning(lcQpaGl) << "Disabling ANGLE: " << gpu; + qCDebug(lcQpaGl) << "Disabling ANGLE: " << gpu; result &= ~QWindowsOpenGLTester::GlesMask; } else { if (features.contains(QStringLiteral("disable_d3d11"))) { // standard keyword - qCWarning(lcQpaGl) << "Disabling D3D11: " << gpu; + qCDebug(lcQpaGl) << "Disabling D3D11: " << gpu; result &= ~QWindowsOpenGLTester::AngleRendererD3d11; } if (features.contains(QStringLiteral("disable_d3d9"))) { // Qt-specific - qCWarning(lcQpaGl) << "Disabling D3D9: " << gpu; + qCDebug(lcQpaGl) << "Disabling D3D9: " << gpu; result &= ~QWindowsOpenGLTester::AngleRendererD3d9; } } diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h index 748885542d50c839adcae97ff745c3397ed1b854..3cd8bf4d4bec9c7f43046ed7503dabfc9aad0073 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.h +++ b/src/plugins/platforms/windows/qwindowsopengltester.h @@ -36,7 +36,7 @@ #include <QtCore/QByteArray> #include <QtCore/QFlags> -#include <private/qversionnumber_p.h> +#include <QtCore/qversionnumber.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsscaling.h b/src/plugins/platforms/windows/qwindowsscaling.h deleted file mode 100644 index 39e554bbe210389ca272f2b144512390722608d5..0000000000000000000000000000000000000000 --- a/src/plugins/platforms/windows/qwindowsscaling.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWINDOWSSCALING_H -#define QWINDOWSSCALING_H - -#include <QtGui/QRegion> -#include <QtCore/QVector> -#include <QtCore/QRect> - -QT_BEGIN_NAMESPACE - -enum -#if defined(Q_COMPILER_CLASS_ENUM) || defined(Q_CC_MSVC) - : int -#endif -{ QWINDOWSIZE_MAX = 16777215 }; - -class QWindowsScaling { -public: - static bool isActive() { return m_factor > 1; } - static int factor() { return m_factor; } - static void setFactor(int factor) { m_factor = factor; } - static int determineUiScaleFactor(); - - // Scaling helpers for size constraints. - static int mapToNativeConstrained(int qt) - { return m_factor != 1 && qt > 0 && qt < QWINDOWSIZE_MAX ? qt * m_factor : qt; } - - static int mapFromNativeConstrained(int dp) - { return m_factor != 1 && dp > 0 && dp < QWINDOWSIZE_MAX ? dp / m_factor : dp; } - - static QSize mapToNativeConstrained(const QSize &qt) - { return QSize(mapToNativeConstrained(qt.width()), mapToNativeConstrained(qt.height())); } - - static QRect mapToNative(const QRect &qRect) - { - return QRect(qRect.x() * m_factor, qRect.y() * m_factor, qRect.width() * m_factor, qRect.height() * m_factor); - } - - static QRect mapFromNative(const QRect &dp) - { - return isActive() ? - QRect(dp.x() / m_factor, dp.y() / m_factor, (dp.width() + 1) / m_factor, (dp.height() + 1) / m_factor) : - dp; - } - - static QRegion mapToNative(const QRegion ®ionQt) - { - if (!QWindowsScaling::isActive() || regionQt.isEmpty()) - return regionQt; - - QRegion result; - foreach (const QRect &rectQt, regionQt.rects()) - result += QWindowsScaling::mapToNative(rectQt); - return result; - } - - static QRegion mapFromNative(const QRegion ®ionDp) - { - if (!QWindowsScaling::isActive() || regionDp.isEmpty()) - return regionDp; - - QRegion result; - foreach (const QRect &rectDp, regionDp.rects()) - result += QWindowsScaling::mapFromNative(rectDp); - return result; - } - -private: - static int m_factor; -}; - -QT_END_NAMESPACE - -#endif // QWINDOWSSCALING_H diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index 7756c77001370d64bb994d7ee58edf887859d6d6..391735a035740eaabf2d20e7dcd7bd7f333260b3 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -43,6 +43,7 @@ #include <QtGui/QPixmap> #include <QtGui/QGuiApplication> #include <qpa/qwindowsysteminterface.h> +#include <private/qhighdpiscaling_p.h> #include <QtGui/QScreen> #include <QtCore/QDebug> @@ -218,36 +219,14 @@ QWindowsScreen::QWindowsScreen(const QWindowsScreenData &data) : { } -BOOL QT_WIN_CALLBACK monitorResolutionEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM p) -{ - QWindowsScreenData data; - if (monitorData(hMonitor, &data)) { - int *maxHorizResolution = reinterpret_cast<int *>(p); - const int horizResolution = qRound(data.dpi.first); - if (horizResolution > *maxHorizResolution) - *maxHorizResolution = horizResolution; - } - return TRUE; -} - -int QWindowsScreen::maxMonitorHorizResolution() -{ - int result = 0; - EnumDisplayMonitors(0, 0, monitorResolutionEnumCallback, (LPARAM)&result); - return result; -} - Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0); -QPixmap QWindowsScreen::grabWindow(WId window, int qX, int qY, int qWidth, int qHeight) const +QPixmap QWindowsScreen::grabWindow(WId window, int x, int y, int width, int height) const { RECT r; HWND hwnd = window ? (HWND)window : GetDesktopWindow(); GetClientRect(hwnd, &r); - const int x = qX * QWindowsScaling::factor(); - const int y = qY * QWindowsScaling::factor(); - int width = qWidth * QWindowsScaling::factor(); - int height = qHeight * QWindowsScaling::factor(); + if (width < 0) width = r.right - r.left; if (height < 0) height = r.bottom - r.top; @@ -271,10 +250,6 @@ QPixmap QWindowsScreen::grabWindow(WId window, int qX, int qY, int qWidth, int q DeleteObject(bitmap); ReleaseDC(0, display_dc); - if (QWindowsScaling::isActive()) { - const qreal factor = 1.0 / qreal(QWindowsScaling::factor()); - return pixmap.transformed(QTransform::fromScale(factor, factor)); - } return pixmap; } @@ -285,7 +260,7 @@ QPixmap QWindowsScreen::grabWindow(WId window, int qX, int qY, int qWidth, int q QWindow *QWindowsScreen::topLevelAt(const QPoint &point) const { QWindow *result = 0; - if (QWindow *child = QWindowsScreen::windowAt(point * QWindowsScaling::factor(), CWP_SKIPINVISIBLE)) + if (QWindow *child = QWindowsScreen::windowAt(point, CWP_SKIPINVISIBLE)) result = QWindowsWindow::topLevelOf(child); qCDebug(lcQpaWindows) <<__FUNCTION__ << point << result; return result; @@ -313,6 +288,12 @@ QWindowsScreen *QWindowsScreen::screenOf(const QWindow *w) return 0; } +qreal QWindowsScreen::pixelDensity() const +{ + const qreal physicalDpi = m_data.geometry.width() / m_data.physicalSizeMM.width() * qreal(25.4); + return qRound(physicalDpi / 96); +} + /*! \brief Determine siblings in a virtual desktop system. @@ -542,7 +523,7 @@ void QWindowsScreenManager::clearScreens() const QWindowsScreen *QWindowsScreenManager::screenAtDp(const QPoint &p) const { foreach (QWindowsScreen *scr, m_screens) { - if (scr->geometryDp().contains(p)) + if (scr->geometry().contains(p)) return scr; } return Q_NULLPTR; diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h index 7352c457779af695c908fbf5019950441fa96d27..67e7ff644be705bfbd947521029b24d4c30ff236 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.h +++ b/src/plugins/platforms/windows/qwindowsscreen.h @@ -34,7 +34,6 @@ #ifndef QWINDOWSSCREEN_H #define QWINDOWSSCREEN_H -#include "qwindowsscaling.h" #include "qtwindowsglobal.h" #ifdef Q_OS_WINCE # include "qplatformfunctions_wince.h" @@ -82,16 +81,14 @@ public: static QWindowsScreen *screenOf(const QWindow *w = 0); - QRect geometryDp() const { return m_data.geometry; } - QRect geometry() const Q_DECL_OVERRIDE { return QWindowsScaling::mapFromNative(geometryDp()); } - QRect availableGeometryDp() const { return m_data.availableGeometry; } - QRect availableGeometry() const Q_DECL_OVERRIDE { return QWindowsScaling::mapFromNative(availableGeometryDp()); } + QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; } + QRect availableGeometry() const Q_DECL_OVERRIDE { return m_data.availableGeometry; } int depth() const Q_DECL_OVERRIDE { return m_data.depth; } QImage::Format format() const Q_DECL_OVERRIDE { return m_data.format; } QSizeF physicalSize() const Q_DECL_OVERRIDE { return m_data.physicalSizeMM; } - QDpi logicalDpi() const Q_DECL_OVERRIDE - { return QDpi(m_data.dpi.first / QWindowsScaling::factor(), m_data.dpi.second / QWindowsScaling::factor()); } - qreal devicePixelRatio() const Q_DECL_OVERRIDE { return QWindowsScaling::factor(); } + QDpi logicalDpi() const Q_DECL_OVERRIDE { return m_data.dpi; } + qreal pixelDensity() const Q_DECL_OVERRIDE; + qreal devicePixelRatio() const Q_DECL_OVERRIDE { return 1.0; } qreal refreshRate() const Q_DECL_OVERRIDE { return m_data.refreshRateHz; } QString name() const Q_DECL_OVERRIDE { return m_data.name; } Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE { return m_data.orientation; } @@ -112,7 +109,6 @@ public: #endif // !QT_NO_CURSOR const QWindowsScreenData &data() const { return m_data; } - static int maxMonitorHorizResolution(); private: QWindowsScreenData m_data; diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index 7b871be01511ca1a828fe53a1900e255b5db5bb0..05bddec5302c57d5a86155ef993801318441f6f6 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -32,7 +32,6 @@ ****************************************************************************/ #include "qwindowstabletsupport.h" -#include "qwindowsscaling.h" #ifndef QT_NO_TABLETEVENT @@ -399,8 +398,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent() // in which case we snap the position to the mouse position. // It seems there is no way to find out the mode programmatically, the LOGCONTEXT orgX/Y/Ext // area is always the virtual desktop. - const QRect virtualDesktopArea - = QWindowsScaling::mapToNative(QGuiApplication::primaryScreen()->virtualGeometry()); + const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry(); qCDebug(lcQpaTablet) << __FUNCTION__ << "processing " << packetCount << "target:" << QGuiApplicationPrivate::tabletPressTarget; @@ -420,7 +418,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent() QPoint globalPos = globalPosF.toPoint(); // Get Mouse Position and compare to tablet info - QPoint mouseLocation = QWindowsCursor::mousePosition(); + const QPoint mouseLocation = QWindowsCursor::mousePosition(); // Positions should be almost the same if we are in absolute // mode. If they are not, use the mouse location. @@ -475,9 +473,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent() << tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation; } - const QPointF localPosDip = QPointF(localPos / QWindowsScaling::factor()); - const QPointF globalPosDip = globalPosF / qreal(QWindowsScaling::factor()); - QWindowSystemInterface::handleTabletEvent(target, localPosDip, globalPosDip, + QWindowSystemInterface::handleTabletEvent(target, QPointF(localPos), globalPosF, currentDevice, currentPointer, static_cast<Qt::MouseButtons>(packet.pkButtons), pressureNew, tiltX, tiltY, diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index d3f67e9eaaa063bd3395f004de8d1e5e29f7114f..33c7ccfdce84696cfab44c25543c678b06927e9f 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -43,7 +43,6 @@ #include "qwindowsintegration.h" #include "qt_windows.h" #include "qwindowsfontdatabase.h" -#include "qwindowsscaling.h" #ifdef Q_OS_WINCE # include "qplatformfunctions_wince.h" # include "winuser.h" @@ -68,6 +67,7 @@ #include <QtGui/QPainter> #include <QtGui/QPixmapCache> #include <qpa/qwindowsysteminterface.h> +#include <private/qhighdpiscaling_p.h> #include <private/qsystemlibrary_p.h> #include <algorithm> @@ -495,7 +495,8 @@ static QPixmap loadIconFromShell32(int resourceId, QSizeF size) QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const { - const int scaleFactor = QWindowsScaling::factor(); + const QScreen *primaryScreen = QGuiApplication::primaryScreen(); + const int scaleFactor = primaryScreen ? qRound(QHighDpiScaling::factor(primaryScreen)) : 1; const QSizeF pixmapSize = size * scaleFactor; int resourceId = -1; LPCTSTR iconName = 0; @@ -632,7 +633,7 @@ public: static FakePointer *create(T thing) { - return reinterpret_cast<FakePointer *>(thing); + return reinterpret_cast<FakePointer *>(qintptr(thing)); } T operator * () const @@ -720,6 +721,7 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s iconSize|SHGFI_SYSICONINDEX; #endif // Q_OS_WINCE unsigned long val = 0; +#if !defined(QT_NO_WINCE_SHELLSDK) if (cacheableDirIcon && useDefaultFolderIcon) { flags |= SHGFI_USEFILEATTRIBUTES; val = SHGetFileInfo(L"dummy", @@ -729,6 +731,7 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s val = SHGetFileInfo(reinterpret_cast<const wchar_t *>(filePath.utf16()), 0, &info, sizeof(SHFILEINFO), flags); } +#endif // !QT_NO_WINCE_SHELLSDK // Even if GetFileInfo returns a valid result, hIcon can be empty in some cases if (val && info.hIcon) { diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 543c08135f80d6f377830896247e4fba0882a028..87747a74fd0d044f5cf2940cc92d3e18e6656b78 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -36,7 +36,6 @@ #include "qwindowscontext.h" #include "qwindowsdrag.h" #include "qwindowsscreen.h" -#include "qwindowsscaling.h" #include "qwindowsintegration.h" #include "qwindowsopenglcontext.h" #ifdef QT_NO_CURSOR @@ -49,8 +48,9 @@ #include <QtGui/QRegion> #include <QtGui/QOpenGLContext> #include <private/qsystemlibrary_p.h> -#include <private/qwindow_p.h> +#include <private/qwindow_p.h> // QWINDOWSIZE_MAX #include <private/qguiapplication_p.h> +#include <private/qhighdpiscaling_p.h> #include <qpa/qwindowsysteminterface.h> #include <QtCore/QDebug> @@ -169,7 +169,7 @@ static QPoint windowPlacementOffset(HWND hwnd, const QPoint &point) const QWindowsScreen *screen = screenManager.screens().size() == 1 ? screenManager.screens().first() : screenManager.screenAtDp(point); if (screen) - return screen->availableGeometryDp().topLeft() - screen->geometryDp().topLeft(); + return screen->availableGeometry().topLeft() - screen->geometry().topLeft(); #else Q_UNUSED(hwnd) Q_UNUSED(point) @@ -608,9 +608,7 @@ QWindowsWindowData const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w); - const QRect geometryDip = QWindowsScaling::mapFromNative(data.geometry); - QRect fixedGeometryDip = QPlatformWindow::initialGeometry(w, geometryDip, defaultWindowWidth, defaultWindowHeight); - const QRect rect = fixedGeometryDip != geometryDip ? QWindowsScaling::mapToNative(fixedGeometryDip) : data.geometry; + const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry, defaultWindowWidth, defaultWindowHeight); if (title.isEmpty() && (result.flags & Qt::WindowTitleHint)) title = topLevel ? qAppName() : w->objectName(); @@ -706,6 +704,20 @@ void WindowCreationData::initialize(const QWindow *w, HWND hwnd, bool frameChang } } + +// Scaling helpers for size constraints. +static QSize toNativeSizeConstrained(QSize dip, const QWindow *w) +{ + if (QHighDpiScaling::isActive()) { + const qreal factor = QHighDpiScaling::factor(w); + if (dip.width() > 0 && dip.width() < QWINDOWSIZE_MAX) + dip.rwidth() *= factor; + if (dip.height() > 0 && dip.height() < QWINDOWSIZE_MAX) + dip.rheight() *= factor; + } + return dip; +} + /*! \class QWindowsGeometryHint \brief Stores geometry constraints and provides utility functions. @@ -718,8 +730,8 @@ void WindowCreationData::initialize(const QWindow *w, HWND hwnd, bool frameChang */ QWindowsGeometryHint::QWindowsGeometryHint(const QWindow *w, const QMargins &cm) : - minimumSize(QWindowsScaling::mapToNativeConstrained(w->minimumSize())), - maximumSize(QWindowsScaling::mapToNativeConstrained(w->maximumSize())), + minimumSize(toNativeSizeConstrained(w->minimumSize(), w)), + maximumSize(toNativeSizeConstrained(w->maximumSize(), w)), customMargins(cm) { } @@ -953,8 +965,7 @@ void QWindowsWindow::fireExpose(const QRegion ®ion, bool force) clearFlag(Exposed); else setFlag(Exposed); - QWindowSystemInterface::handleExposeEvent(window(), - QWindowsScaling::mapFromNative(region)); + QWindowSystemInterface::handleExposeEvent(window(), region); } static inline QWindow *findTransientChild(const QWindow *parent) @@ -1134,7 +1145,7 @@ bool QWindowsWindow::isEmbedded(const QPlatformWindow *parentWindow) const return m_data.embedded; } -QPoint QWindowsWindow::mapToGlobalDp(const QPoint &pos) const +QPoint QWindowsWindow::mapToGlobal(const QPoint &pos) const { if (m_data.hwnd) return QWindowsGeometryHint::mapToGlobal(m_data.hwnd, pos); @@ -1142,7 +1153,7 @@ QPoint QWindowsWindow::mapToGlobalDp(const QPoint &pos) const return pos; } -QPoint QWindowsWindow::mapFromGlobalDp(const QPoint &pos) const +QPoint QWindowsWindow::mapFromGlobal(const QPoint &pos) const { if (m_data.hwnd) return QWindowsGeometryHint::mapFromGlobal(m_data.hwnd, pos); @@ -1323,22 +1334,22 @@ static QRect normalFrameGeometry(HWND hwnd) return QRect(); } -QRect QWindowsWindow::normalGeometryDp() const +QRect QWindowsWindow::normalGeometry() const { // Check for fake 'fullscreen' mode. const bool fakeFullScreen = m_savedFrameGeometry.isValid() && window()->windowState() == Qt::WindowFullScreen; const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd); - const QMargins margins = fakeFullScreen ? QWindowsGeometryHint::frame(m_savedStyle, 0) : frameMarginsDp(); + const QMargins margins = fakeFullScreen ? QWindowsGeometryHint::frame(m_savedStyle, 0) : frameMargins(); return frame.isValid() ? frame.marginsRemoved(margins) : frame; } -void QWindowsWindow::setGeometryDp(const QRect &rectIn) +void QWindowsWindow::setGeometry(const QRect &rectIn) { QRect rect = rectIn; // This means it is a call from QWindow::setFramePosition() and // the coordinates include the frame (size is still the contents rectangle). if (QWindowsGeometryHint::positionIncludesFrame(window())) { - const QMargins margins = frameMarginsDp(); + const QMargins margins = frameMargins(); rect.moveTopLeft(rect.topLeft() + QPoint(margins.left(), margins.top())); } if (m_windowState == Qt::WindowMinimized) @@ -1407,9 +1418,8 @@ void QWindowsWindow::handleGeometryChange() return; const QRect previousGeometry = m_data.geometry; m_data.geometry = geometry_sys(); - const QRect geometryDip = QWindowsScaling::mapFromNative(m_data.geometry); - QPlatformWindow::setGeometry(geometryDip); - QWindowSystemInterface::handleGeometryChange(window(), geometryDip); + QPlatformWindow::setGeometry(m_data.geometry); + QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry); // QTBUG-32121: OpenGL/normal windows (with exception of ANGLE) do not receive // expose events when shrinking, synthesize. if (!testFlag(OpenGL_ES2) && isExposed() @@ -1417,7 +1427,7 @@ void QWindowsWindow::handleGeometryChange() fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true); } if (previousGeometry.topLeft() != m_data.geometry.topLeft()) { - QPlatformScreen *newScreen = screenForGeometry(geometryDip); + QPlatformScreen *newScreen = screenForGeometry(m_data.geometry); if (newScreen != screen()) QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); } @@ -1429,7 +1439,7 @@ void QWindowsWindow::handleGeometryChange() void QWindowsWindow::setGeometry_sys(const QRect &rect) const { - const QMargins margins = frameMarginsDp(); + const QMargins margins = frameMargins(); const QRect frameGeometry = rect + margins; qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << window() @@ -1468,7 +1478,7 @@ QRect QWindowsWindow::frameGeometry_sys() const QRect QWindowsWindow::geometry_sys() const { - return frameGeometry_sys().marginsRemoved(frameMarginsDp()); + return frameGeometry_sys().marginsRemoved(frameMargins()); } /*! @@ -1540,7 +1550,7 @@ void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags) { qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window() << "\n from: " << m_data.flags << "\n to: " << flags; - const QRect oldGeometry = geometryDp(); + const QRect oldGeometry = geometry(); if (m_data.flags != flags) { m_data.flags = flags; if (m_data.hwnd) { @@ -1626,8 +1636,9 @@ void QWindowsWindow::setWindowState(Qt::WindowState state) bool QWindowsWindow::isFullScreen_sys() const { - return window()->isTopLevel() - && geometry_sys() == QWindowsScaling::mapToNative(window()->screen()->geometry()); + const QWindow *w = window(); + return w->isTopLevel() + && geometry_sys() == QHighDpi::toNativePixels(w->screen()->geometry(), w); } /*! @@ -1697,15 +1708,14 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState) // Use geometry of QWindow::screen() within creation or the virtual screen the // window is in (QTBUG-31166, QTBUG-30724). const QScreen *screen = window()->screen(); - const QRect rDip = screen->geometry(); - const QRect r = QWindowsScaling::mapToNative(rDip); + const QRect r = QHighDpi::toNativePixels(screen->geometry(), window()); const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE; const bool wasSync = testFlag(SynchronousGeometryChangeEvent); setFlag(SynchronousGeometryChangeEvent); SetWindowPos(m_data.hwnd, HWND_TOP, r.left(), r.top(), r.width(), r.height(), swpf); if (!wasSync) clearFlag(SynchronousGeometryChangeEvent); - QWindowSystemInterface::handleGeometryChange(window(), rDip); + QWindowSystemInterface::handleGeometryChange(window(), r); QWindowSystemInterface::flushWindowSystemEvents(); } else if (newState != Qt::WindowMinimized) { // Restore saved state. @@ -1804,7 +1814,7 @@ void QWindowsWindow::propagateSizeHints() qCDebug(lcQpaWindows) << __FUNCTION__ << this << window(); } -bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp) +bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &margins) { #ifndef Q_OS_WINCE if (!qWindow->isTopLevel()) // Implement hasHeightForWidth(). @@ -1812,26 +1822,19 @@ bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow * WINDOWPOS *windowPos = reinterpret_cast<WINDOWPOS *>(message->lParam); if ((windowPos->flags & (SWP_NOCOPYBITS | SWP_NOSIZE))) return false; - const QRect suggestedFrameGeometryDp(windowPos->x, windowPos->y, - windowPos->cx, windowPos->cy); - const qreal factor = QWindowsScaling::factor(); - const QRect suggestedGeometryDp = suggestedFrameGeometryDp - marginsDp; - const QRectF suggestedGeometry = QRectF(QPointF(suggestedGeometryDp.topLeft()) / factor, - QSizeF(suggestedGeometryDp.size()) / factor); - const QRectF correctedGeometryF = - qt_window_private(const_cast<QWindow *>(qWindow))->closestAcceptableGeometry(suggestedGeometry); + const QRect suggestedFrameGeometry(windowPos->x, windowPos->y, + windowPos->cx, windowPos->cy); + const QRect suggestedGeometry = suggestedFrameGeometry - margins; + const QRectF correctedGeometryF = qWindow->handle()->windowClosestAcceptableGeometry(suggestedGeometry); if (!correctedGeometryF.isValid()) return false; - const QRect correctedFrameGeometryDp - = QRectF(correctedGeometryF.topLeft() * factor, - correctedGeometryF.size() * factor).toRect() - + marginsDp; - if (correctedFrameGeometryDp == suggestedFrameGeometryDp) + const QRect correctedFrameGeometry = correctedGeometryF.toRect() + margins; + if (correctedFrameGeometry == suggestedFrameGeometry) return false; - windowPos->x = correctedFrameGeometryDp.left(); - windowPos->y = correctedFrameGeometryDp.top(); - windowPos->cx = correctedFrameGeometryDp.width(); - windowPos->cy = correctedFrameGeometryDp.height(); + windowPos->x = correctedFrameGeometry.left(); + windowPos->y = correctedFrameGeometry.top(); + windowPos->cx = correctedFrameGeometry.width(); + windowPos->cy = correctedFrameGeometry.height(); return true; #else // !Q_OS_WINCE Q_UNUSED(message) @@ -1841,11 +1844,11 @@ bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow * bool QWindowsWindow::handleGeometryChanging(MSG *message) const { - const QMargins marginsDp = window()->isTopLevel() ? frameMarginsDp() : QMargins(); - return QWindowsWindow::handleGeometryChangingMessage(message, window(), marginsDp); + const QMargins margins = window()->isTopLevel() ? frameMargins() : QMargins(); + return QWindowsWindow::handleGeometryChangingMessage(message, window(), margins); } -QMargins QWindowsWindow::frameMarginsDp() const +QMargins QWindowsWindow::frameMargins() const { // Frames are invalidated by style changes (window state, flags). // As they are also required for geometry calculations in resize @@ -1892,17 +1895,17 @@ static inline void addRectToWinRegion(const QRect &rect, HRGN *winRegion) } } -static HRGN qRegionToWinRegion(const QRegion ®ionDip) +static HRGN qRegionToWinRegion(const QRegion ®ion) { - const QVector<QRect> rects = regionDip.rects(); + const QVector<QRect> rects = region.rects(); if (rects.isEmpty()) return NULL; const int rectCount = rects.size(); if (rectCount == 1) - return createRectRegion(QWindowsScaling::mapToNative(regionDip.boundingRect())); - HRGN hRegion = createRectRegion(QWindowsScaling::mapToNative(rects.front())); + return createRectRegion(region.boundingRect()); + HRGN hRegion = createRectRegion(rects.front()); for (int i = 1; i < rectCount; ++i) - addRectToWinRegion(QWindowsScaling::mapToNative(rects.at(i)), &hRegion); + addRectToWinRegion(rects.at(i), &hRegion); return hRegion; } @@ -1916,7 +1919,7 @@ void QWindowsWindow::setMask(const QRegion ®ion) // Mask is in client area coordinates, so offset it in case we have a frame if (window()->isTopLevel()) { - const QMargins margins = frameMarginsDp(); + const QMargins margins = frameMargins(); OffsetRgn(winRegion, margins.left(), margins.top()); } @@ -2053,23 +2056,23 @@ bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *re || (m_data.flags & Qt::FramelessWindowHint)) { return false; } - const QSize minimumSize = QWindowsScaling::mapToNativeConstrained(w->minimumSize()); + const QSize minimumSize = w->minimumSize(); if (minimumSize.isEmpty()) return false; - const QSize maximumSize = QWindowsScaling::mapToNativeConstrained(w->maximumSize()); + const QSize maximumSize = w->maximumSize(); const bool fixedWidth = minimumSize.width() == maximumSize.width(); const bool fixedHeight = minimumSize.height() == maximumSize.height(); if (!fixedWidth && !fixedHeight) return false; - const QPoint localPos = mapFromGlobalDp(globalPos); - const QSize size = w->size() * QWindowsScaling::factor(); + const QPoint localPos = w->mapFromGlobal(QHighDpi::fromNativePixels(globalPos, w)); + const QSize size = w->size(); if (fixedHeight) { if (localPos.y() >= size.height()) { *result = HTBORDER; // Unspecified border, no resize cursor. return true; } if (localPos.y() < 0) { - const QMargins margins = frameMarginsDp(); + const QMargins margins = frameMargins(); const int topResizeBarPos = margins.left() - margins.top(); if (localPos.y() < topResizeBarPos) { *result = HTCAPTION; // Extend caption over top resize bar, let's user move the window. @@ -2245,10 +2248,6 @@ void QWindowsWindow::setWindowIcon(const QIcon &icon) The property can be set using QPlatformNativeInterface::setWindowProperty() or, before platform window creation, by setting a dynamic property on the QWindow (see QWindowsIntegration::createPlatformWindow()). - - Note: The function uses (unscaled) device pixels since the QWizard also - uses AdjustWindowRect() and using device independent pixels would introduce - rounding errors. */ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins) diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index fff90b4b11391209876f47450f08ee390f73d625..d96022e3a5079afcb6f21a2e769af04ee7221555 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -38,7 +38,6 @@ #ifdef Q_OS_WINCE # include "qplatformfunctions_wince.h" #endif -#include "qwindowsscaling.h" #include "qwindowscursor.h" #include <qpa/qplatformwindow.h> @@ -145,28 +144,18 @@ public: ~QWindowsWindow(); QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; } - void setGeometryDp(const QRect &rectIn); - void setGeometry(const QRect &rect) Q_DECL_OVERRIDE - { setGeometryDp(QWindowsScaling::mapToNative(rect)); } - QRect geometryDp() const { return m_data.geometry; } - QRect geometry() const Q_DECL_OVERRIDE - { return QWindowsScaling::mapFromNative(geometryDp()); } - QRect normalGeometryDp() const; - QRect normalGeometry() const Q_DECL_OVERRIDE - { return QWindowsScaling::mapFromNative(normalGeometryDp()); } - qreal devicePixelRatio() const Q_DECL_OVERRIDE - { return qreal(QWindowsScaling::factor()); } + void setGeometry(const QRect &rect) Q_DECL_OVERRIDE; + QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; } + QRect normalGeometry() const Q_DECL_OVERRIDE; + void setVisible(bool visible) Q_DECL_OVERRIDE; bool isVisible() const; bool isExposed() const Q_DECL_OVERRIDE { return testFlag(Exposed); } bool isActive() const Q_DECL_OVERRIDE; bool isEmbedded(const QPlatformWindow *parentWindow) const Q_DECL_OVERRIDE; - QPoint mapToGlobalDp(const QPoint &pos) const; - QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE - { return mapToGlobalDp(pos * QWindowsScaling::factor()) / QWindowsScaling::factor(); } - QPoint mapFromGlobalDp(const QPoint &pos) const; - QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE - { return mapFromGlobalDp(pos * QWindowsScaling::factor()) / QWindowsScaling::factor(); } + QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE; + QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE; + void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE; void setWindowState(Qt::WindowState state) Q_DECL_OVERRIDE; @@ -184,8 +173,7 @@ public: void propagateSizeHints() Q_DECL_OVERRIDE; static bool handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp); bool handleGeometryChanging(MSG *message) const; - QMargins frameMarginsDp() const; - QMargins frameMargins() const Q_DECL_OVERRIDE { return frameMarginsDp() / QWindowsScaling::factor(); } + QMargins frameMargins() const Q_DECL_OVERRIDE; void setOpacity(qreal level) Q_DECL_OVERRIDE; void setMask(const QRegion ®ion) Q_DECL_OVERRIDE; @@ -196,7 +184,7 @@ public: bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE; inline bool hasMouseCapture() const { return GetCapture() == m_data.hwnd; } - bool startSystemResize(const QPoint &, Qt::Corner corner) Q_DECL_OVERRIDE; + bool startSystemResize(const QPoint &pos, Qt::Corner corner) Q_DECL_OVERRIDE; void setFrameStrutEventsEnabled(bool enabled); bool frameStrutEventsEnabled() const { return testFlag(FrameStrutEventsEnabled); } diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index a0460630a76fcc8130863a236094ece453c1df80..6e5789a86e0dd33f14b8795b048d14cd542fefe9 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -1,14 +1,14 @@ # Note: OpenGL32 must precede Gdi32 as it overwrites some functions. LIBS *= -lole32 -!wince*:LIBS *= -luser32 -lwinspool -limm32 -lwinmm -loleaut32 +!wince: LIBS *= -luser32 -lwinspool -limm32 -lwinmm -loleaut32 contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles2):!contains(QT_CONFIG, dynamicgl): LIBS *= -lopengl32 mingw: LIBS *= -luuid # For the dialog helpers: -!wince*:LIBS *= -lshlwapi -lshell32 -!wince*:LIBS *= -ladvapi32 -wince*:DEFINES *= QT_LIBINFIX=L"\"\\\"$${QT_LIBINFIX}\\\"\"" +!wince: LIBS *= -lshlwapi -lshell32 +!wince: LIBS *= -ladvapi32 +wince: DEFINES *= QT_LIBINFIX=L"\"\\\"$${QT_LIBINFIX}\\\"\"" DEFINES *= QT_NO_CAST_FROM_ASCII @@ -40,7 +40,6 @@ SOURCES += \ $$PWD/qwindowsservices.cpp \ $$PWD/qwindowsnativeimage.cpp \ $$PWD/qwindowsnativeinterface.cpp \ - $$PWD/qwindowsscaling.cpp \ $$PWD/qwindowsopengltester.cpp HEADERS += \ @@ -67,7 +66,6 @@ HEADERS += \ $$PWD/qplatformfunctions_wince.h \ $$PWD/qwindowsnativeimage.h \ $$PWD/qwindowsnativeinterface.h \ - $$PWD/qwindowsscaling.h \ $$PWD/qwindowsopengltester.h INCLUDEPATH += $$PWD @@ -103,22 +101,22 @@ contains(QT_CONFIG,dynamicgl) { } } -!wince*:!contains( DEFINES, QT_NO_TABLETEVENT ) { +!wince:!contains( DEFINES, QT_NO_TABLETEVENT ) { INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/wintab HEADERS += $$PWD/qwindowstabletsupport.h SOURCES += $$PWD/qwindowstabletsupport.cpp } -!wince*:!contains( DEFINES, QT_NO_SESSIONMANAGER ) { +!wince:!contains( DEFINES, QT_NO_SESSIONMANAGER ) { SOURCES += $$PWD/qwindowssessionmanager.cpp HEADERS += $$PWD/qwindowssessionmanager.h } -!wince*:!contains( DEFINES, QT_NO_IMAGEFORMAT_PNG ) { +!wince:!contains( DEFINES, QT_NO_IMAGEFORMAT_PNG ) { RESOURCES += $$PWD/cursors.qrc } -!wince*: RESOURCES += $$PWD/openglblacklists.qrc +!wince: RESOURCES += $$PWD/openglblacklists.qrc contains(QT_CONFIG, freetype) { DEFINES *= QT_NO_FONTCONFIG diff --git a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationfactory.cpp b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationfactory.cpp index 10411e72e20e3628d2115a9e86f1ef947379656f..508f5e82e6c22047d93d5e3928777e85bea14ed3 100644 --- a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationfactory.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationfactory.cpp @@ -78,6 +78,7 @@ QStringList QXcbGlIntegrationFactory::keys(const QString &pluginPath) list.append(loader()->keyMap().values()); return list; #else + Q_UNUSED(pluginPath); return QStringList(); #endif } @@ -93,6 +94,9 @@ QXcbGlIntegration *QXcbGlIntegrationFactory::create(const QString &platform, con } if (QXcbGlIntegration *ret = loadIntegration(loader(), platform)) return ret; +#else + Q_UNUSED(platform); + Q_UNUSED(pluginPath); #endif return Q_NULLPTR; } diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp index 397ee229879434cfe0e4f041a14f2ca95d2668cd..37f01d4eed2bf3fcd49447ce3c81981c46230767 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp @@ -542,6 +542,9 @@ void QGLXContext::swapBuffers(QPlatformSurface *surface) void (*QGLXContext::getProcAddress(const QByteArray &procName)) () { +#ifdef QT_STATIC + return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.constData())); +#else typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *); static qt_glXGetProcAddressARB glXGetProcAddressARB = 0; static bool resolved = false; @@ -560,10 +563,12 @@ void (*QGLXContext::getProcAddress(const QByteArray &procName)) () if (!glXGetProcAddressARB) #endif { +#ifndef QT_NO_LIBRARY extern const QString qt_gl_library_name(); // QLibrary lib(qt_gl_library_name()); QLibrary lib(QLatin1String("GL")); glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB"); +#endif } } resolved = true; @@ -571,6 +576,7 @@ void (*QGLXContext::getProcAddress(const QByteArray &procName)) () if (!glXGetProcAddressARB) return 0; return (void (*)())glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.constData())); +#endif } QSurfaceFormat QGLXContext::format() const diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index c0f5477f82bbdb11b48d2ca694f654883a239dc8..e62d515b62bf291622a95dfc7fd559188c6e0abc 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -49,6 +49,7 @@ #include <qdebug.h> #include <qpainter.h> #include <qscreen.h> +#include <QtGui/private/qhighdpiscaling_p.h> #include <qpa/qplatformgraphicsbuffer.h> #include <algorithm> @@ -313,14 +314,7 @@ void QXcbBackingStore::beginPaint(const QRegion ®ion) if (!m_image) return; - int dpr = int(m_image->image()->devicePixelRatio()); - const int windowDpr = int(window()->devicePixelRatio()); - if (windowDpr != dpr) { - resize(window()->size(), QRegion()); - dpr = int(m_image->image()->devicePixelRatio()); - } - - m_paintRegion = dpr == 1 ? region : QTransform::fromScale(dpr,dpr).map(region); + m_paintRegion = region; m_image->preparePaint(m_paintRegion); if (m_image->image()->hasAlphaChannel()) { @@ -369,18 +363,10 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin if (!m_image || m_image->size().isEmpty()) return; - const int dpr = int(window->devicePixelRatio()); - -#ifndef QT_NO_DEBUG - const int imageDpr = int(m_image->image()->devicePixelRatio()); - if (dpr != imageDpr) - qWarning() << "QXcbBackingStore::flush() wrong devicePixelRatio for backingstore image" << dpr << imageDpr; -#endif - - QSize imageSize = m_image->size() / dpr; //because we multiply with the DPR later + QSize imageSize = m_image->size(); QRegion clipped = region; - clipped &= QRect(0, 0, window->width(), window->height()); + clipped &= QRect(QPoint(), QHighDpi::toNativePixels(window->size(), window)); clipped &= QRect(0, 0, imageSize.width(), imageSize.height()).translated(-offset); QRect bounds = clipped.boundingRect(); @@ -398,8 +384,8 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin QVector<QRect> rects = clipped.rects(); for (int i = 0; i < rects.size(); ++i) { - QRect rect = QRect(rects.at(i).topLeft() * dpr, rects.at(i).size() * dpr); - m_image->put(platformWindow->xcb_window(), rect.topLeft(), rect.translated(offset * dpr)); + QRect rect = QRect(rects.at(i).topLeft(), rects.at(i).size()); + m_image->put(platformWindow->xcb_window(), rect.topLeft(), rect.translated(offset)); } Q_XCB_NOOP(connection()); @@ -430,9 +416,7 @@ void QXcbBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, c void QXcbBackingStore::resize(const QSize &size, const QRegion &) { - const int dpr = int(window()->devicePixelRatio()); - const QSize xSize = size * dpr; - if (m_image && xSize == m_image->size() && dpr == m_image->image()->devicePixelRatio()) + if (m_image && size == m_image->size()) return; Q_XCB_NOOP(connection()); @@ -445,13 +429,11 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &) QXcbWindow* win = static_cast<QXcbWindow *>(pw); delete m_image; - m_image = new QXcbShmImage(screen, xSize, win->depth(), win->imageFormat()); - m_image->image()->setDevicePixelRatio(dpr); + m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat()); // Slow path for bgr888 VNC: Create an additional image, paint into that and // swap R and B while copying to m_image after each paint. if (win->imageNeedsRgbSwap()) { - m_rgbImage = QImage(xSize, win->imageFormat()); - m_rgbImage.setDevicePixelRatio(dpr); + m_rgbImage = QImage(size, win->imageFormat()); } Q_XCB_NOOP(connection()); } @@ -463,14 +445,12 @@ bool QXcbBackingStore::scroll(const QRegion &area, int dx, int dy) if (!m_image || m_image->image()->isNull()) return false; - const int dpr = int(m_image->image()->devicePixelRatio()); - QRegion xArea = dpr == 1 ? area : QTransform::fromScale(dpr,dpr).map(area); m_image->preparePaint(area); - QPoint delta(dx * dpr, dy * dpr); - const QVector<QRect> xRects = xArea.rects(); - for (int i = 0; i < xRects.size(); ++i) - qt_scrollRectInImage(*m_image->image(), xRects.at(i), delta); + QPoint delta(dx, dy); + const QVector<QRect> rects = area.rects(); + for (int i = 0; i < rects.size(); ++i) + qt_scrollRectInImage(*m_image->image(), rects.at(i), delta); return true; } diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 78282d1415edd47c5a422d4d34a096aee28bdfb7..1fe46ff29024e4020c9d607dddb2c89157d47886 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -454,6 +454,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra , has_xkb(false) , m_buttons(0) , m_focusWindow(0) + , m_clientLeader(0) , m_systemTrayTracker(0) , m_glIntegration(Q_NULLPTR) , m_xiGrab(false) @@ -532,9 +533,14 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra QStringList glIntegrationNames; glIntegrationNames << QStringLiteral("xcb_glx") << QStringLiteral("xcb_egl"); QString glIntegrationName = QString::fromLocal8Bit(qgetenv("QT_XCB_GL_INTEGRATION")); - if (glIntegrationName.size()) { - glIntegrationNames.removeAll(glIntegrationName); - glIntegrationNames.prepend(glIntegrationName); + if (!glIntegrationName.isEmpty()) { + qCDebug(QT_XCB_GLINTEGRATION) << "QT_XCB_GL_INTEGRATION is set to" << glIntegrationName; + if (glIntegrationName != QStringLiteral("none")) { + glIntegrationNames.removeAll(glIntegrationName); + glIntegrationNames.prepend(glIntegrationName); + } else { + glIntegrationNames.clear(); + } } qCDebug(QT_XCB_GLINTEGRATION) << "Choosing xcb gl-integration based on following priority\n" << glIntegrationNames; @@ -1331,6 +1337,58 @@ xcb_window_t QXcbConnection::rootWindow() return s ? s->root() : 0; } +xcb_window_t QXcbConnection::clientLeader() +{ + if (m_clientLeader == 0) { + m_clientLeader = xcb_generate_id(xcb_connection()); + QXcbScreen *screen = primaryScreen(); + Q_XCB_CALL(xcb_create_window(xcb_connection(), + XCB_COPY_FROM_PARENT, + m_clientLeader, + screen->root(), + 0, 0, 1, 1, + 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + screen->screen()->root_visual, + 0, 0)); +#ifndef QT_NO_DEBUG + QByteArray ba("Qt client leader window"); + Q_XCB_CALL(xcb_change_property(xcb_connection(), + XCB_PROP_MODE_REPLACE, + m_clientLeader, + atom(QXcbAtom::_NET_WM_NAME), + atom(QXcbAtom::UTF8_STRING), + 8, + ba.length(), + ba.constData())); +#endif + Q_XCB_CALL(xcb_change_property(xcb_connection(), + XCB_PROP_MODE_REPLACE, + m_clientLeader, + atom(QXcbAtom::WM_CLIENT_LEADER), + XCB_ATOM_WINDOW, + 32, + 1, + &m_clientLeader)); + +#if !defined(QT_NO_SESSIONMANAGER) && defined(XCB_USE_SM) + // If we are session managed, inform the window manager about it + QByteArray session = qGuiApp->sessionId().toLatin1(); + if (!session.isEmpty()) { + Q_XCB_CALL(xcb_change_property(xcb_connection(), + XCB_PROP_MODE_REPLACE, + m_clientLeader, + atom(QXcbAtom::SM_CLIENT_ID), + XCB_ATOM_STRING, + 8, + session.length(), + session.constData())); + } +#endif + } + return m_clientLeader; +} + #ifdef XCB_USE_XLIB void *QXcbConnection::xlib_display() const { @@ -1573,6 +1631,7 @@ static const char * xcb_atomnames = { "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE\0" "_KDE_NET_WM_FRAME_STRUT\0" + "_NET_FRAME_EXTENTS\0" "_NET_STARTUP_INFO\0" "_NET_STARTUP_INFO_BEGIN\0" diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 0191b0e1efe72b5f0ac2b680f379d2f3769f0e64..7016b994253b377c2aedfa1badbdcbc41f36d8ba 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -194,6 +194,7 @@ namespace QXcbAtom { _KDE_NET_WM_WINDOW_TYPE_OVERRIDE, _KDE_NET_WM_FRAME_STRUT, + _NET_FRAME_EXTENTS, _NET_STARTUP_INFO, _NET_STARTUP_INFO_BEGIN, @@ -402,6 +403,7 @@ public: QXcbWMSupport *wmSupport() const { return m_wmSupport.data(); } xcb_window_t rootWindow(); + xcb_window_t clientLeader(); bool hasDefaultVisualId() const { return m_defaultVisualId != UINT_MAX; } xcb_visualid_t defaultVisualId() const { return m_defaultVisualId; } @@ -609,7 +611,6 @@ private: #endif QXcbEventReader *m_reader; #if defined(XCB_USE_XINPUT2) - QHash<int, QWindowSystemInterface::TouchPoint> m_touchPoints; QHash<int, XInput2TouchDeviceData*> m_touchDevices; #endif #ifdef Q_XCB_DEBUG @@ -642,6 +643,7 @@ private: QXcbWindow *m_focusWindow; + xcb_window_t m_clientLeader; QByteArray m_startupId; QXcbSystemTrayTracker *m_systemTrayTracker; QXcbGlIntegration *m_glIntegration; diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index c7784ddb48dd7da4a45bbb92d045ef2f1bf09273..4a347a370673f30ce9f9ffcedf23146963826366 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -52,6 +52,7 @@ struct XInput2TouchDeviceData { } XIDeviceInfo *xiDeviceInfo; QTouchDevice *qtTouchDevice; + QHash<int, QWindowSystemInterface::TouchPoint> touchPoints; // Stuff that is relevant only for touchpads QHash<int, QPointF> pointPressedPosition; // in screen coordinates where each point was pressed @@ -525,7 +526,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) case XI_ButtonPress: case XI_ButtonRelease: case XI_Motion: - if (xi2MouseEvents() && eventListener) + if (xi2MouseEvents() && eventListener && !(xiDeviceEvent->flags & XIPointerEmulated)) eventListener->handleXIMouseEvent(event); break; @@ -552,19 +553,19 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo xXIDeviceEvent *xiDeviceEvent = static_cast<xXIDeviceEvent *>(xiDevEvent); XInput2TouchDeviceData *dev = touchDeviceForId(xiDeviceEvent->sourceid); Q_ASSERT(dev); - const bool firstTouch = m_touchPoints.isEmpty(); + const bool firstTouch = dev->touchPoints.isEmpty(); if (xiDeviceEvent->evtype == XI_TouchBegin) { QWindowSystemInterface::TouchPoint tp; tp.id = xiDeviceEvent->detail % INT_MAX; tp.state = Qt::TouchPointPressed; tp.pressure = -1.0; - m_touchPoints[tp.id] = tp; + dev->touchPoints[tp.id] = tp; } - QWindowSystemInterface::TouchPoint &touchPoint = m_touchPoints[xiDeviceEvent->detail]; + QWindowSystemInterface::TouchPoint &touchPoint = dev->touchPoints[xiDeviceEvent->detail]; + QXcbScreen* screen = platformWindow->xcbScreen(); qreal x = fixed1616ToReal(xiDeviceEvent->root_x); qreal y = fixed1616ToReal(xiDeviceEvent->root_y); qreal nx = -1.0, ny = -1.0, d = 0.0; - QXcbScreen* screen = m_screens.at(0); for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) { XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i]; if (classinfo->type == XIValuatorClass) { @@ -677,10 +678,10 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) qCDebug(lcQpaXInput) << " touchpoint " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition << " area " << touchPoint.area << " pressure " << touchPoint.pressure; - QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiDeviceEvent->time, dev->qtTouchDevice, m_touchPoints.values()); + QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiDeviceEvent->time, dev->qtTouchDevice, dev->touchPoints.values()); if (touchPoint.state == Qt::TouchPointReleased) // If a touchpoint was released, we can forget it, because the ID won't be reused. - m_touchPoints.remove(touchPoint.id); + dev->touchPoints.remove(touchPoint.id); else // Make sure that we don't send TouchPointPressed/Moved in more than one QTouchEvent // with this touch point if the next XI2 event is about a different touch point. @@ -870,9 +871,8 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin } } if (!angleDelta.isNull()) { - const int dpr = int(platformWindow->devicePixelRatio()); - QPoint local(fixed1616ToReal(xiDeviceEvent->event_x)/dpr, fixed1616ToReal(xiDeviceEvent->event_y)/dpr); - QPoint global(fixed1616ToReal(xiDeviceEvent->root_x)/dpr, fixed1616ToReal(xiDeviceEvent->root_y)/dpr); + QPoint local(fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y)); + QPoint global(fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y)); Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective_mods); if (modifiers & Qt::AltModifier) { std::swap(angleDelta.rx(), angleDelta.ry()); @@ -898,9 +898,8 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin angleDelta.setX(-120); } if (!angleDelta.isNull()) { - const int dpr = int(platformWindow->devicePixelRatio()); - QPoint local(fixed1616ToReal(xiDeviceEvent->event_x)/dpr, fixed1616ToReal(xiDeviceEvent->event_y)/dpr); - QPoint global(fixed1616ToReal(xiDeviceEvent->root_x)/dpr, fixed1616ToReal(xiDeviceEvent->root_y)/dpr); + QPoint local(fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y)); + QPoint global(fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y)); Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective_mods); if (modifiers & Qt::AltModifier) std::swap(angleDelta.rx(), angleDelta.ry()); diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index e51ab85e30bd48bde7329da8df16abdcfaf50537..6c95de6806e792f9d3923ac28e3c076380d1e20f 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -52,7 +52,7 @@ typedef char *(*PtrXcursorLibraryGetTheme)(void *); typedef int (*PtrXcursorLibrarySetTheme)(void *, const char *); typedef int (*PtrXcursorLibraryGetDefaultSize)(void *); -#ifdef XCB_USE_XLIB +#if defined(XCB_USE_XLIB) && !defined(QT_NO_LIBRARY) #include <X11/Xlib.h> enum { XCursorShape = CursorShape @@ -300,7 +300,7 @@ QXcbCursor::QXcbCursor(QXcbConnection *conn, QXcbScreen *screen) const char *cursorStr = "cursor"; xcb_open_font(xcb_connection(), cursorFont, strlen(cursorStr), cursorStr); -#ifdef XCB_USE_XLIB +#if defined(XCB_USE_XLIB) && !defined(QT_NO_LIBRARY) static bool function_ptrs_not_initialized = true; if (function_ptrs_not_initialized) { QLibrary xcursorLib(QLatin1String("Xcursor"), 1); @@ -489,7 +489,7 @@ xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape) return cursor; } -#ifdef XCB_USE_XLIB +#if defined(XCB_USE_XLIB) && !defined(QT_NO_LIBRARY) bool updateCursorTheme(void *dpy, const QByteArray &theme) { if (!ptrXcursorLibraryGetTheme || !ptrXcursorLibrarySetTheme) @@ -533,7 +533,7 @@ static xcb_cursor_t loadCursor(void *dpy, int cshape) } return cursor; } -#endif //XCB_USE_XLIB +#endif //XCB_USE_XLIB / QT_NO_LIBRARY xcb_cursor_t QXcbCursor::createFontCursor(int cshape) { @@ -542,7 +542,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) xcb_cursor_t cursor = XCB_NONE; // Try Xcursor first -#ifdef XCB_USE_XLIB +#if defined(XCB_USE_XLIB) && !defined(QT_NO_LIBRARY) if (cshape >= 0 && cshape <= Qt::LastCursor) { void *dpy = connection()->xlib_display(); // special case for non-standard dnd-* cursors @@ -635,15 +635,14 @@ QPoint QXcbCursor::pos() const { QPoint p; queryPointer(connection(), 0, &p); - return m_screen->mapFromNative(p); + return p; } void QXcbCursor::setPos(const QPoint &pos) { - const QPoint xPos = m_screen->mapToNative(pos); xcb_window_t root = 0; queryPointer(connection(), &root, 0); - xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, xPos.x(), xPos.y()); + xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, pos.x(), pos.y()); xcb_flush(xcb_connection()); } diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h index 7e5cdc6870fe1c6e9248fd0e3abac1fbc91021f6..f4f6e61706df5415af98c687869933557f5c8c7e 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.h +++ b/src/plugins/platforms/xcb/qxcbcursor.h @@ -90,7 +90,7 @@ private: #ifndef QT_NO_CURSOR CursorHash m_cursorHash; #endif -#ifdef XCB_USE_XLIB +#if defined(XCB_USE_XLIB) && !defined(QT_NO_LIBRARY) static void cursorThemePropertyChanged(QXcbVirtualDesktop *screen, const QByteArray &name, const QVariant &property, diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 1d13adf851118fb62c020dc64b5b3de89c8415eb..a3e646ed7a79914b1f12041e7c180e9b460a3c9e 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -51,6 +51,7 @@ #include <private/qshapedpixmapdndwindow_p.h> #include <private/qsimpledrag_p.h> +#include <private/qhighdpiscaling_p.h> QT_BEGIN_NAMESPACE @@ -71,12 +72,16 @@ QT_BEGIN_NAMESPACE const int xdnd_version = 5; +static inline xcb_window_t xcb_window(QPlatformWindow *w) +{ + return static_cast<QXcbWindow *>(w)->xcb_window(); +} + static inline xcb_window_t xcb_window(QWindow *w) { return static_cast<QXcbWindow *>(w->handle())->xcb_window(); } - static xcb_window_t xdndProxy(QXcbConnection *c, xcb_window_t w) { xcb_window_t proxy = XCB_NONE; @@ -297,15 +302,8 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md return 0; } -void QXcbDrag::move(const QMouseEvent *me) +void QXcbDrag::move(const QPoint &globalPos) { - // The mouse event is in the coordinate system of the window that started the drag. - // We do not know which window that was at this point, so we just use the device pixel ratio - // of the QGuiApplication. This will break once we support screens with different DPR. Fixing - // this properly requires some redesign of the drag and drop architecture. - static const int dpr = int(qApp->devicePixelRatio()); - QBasicDrag::move(me); - QPoint globalPos = me->globalPos(); if (source_sameanswer.contains(globalPos) && source_sameanswer.isValid()) return; @@ -318,6 +316,9 @@ void QXcbDrag::move(const QMouseEvent *me) break; } } + + QBasicDrag::moveShapedPixmapWindow(QHighDpiScaling::mapPositionFromNative(globalPos, screen)); + if (screen != current_screen) { // ### need to recreate the shaped pixmap window? // int screen = QCursor::x11Screen(); @@ -340,7 +341,7 @@ void QXcbDrag::move(const QMouseEvent *me) // qt_xdnd_current_screen = screen; xcb_window_t rootwin = current_screen->root(); xcb_translate_coordinates_reply_t *translate = - ::translateCoordinates(connection(), rootwin, rootwin, globalPos.x() * dpr, globalPos.y() * dpr); + ::translateCoordinates(connection(), rootwin, rootwin, globalPos.x(), globalPos.y()); if (!translate) return; @@ -443,7 +444,7 @@ void QXcbDrag::move(const QMouseEvent *me) DEBUG() << "sending Xdnd enter source=" << enter.data.data32[0]; if (w) - handleEnter(w->window(), &enter); + handleEnter(w, &enter); else if (target) xcb_send_event(xcb_connection(), false, proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&enter); waiting_for_status = false; @@ -463,7 +464,7 @@ void QXcbDrag::move(const QMouseEvent *me) move.type = atom(QXcbAtom::XdndPosition); move.data.data32[0] = connection()->clipboard()->owner(); move.data.data32[1] = 0; // flags - move.data.data32[2] = (globalPos.x() * dpr << 16) + globalPos.y() * dpr; + move.data.data32[2] = (globalPos.x() << 16) + globalPos.y(); move.data.data32[3] = connection()->time(); move.data.data32[4] = toXdndAction(defaultAction(currentDrag()->supportedActions(), QGuiApplication::keyboardModifiers())); DEBUG() << "sending Xdnd position source=" << move.data.data32[0] << "target=" << move.window; @@ -471,15 +472,15 @@ void QXcbDrag::move(const QMouseEvent *me) source_time = connection()->time(); if (w) - handle_xdnd_position(w->window(), &move); + handle_xdnd_position(w, &move); else xcb_send_event(xcb_connection(), false, proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&move); } } -void QXcbDrag::drop(const QMouseEvent *event) +void QXcbDrag::drop(const QPoint &globalPos) { - QBasicDrag::drop(event); + QBasicDrag::drop(globalPos); if (!current_target) return; @@ -505,7 +506,7 @@ void QXcbDrag::drop(const QMouseEvent *event) connection()->time(), current_target, current_proxy_target, - (w ? w->window() : 0), + w, // current_embeddig_widget, currentDrag(), QTime::currentTime() @@ -518,7 +519,7 @@ void QXcbDrag::drop(const QMouseEvent *event) } if (w) { - handleDrop(w->window(), &drop); + handleDrop(w, &drop); } else { xcb_send_event(xcb_connection(), false, current_proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&drop); } @@ -664,7 +665,7 @@ static bool checkEmbedded(QWidget* w, const XEvent* xe) #endif -void QXcbDrag::handleEnter(QWindow *window, const xcb_client_message_event_t *event) +void QXcbDrag::handleEnter(QPlatformWindow *window, const xcb_client_message_event_t *event) { Q_UNUSED(window); DEBUG() << "handleEnter" << window; @@ -689,6 +690,7 @@ void QXcbDrag::handleEnter(QWindow *window, const xcb_client_message_event_t *ev length = xdnd_max_type; xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply); + xdnd_types.reserve(length); for (int i = 0; i < length; ++i) xdnd_types.append(atoms[i]); } @@ -704,17 +706,14 @@ void QXcbDrag::handleEnter(QWindow *window, const xcb_client_message_event_t *ev DEBUG() << " " << connection()->atomName(xdnd_types.at(i)); } -void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t *e) +void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message_event_t *e) { QPoint p((e->data.data32[2] & 0xffff0000) >> 16, e->data.data32[2] & 0x0000ffff); Q_ASSERT(w); QRect geometry = w->geometry(); - const int dpr = int(w->handle()->devicePixelRatio()); - - p /= dpr; p -= geometry.topLeft(); - if (!w || (w->type() == Qt::Desktop)) + if (!w || !w->window() || (w->window()->type() == Qt::Desktop)) return; if (e->data.data32[0] != xdnd_dragsource) { @@ -723,7 +722,7 @@ void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t } currentPosition = p; - currentWindow = w; + currentWindow = w->window(); // timestamp from the source if (e->data.data32[3] != XCB_NONE) { @@ -740,7 +739,7 @@ void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t supported_actions = Qt::DropActions(toDropAction(e->data.data32[4])); } - QPlatformDragQtResponse qt_response = QWindowSystemInterface::handleDrag(w,dropData,p,supported_actions); + QPlatformDragQtResponse qt_response = QWindowSystemInterface::handleDrag(w->window(),dropData,p,supported_actions); QRect answerRect(p + geometry.topLeft(), QSize(1,1)); answerRect = qt_response.answerRect().translated(geometry.topLeft()).intersected(geometry); @@ -796,7 +795,7 @@ namespace }; } -void QXcbDrag::handlePosition(QWindow * w, const xcb_client_message_event_t *event) +void QXcbDrag::handlePosition(QPlatformWindow * w, const xcb_client_message_event_t *event) { xcb_client_message_event_t *lastEvent = const_cast<xcb_client_message_event_t *>(event); xcb_generic_event_t *nextEvent; @@ -830,12 +829,10 @@ void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event) updateCursor(Qt::IgnoreAction); } - static const int dpr = int(qApp->devicePixelRatio()); - if ((event->data.data32[1] & 2) == 0) { QPoint p((event->data.data32[2] & 0xffff0000) >> 16, event->data.data32[2] & 0x0000ffff); QSize s((event->data.data32[3] & 0xffff0000) >> 16, event->data.data32[3] & 0x0000ffff); - source_sameanswer = QRect(p / dpr, s / dpr); + source_sameanswer = QRect(p, s); } else { source_sameanswer = QRect(); } @@ -861,10 +858,10 @@ void QXcbDrag::handleStatus(const xcb_client_message_event_t *event) DEBUG("xdndHandleStatus end"); } -void QXcbDrag::handleLeave(QWindow *w, const xcb_client_message_event_t *event) +void QXcbDrag::handleLeave(QPlatformWindow *w, const xcb_client_message_event_t *event) { DEBUG("xdnd leave"); - if (!currentWindow || w != currentWindow.data()) + if (!currentWindow || w != currentWindow.data()->handle()) return; // sanity // ### @@ -879,7 +876,7 @@ void QXcbDrag::handleLeave(QWindow *w, const xcb_client_message_event_t *event) DEBUG("xdnd drag leave from unexpected source (%x not %x", event->data.data32[0], xdnd_dragsource); } - QWindowSystemInterface::handleDrag(w,0,QPoint(),Qt::IgnoreAction); + QWindowSystemInterface::handleDrag(w->window(),0,QPoint(),Qt::IgnoreAction); xdnd_dragsource = 0; xdnd_types.clear(); @@ -909,7 +906,7 @@ void QXcbDrag::send_leave() w = 0; if (w) - handleLeave(w->window(), (const xcb_client_message_event_t *)&leave); + handleLeave(w, (const xcb_client_message_event_t *)&leave); else xcb_send_event(xcb_connection(), false,current_proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&leave); @@ -920,7 +917,7 @@ void QXcbDrag::send_leave() waiting_for_status = false; } -void QXcbDrag::handleDrop(QWindow *, const xcb_client_message_event_t *event) +void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *event) { DEBUG("xdndHandleDrop"); if (!currentWindow) { diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h index 95da76b732f1b881a1eddfef0531820ae1fdc86a..699d402ea6138c6b649377c5aa923d937228664c 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.h +++ b/src/plugins/platforms/xcb/qxcbdrag.h @@ -53,8 +53,8 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_DRAGANDDROP -class QMouseEvent; class QWindow; +class QPlatformWindow; class QXcbConnection; class QXcbWindow; class QXcbDropData; @@ -72,14 +72,14 @@ public: void startDrag() Q_DECL_OVERRIDE; void cancel() Q_DECL_OVERRIDE; - void move(const QMouseEvent *me) Q_DECL_OVERRIDE; - void drop(const QMouseEvent *me) Q_DECL_OVERRIDE; + void move(const QPoint &globalPos) Q_DECL_OVERRIDE; + void drop(const QPoint &globalPos) Q_DECL_OVERRIDE; void endDrag() Q_DECL_OVERRIDE; - void handleEnter(QWindow *window, const xcb_client_message_event_t *event); - void handlePosition(QWindow *w, const xcb_client_message_event_t *event); - void handleLeave(QWindow *w, const xcb_client_message_event_t *event); - void handleDrop(QWindow *, const xcb_client_message_event_t *event); + void handleEnter(QPlatformWindow *window, const xcb_client_message_event_t *event); + void handlePosition(QPlatformWindow *w, const xcb_client_message_event_t *event); + void handleLeave(QPlatformWindow *w, const xcb_client_message_event_t *event); + void handleDrop(QPlatformWindow *, const xcb_client_message_event_t *event); void handleStatus(const xcb_client_message_event_t *event); void handleSelectionRequest(const xcb_selection_request_event_t *event); @@ -99,7 +99,7 @@ private: void init(); - void handle_xdnd_position(QWindow *w, const xcb_client_message_event_t *event); + void handle_xdnd_position(QPlatformWindow *w, const xcb_client_message_event_t *event); void handle_xdnd_status(const xcb_client_message_event_t *event); void send_leave(); @@ -146,7 +146,7 @@ private: xcb_timestamp_t timestamp; xcb_window_t target; xcb_window_t proxy_target; - QWindow *targetWindow; + QPlatformWindow *targetWindow; // QWidget *embedding_widget; QPointer<QDrag> drag; QTime time; diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index f3bffd2998331ebe188aa87131d6efe69b034c0f..2e088d3ca51dfff7fcf41f476b4f8db7c8f40543 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -1473,8 +1473,6 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, } QString string = lookupString(xkb_state, code); - int count = string.size(); - string.truncate(count); // Ιf control modifier is set we should prefer latin character, this is // used for standard shortcuts in checks like "key == QKeySequence::Copy", @@ -1506,7 +1504,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, bool filtered = false; if (inputContext) { - QKeyEvent event(type, qtcode, modifiers, code, sym, state, string, isAutoRepeat, count); + QKeyEvent event(type, qtcode, modifiers, code, sym, state, string, isAutoRepeat, string.length()); event.setTimestamp(time); filtered = inputContext->filterEvent(&event); } @@ -1535,7 +1533,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, } if (!filtered && inputContext) { - QKeyEvent event(QEvent::KeyPress, qtcode, modifiers, code, sym, state, string, isAutoRepeat, count); + QKeyEvent event(QEvent::KeyPress, qtcode, modifiers, code, sym, state, string, isAutoRepeat, string.length()); event.setTimestamp(time); filtered = inputContext->filterEvent(&event); } diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index c14ec0bb3f7bea50b129bf857011359d0a149055..29262b5847513c544aae1d0b24430435536dc937 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -44,6 +44,7 @@ #include <qpa/qwindowsysteminterface.h> #include <private/qmath_p.h> +#include <QtGui/private/qhighdpiscaling_p.h> QT_BEGIN_NAMESPACE @@ -86,7 +87,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe , m_orientation(Qt::PrimaryOrientation) , m_refreshRate(60) , m_forcedDpi(-1) - , m_devicePixelRatio(1) + , m_pixelDensity(1) , m_hintStyle(QFontEngine::HintStyle(-1)) , m_noFontHinting(false) , m_subpixelType(QFontEngine::SubpixelAntialiasingType(-1)) @@ -107,9 +108,8 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe updateGeometry(output ? output->timestamp : 0); } - const int dpr = int(devicePixelRatio()); if (m_geometry.isEmpty()) { - m_geometry = QRect(QPoint(), m_virtualSize/dpr); + m_geometry = QRect(QPoint(), m_virtualSize); m_nativeGeometry = QRect(QPoint(), m_virtualSize); } if (m_availableGeometry.isEmpty()) @@ -117,12 +117,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe readXResources(); - // disable font hinting when we do UI scaling - static bool dpr_scaling_enabled = (qgetenv("QT_DEVICE_PIXEL_RATIO").toInt() > 1 - || qgetenv("QT_DEVICE_PIXEL_RATIO").toLower() == "auto"); - if (dpr_scaling_enabled) - m_noFontHinting = true; - QScopedPointer<xcb_get_window_attributes_reply_t, QScopedPointerPodDeleter> rootAttribs( xcb_get_window_attributes_reply(xcb_connection(), xcb_get_window_attributes_unchecked(xcb_connection(), screen()->root), NULL)); @@ -170,38 +164,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe else m_syncRequestSupported = true; - m_clientLeader = xcb_generate_id(xcb_connection()); - Q_XCB_CALL2(xcb_create_window(xcb_connection(), - XCB_COPY_FROM_PARENT, - m_clientLeader, - screen()->root, - 0, 0, 1, 1, - 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - screen()->root_visual, - 0, 0), connection); -#ifndef QT_NO_DEBUG - QByteArray ba("Qt client leader window for screen "); - ba += m_outputName.toUtf8(); - Q_XCB_CALL2(xcb_change_property(xcb_connection(), - XCB_PROP_MODE_REPLACE, - m_clientLeader, - atom(QXcbAtom::_NET_WM_NAME), - atom(QXcbAtom::UTF8_STRING), - 8, - ba.length(), - ba.constData()), connection); -#endif - - Q_XCB_CALL2(xcb_change_property(xcb_connection(), - XCB_PROP_MODE_REPLACE, - m_clientLeader, - atom(QXcbAtom::WM_CLIENT_LEADER), - XCB_ATOM_WINDOW, - 32, - 1, - &m_clientLeader), connection); - xcb_depth_iterator_t depth_iterator = xcb_screen_allowed_depths_iterator(screen()); @@ -233,9 +195,8 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const { xcb_window_t root = screen()->root; - int dpr = int(devicePixelRatio()); - int x = p.x() / dpr; - int y = p.y() / dpr; + int x = p.x(); + int y = p.y(); xcb_window_t parent = root; xcb_window_t child = root; @@ -269,31 +230,6 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const return 0; } - -QPoint QXcbScreen::mapToNative(const QPoint &pos) const -{ - const int dpr = int(devicePixelRatio()); - return (pos - m_geometry.topLeft()) * dpr + m_nativeGeometry.topLeft(); -} - -QPoint QXcbScreen::mapFromNative(const QPoint &pos) const -{ - const int dpr = int(devicePixelRatio()); - return (pos - m_nativeGeometry.topLeft()) / dpr + m_geometry.topLeft(); -} - -QRect QXcbScreen::mapToNative(const QRect &rect) const -{ - const int dpr = int(devicePixelRatio()); - return QRect(mapToNative(rect.topLeft()), rect.size() * dpr); -} - -QRect QXcbScreen::mapFromNative(const QRect &rect) const -{ - const int dpr = int(devicePixelRatio()); - return QRect(mapFromNative(rect.topLeft()), rect.size() / dpr); -} - void QXcbScreen::windowShown(QXcbWindow *window) { // Freedesktop.org Startup Notification @@ -355,6 +291,7 @@ QDpi QXcbScreen::virtualDpi() const Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height()); } + QDpi QXcbScreen::logicalDpi() const { static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI"); @@ -362,22 +299,14 @@ QDpi QXcbScreen::logicalDpi() const return QDpi(overrideDpi, overrideDpi); if (m_forcedDpi > 0) { - int primaryDpr = int(connection()->screens().at(0)->devicePixelRatio()); - return QDpi(m_forcedDpi/primaryDpr, m_forcedDpi/primaryDpr); + return QDpi(m_forcedDpi, m_forcedDpi); } return virtualDpi(); } - -qreal QXcbScreen::devicePixelRatio() const +qreal QXcbScreen::pixelDensity() const { - static int override_dpr = qEnvironmentVariableIntValue("QT_DEVICE_PIXEL_RATIO"); - static bool auto_dpr = qgetenv("QT_DEVICE_PIXEL_RATIO").toLower() == "auto"; - if (override_dpr > 0) - return override_dpr; - if (auto_dpr) - return m_devicePixelRatio; - return 1.0; + return m_pixelDensity; } QPlatformCursor *QXcbScreen::cursor() const @@ -536,11 +465,10 @@ void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation) free(workArea); qreal dpi = xGeometry.width() / physicalSize().width() * qreal(25.4); - m_devicePixelRatio = qRound(dpi/96); - const int dpr = int(devicePixelRatio()); // we may override m_devicePixelRatio - m_geometry = QRect(xGeometry.topLeft(), xGeometry.size()/dpr); + m_pixelDensity = qRound(dpi/96); + m_geometry = QRect(xGeometry.topLeft(), xGeometry.size()); m_nativeGeometry = QRect(xGeometry.topLeft(), xGeometry.size()); - m_availableGeometry = QRect(mapFromNative(xAvailableGeometry.topLeft()), xAvailableGeometry.size()/dpr); + m_availableGeometry = QRect(xAvailableGeometry.topLeft(), xAvailableGeometry.size()); QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry); } diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index ec05e3bb25c90ffb9c16e86c6e9a778b5569823d..cbb6307d6ec52f701fd3e7fe0392e5db4c82dbd0 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -96,7 +96,7 @@ public: QSizeF physicalVirtualSize() const { return m_virtualSizeMillimeters; } QDpi virtualDpi() const; QDpi logicalDpi() const Q_DECL_OVERRIDE; - qreal devicePixelRatio() const Q_DECL_OVERRIDE; + qreal pixelDensity() const Q_DECL_OVERRIDE; QPlatformCursor *cursor() const Q_DECL_OVERRIDE; qreal refreshRate() const Q_DECL_OVERRIDE { return m_refreshRate; } Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE { return m_orientation; } @@ -116,8 +116,6 @@ public: xcb_randr_crtc_t crtc() const { return m_crtc; } xcb_randr_mode_t mode() const { return m_mode; } - xcb_window_t clientLeader() const { return m_clientLeader; } - void windowShown(QXcbWindow *window); QString windowManagerName() const { return m_windowManagerName; } bool syncRequestSupported() const { return m_syncRequestSupported; } @@ -141,11 +139,6 @@ public: QXcbXSettings *xSettings() const; - QPoint mapToNative(const QPoint &pos) const; - QPoint mapFromNative(const QPoint &pos) const; - QRect mapToNative(const QRect &rect) const; - QRect mapFromNative(const QRect &rect) const; - private: static bool xResource(const QByteArray &identifier, const QByteArray &expectedIdentifier, @@ -171,13 +164,12 @@ private: Qt::ScreenOrientation m_orientation; QString m_windowManagerName; bool m_syncRequestSupported; - xcb_window_t m_clientLeader; QMap<xcb_visualid_t, xcb_visualtype_t> m_visuals; QMap<xcb_visualid_t, quint8> m_visualDepths; QXcbCursor *m_cursor; int m_refreshRate; int m_forcedDpi; - int m_devicePixelRatio; + int m_pixelDensity; QFontEngine::HintStyle m_hintStyle; bool m_noFontHinting; QFontEngine::SubpixelAntialiasingType m_subpixelType; diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp index 328b72234a90b464b68c360ed65ab28c9b2882e5..c2101a71c13d35f83ff0c7d248fd2915b49aa06b 100644 --- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp +++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp @@ -134,6 +134,7 @@ static void sm_setProperty(const QString &name, const QStringList &value) SmPropValue *prop = new SmPropValue[value.count()]; int count = 0; QList<QByteArray> vl; + vl.reserve(value.size()); for (QStringList::ConstIterator it = value.begin(); it != value.end(); ++it) { prop[count].length = (*it).length(); vl.append((*it).toUtf8()); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index d2da1375918e782ef0663fc8b25252d7d9fc5e16..f9a85cdf44ca895a81a0459951c415792440207b 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -37,6 +37,7 @@ #include <QScreen> #include <QtGui/QIcon> #include <QtGui/QRegion> +#include <QtGui/private/qhighdpiscaling_p.h> #include "qxcbintegration.h" #include "qxcbconnection.h" @@ -140,73 +141,11 @@ enum QX11EmbedMessageType { const quint32 XEMBED_VERSION = 0; -static inline QRect mapLocalGeometryToNative(const QRect &qtRect, int dpr) -{ - return QRect(qtRect.x() * dpr, qtRect.y() * dpr, qtRect.width() * dpr, qtRect.height() * dpr); -} - -// When mapping expose events to Qt rects: round top/left towards the origin and -// bottom/right away from the origin, making sure that we cover the whole widget - -static inline QPoint dpr_floor(const QPoint &p, int dpr) -{ - return QPoint(p.x()/dpr, p.y()/dpr); -} - -static inline QPoint dpr_ceil(const QPoint &p, int dpr) -{ - return QPoint((p.x() + dpr - 1) / dpr, (p.y() + dpr - 1) / dpr); -} - -static inline QSize dpr_ceil(const QSize &s, int dpr) -{ - return QSize((s.width() + dpr - 1) / dpr, (s.height() + dpr - 1) / dpr); -} - -static inline QRect mapExposeFromNative(const QRect &xRect, int dpr) -{ - return QRect(dpr_floor(xRect.topLeft(), dpr), dpr_ceil(xRect.bottomRight(), dpr)); -} - -static inline QRect mapLocalGeometryFromNative(const QRect &xRect, int dpr) -{ - return QRect(xRect.topLeft() / dpr, dpr_ceil(xRect.size(), dpr)); -} - QXcbScreen *QXcbWindow::parentScreen() { return parent() ? static_cast<QXcbWindow*>(parent())->parentScreen() : m_xcbScreen; } -QPoint QXcbWindow::mapToNative(const QPoint &pos, const QXcbScreen *screen) const -{ - if (parent()) - return pos * int(screen->devicePixelRatio()); - else - return screen->mapToNative(pos); -} -QPoint QXcbWindow::mapFromNative(const QPoint &pos, const QXcbScreen *screen) const -{ - if (parent()) - return pos / int(screen->devicePixelRatio()); - else - return screen->mapFromNative(pos); -} -QRect QXcbWindow::mapToNative(const QRect &rect, const QXcbScreen *screen) const -{ - if (parent()) - return mapLocalGeometryToNative(rect, int(screen->devicePixelRatio())); - else - return screen->mapToNative(rect); -} -QRect QXcbWindow::mapFromNative(const QRect &rect, const QXcbScreen *screen) const -{ - if (parent()) - return mapLocalGeometryFromNative(rect, int(screen->devicePixelRatio())); - else - return screen->mapFromNative(rect); -} - // Returns \c true if we should set WM_TRANSIENT_FOR on \a w static inline bool isTransient(const QWindow *w) { @@ -382,7 +321,7 @@ void QXcbWindow::create() Qt::WindowType type = window()->type(); QXcbScreen *currentScreen = xcbScreen(); - QRect rect = window()->geometry(); + QRect rect = windowGeometry(); QXcbScreen *platformScreen = parent() ? parentScreen() : static_cast<QXcbScreen*>(screenForGeometry(rect)); m_xcbScreen = platformScreen; @@ -425,17 +364,15 @@ void QXcbWindow::create() if (platformScreen != currentScreen) QWindowSystemInterface::handleWindowScreenChanged(window(), platformScreen->QPlatformScreen::screen()); - const int dpr = int(devicePixelRatio()); - - QSize minimumSize = window()->minimumSize(); + const QSize minimumSize = windowMinimumSize(); if (rect.width() > 0 || rect.height() > 0) { - rect.setWidth(qBound(1, rect.width(), XCOORD_MAX/dpr)); - rect.setHeight(qBound(1, rect.height(), XCOORD_MAX/dpr)); + rect.setWidth(qBound(1, rect.width(), XCOORD_MAX)); + rect.setHeight(qBound(1, rect.height(), XCOORD_MAX)); } else if (minimumSize.width() > 0 || minimumSize.height() > 0) { rect.setSize(minimumSize); } else { - rect.setWidth(defaultWindowWidth); - rect.setHeight(defaultWindowHeight); + rect.setWidth(QHighDpi::toNativePixels(int(defaultWindowWidth), platformScreen->QPlatformScreen::screen())); + rect.setHeight(QHighDpi::toNativePixels(int(defaultWindowHeight), platformScreen->QPlatformScreen::screen())); } xcb_window_t xcb_parent_id = platformScreen->root(); @@ -479,9 +416,7 @@ void QXcbWindow::create() m_visualId = visualInfo->visualid; - const QRect xRect = mapToNative(rect, platformScreen); - - m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, xRect.x(), xRect.y(), xRect.width(), xRect.height(), + m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, rect.x(), rect.y(), rect.width(), rect.height(), 0, visualInfo->depth, InputOutput, visualInfo->visual, CWBackPixel|CWBorderPixel|CWColormap, &a); @@ -537,16 +472,14 @@ void QXcbWindow::create() } m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap); - const QRect xRect = mapToNative(rect, platformScreen); - Q_XCB_CALL(xcb_create_window(xcb_connection(), m_depth, m_window, // window id xcb_parent_id, // parent window id - xRect.x(), - xRect.y(), - xRect.width(), - xRect.height(), + rect.x(), + rect.y(), + rect.width(), + rect.height(), 0, // border width XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class m_visualId, // visual @@ -623,7 +556,7 @@ void QXcbWindow::create() xcb_set_wm_hints(xcb_connection(), m_window, &hints); - xcb_window_t leader = platformScreen->clientLeader(); + xcb_window_t leader = connection()->clientLeader(); Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, atom(QXcbAtom::WM_CLIENT_LEADER), XCB_ATOM_WINDOW, 32, 1, &leader)); @@ -709,15 +642,14 @@ void QXcbWindow::setGeometry(const QRect &rect) propagateSizeHints(); - QXcbScreen *currentScreen = xcbScreen(); + QXcbScreen *currentScreen = m_xcbScreen; QXcbScreen *newScreen = parent() ? parentScreen() : static_cast<QXcbScreen*>(screenForGeometry(rect)); if (!newScreen) - newScreen = currentScreen; + newScreen = xcbScreen(); m_xcbScreen = newScreen; - const QRect xRect = mapToNative(rect, newScreen); - const QRect wmGeometry = windowToWmGeometry(xRect); + const QRect wmGeometry = windowToWmGeometry(rect); if (newScreen != currentScreen) QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); @@ -746,6 +678,22 @@ void QXcbWindow::setGeometry(const QRect &rect) QMargins QXcbWindow::frameMargins() const { if (m_dirtyFrameMargins) { + if (connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::_NET_FRAME_EXTENTS))) { + xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, m_window, + atom(QXcbAtom::_NET_FRAME_EXTENTS), XCB_ATOM_CARDINAL, 0, 4); + QScopedPointer<xcb_get_property_reply_t, QScopedPointerPodDeleter> reply( + xcb_get_property_reply(xcb_connection(), cookie, NULL)); + if (reply && reply->type == XCB_ATOM_CARDINAL && reply->format == 32 && reply->value_len == 4) { + quint32 *data = (quint32 *)xcb_get_property_value(reply.data()); + // _NET_FRAME_EXTENTS format is left, right, top, bottom + m_frameMargins = QMargins(data[0], data[2], data[1], data[3]); + m_dirtyFrameMargins = false; + return m_frameMargins; + } + } + + // _NET_FRAME_EXTENTS property is not available, so + // walk up the window tree to get the frame parent xcb_window_t window = m_window; xcb_window_t parent = m_window; @@ -859,7 +807,7 @@ void QXcbWindow::show() // Default to client leader if there is no transient parent, else modal dialogs can // be hidden by their parents. if (!transientXcbParent) - transientXcbParent = xcbScreen()->clientLeader(); + transientXcbParent = connection()->clientLeader(); if (transientXcbParent) { // ICCCM 4.1.2.6 Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32, @@ -874,11 +822,6 @@ void QXcbWindow::show() updateNetWmStateBeforeMap(); } - if (window()->metaObject()->indexOfProperty(wm_window_type_property_id) >= 0) { - QXcbWindowFunctions::WmWindowTypes wmWindowTypes(window()->property(wm_window_type_property_id).value<int>()); - setWmWindowType(wmWindowTypes); - } - if (connection()->time() != XCB_TIME_CURRENT_TIME) updateNetWmUserTime(connection()->time()); @@ -1141,7 +1084,13 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags) xcb_change_window_attributes(xcb_connection(), xcb_window(), mask, values); - setNetWmWindowFlags(flags); + QXcbWindowFunctions::WmWindowTypes wmWindowTypes = 0; + if (window()->dynamicPropertyNames().contains(wm_window_type_property_id)) { + wmWindowTypes = static_cast<QXcbWindowFunctions::WmWindowTypes>( + window()->property(wm_window_type_property_id).value<int>()); + } + + setWmWindowType(wmWindowTypes, flags); setMotifWindowFlags(flags); setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput); @@ -1292,42 +1241,6 @@ void QXcbWindow::setWindowState(Qt::WindowState state) m_windowState = state; } -void QXcbWindow::setNetWmWindowFlags(Qt::WindowFlags flags) -{ - // in order of decreasing priority - QVector<uint> windowTypes; - - Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask)); - - switch (type) { - case Qt::Dialog: - case Qt::Sheet: - windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DIALOG)); - break; - case Qt::Tool: - case Qt::Drawer: - windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_UTILITY)); - break; - case Qt::ToolTip: - windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP)); - break; - case Qt::SplashScreen: - windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_SPLASH)); - break; - default: - break; - } - - if (flags & Qt::FramelessWindowHint) - windowTypes.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE)); - - windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL)); - - Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, - atom(QXcbAtom::_NET_WM_WINDOW_TYPE), XCB_ATOM_ATOM, 32, - windowTypes.count(), windowTypes.constData())); -} - void QXcbWindow::updateMotifWmHintsBeforeMap() { QtMotifWmHints mwmhints = getMotifWmHints(connection(), m_window); @@ -1348,7 +1261,7 @@ void QXcbWindow::updateMotifWmHintsBeforeMap() mwmhints.flags &= ~MWM_HINTS_INPUT_MODE; } - if (window()->minimumSize() == window()->maximumSize()) { + if (windowMinimumSize() == windowMaximumSize()) { // fixed size, remove the resize handle (since mwm/dtwm // isn't smart enough to do it itself) mwmhints.flags |= MWM_HINTS_FUNCTIONS; @@ -1634,8 +1547,7 @@ void QXcbWindow::propagateSizeHints() xcb_size_hints_t hints; memset(&hints, 0, sizeof(hints)); - const int dpr = int(devicePixelRatio()); - const QRect xRect = windowToWmGeometry(mapToNative(geometry(), xcbScreen())); + const QRect xRect = windowToWmGeometry(geometry()); QWindow *win = window(); @@ -1645,10 +1557,10 @@ void QXcbWindow::propagateSizeHints() xcb_size_hints_set_size(&hints, true, xRect.width(), xRect.height()); xcb_size_hints_set_win_gravity(&hints, m_gravity); - QSize minimumSize = win->minimumSize() * dpr; - QSize maximumSize = win->maximumSize() * dpr; - QSize baseSize = win->baseSize() * dpr; - QSize sizeIncrement = win->sizeIncrement() * dpr; + QSize minimumSize = windowMinimumSize(); + QSize maximumSize = windowMaximumSize(); + QSize baseSize = windowBaseSize(); + QSize sizeIncrement = windowSizeIncrement(); if (minimumSize.width() > 0 || minimumSize.height() > 0) xcb_size_hints_set_min_size(&hints, @@ -1716,10 +1628,10 @@ QSurfaceFormat QXcbWindow::format() const void QXcbWindow::setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowTypes) { + window->setProperty(wm_window_type_property_id, QVariant::fromValue(static_cast<int>(windowTypes))); + if (window->handle()) - static_cast<QXcbWindow *>(window->handle())->setWmWindowType(windowTypes); - else - window->setProperty(wm_window_type_property_id, QVariant::fromValue(static_cast<int>(windowTypes))); + static_cast<QXcbWindow *>(window->handle())->setWmWindowType(windowTypes, window->flags()); } void QXcbWindow::setWindowIconTextStatic(QWindow *window, const QString &text) @@ -1806,40 +1718,82 @@ QXcbWindowFunctions::WmWindowTypes QXcbWindow::wmWindowTypes() const return result; } -void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types) +void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::WindowFlags flags) { QVector<xcb_atom_t> atoms; + // manual selection 1 (these are never set by Qt and take precedence) if (types & QXcbWindowFunctions::Normal) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL)); if (types & QXcbWindowFunctions::Desktop) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DESKTOP)); if (types & QXcbWindowFunctions::Dock) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DOCK)); - if (types & QXcbWindowFunctions::Toolbar) - atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLBAR)); - if (types & QXcbWindowFunctions::Menu) - atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_MENU)); + if (types & QXcbWindowFunctions::Notification) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NOTIFICATION)); + + // manual selection 2 (Qt uses these during auto selection); if (types & QXcbWindowFunctions::Utility) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_UTILITY)); if (types & QXcbWindowFunctions::Splash) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_SPLASH)); if (types & QXcbWindowFunctions::Dialog) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DIALOG)); + if (types & QXcbWindowFunctions::Tooltip) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP)); + if (types & QXcbWindowFunctions::KdeOverride) + atoms.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE)); + + // manual selection 3 (these can be set by Qt, but don't have a + // corresponding Qt::WindowType). note that order of the *MENU + // atoms is important + if (types & QXcbWindowFunctions::Menu) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_MENU)); if (types & QXcbWindowFunctions::DropDownMenu) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)); if (types & QXcbWindowFunctions::PopupMenu) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_POPUP_MENU)); - if (types & QXcbWindowFunctions::Tooltip) - atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP)); - if (types & QXcbWindowFunctions::Notification) - atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NOTIFICATION)); + if (types & QXcbWindowFunctions::Toolbar) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLBAR)); if (types & QXcbWindowFunctions::Combo) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_COMBO)); if (types & QXcbWindowFunctions::Dnd) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DND)); - if (types & QXcbWindowFunctions::KdeOverride) + + // automatic selection + Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask)); + switch (type) { + case Qt::Dialog: + case Qt::Sheet: + if (!(types & QXcbWindowFunctions::Dialog)) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DIALOG)); + break; + case Qt::Tool: + case Qt::Drawer: + if (!(types & QXcbWindowFunctions::Utility)) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_UTILITY)); + break; + case Qt::ToolTip: + if (!(types & QXcbWindowFunctions::Tooltip)) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP)); + break; + case Qt::SplashScreen: + if (!(types & QXcbWindowFunctions::Splash)) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_SPLASH)); + break; + default: + break; + } + + if ((flags & Qt::FramelessWindowHint) && !(type & QXcbWindowFunctions::KdeOverride)) { + // override netwm type - quick and easy for KDE noborder atoms.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE)); + } + + if (atoms.size() == 1 && atoms.first() == atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL)) + atoms.clear(); + else + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL)); if (atoms.isEmpty()) { Q_XCB_CALL(xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_WINDOW_TYPE))); @@ -1896,10 +1850,9 @@ QRect QXcbWindow::systemTrayWindowGlobalGeometry() const class ExposeCompressor { public: - ExposeCompressor(xcb_window_t window, QRegion *region, int devicePixelRatio) + ExposeCompressor(xcb_window_t window, QRegion *region) : m_window(window) , m_region(region) - , m_dpr(devicePixelRatio) , m_pending(true) { } @@ -1915,7 +1868,7 @@ public: return false; if (expose->count == 0) m_pending = false; - *m_region |= mapExposeFromNative(QRect(expose->x, expose->y, expose->width, expose->height), m_dpr); + *m_region |= QRect(expose->x, expose->y, expose->width, expose->height); return true; } @@ -1927,7 +1880,6 @@ public: private: xcb_window_t m_window; QRegion *m_region; - int m_dpr; bool m_pending; }; @@ -1941,16 +1893,14 @@ bool QXcbWindow::handleGenericEvent(xcb_generic_event_t *event, long *result) void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event) { - const int dpr = int(devicePixelRatio()); - QRect x_rect(event->x, event->y, event->width, event->height); - QRect rect = mapExposeFromNative(x_rect, dpr); + QRect rect(event->x, event->y, event->width, event->height); if (m_exposeRegion.isEmpty()) m_exposeRegion = rect; else m_exposeRegion |= rect; - ExposeCompressor compressor(m_window, &m_exposeRegion, dpr); + ExposeCompressor compressor(m_window, &m_exposeRegion); xcb_generic_event_t *filter = 0; do { filter = connection()->checkEvent(compressor); @@ -2002,13 +1952,13 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even } #ifndef QT_NO_DRAGANDDROP } else if (event->type == atom(QXcbAtom::XdndEnter)) { - connection()->drag()->handleEnter(window(), event); + connection()->drag()->handleEnter(this, event); } else if (event->type == atom(QXcbAtom::XdndPosition)) { - connection()->drag()->handlePosition(window(), event); + connection()->drag()->handlePosition(this, event); } else if (event->type == atom(QXcbAtom::XdndLeave)) { - connection()->drag()->handleLeave(window(), event); + connection()->drag()->handleLeave(this, event); } else if (event->type == atom(QXcbAtom::XdndDrop)) { - connection()->drag()->handleDrop(window(), event); + connection()->drag()->handleDrop(this, event); #endif } else if (event->type == atom(QXcbAtom::_XEMBED)) { handleXEmbedMessage(event); @@ -2028,26 +1978,6 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even } } -// Temporary workaround for bug in QPlatformScreen::screenForGeometry -// we need the native geometries to detect our screen, but that's not -// available in cross-platform code. Will be fixed properly when highDPI -// support is refactored to expose the native coordinate system. - -QXcbScreen *QXcbWindow::screenForNativeGeometry(const QRect &newGeometry) const -{ - QXcbScreen *currentScreen = xcbScreen(); - if (!currentScreen && QGuiApplication::primaryScreen()) - currentScreen = static_cast<QXcbScreen*>(QGuiApplication::primaryScreen()->handle()); - if (currentScreen && !parent() && !currentScreen->nativeGeometry().intersects(newGeometry)) { - Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) { - QXcbScreen *xcbScreen = static_cast<QXcbScreen*>(screen); - if (xcbScreen->nativeGeometry().intersects(newGeometry)) - return xcbScreen; - } - } - return currentScreen; -} - void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event) { bool fromSendEvent = (event->response_type & 0x80); @@ -2064,19 +1994,18 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * } } - const QRect nativeRect = QRect(pos, QSize(event->width, event->height)); - QXcbScreen *newScreen = parent() ? parentScreen() : screenForNativeGeometry(nativeRect); + const QRect rect = QRect(pos, QSize(event->width, event->height)); + QPlatformScreen *newScreen = parent() ? parent()->screen() : screenForGeometry(rect); QXcbScreen *currentScreen = m_xcbScreen; - m_xcbScreen = newScreen; + m_xcbScreen = static_cast<QXcbScreen*>(newScreen); if (!newScreen) return; - const QRect rect = mapFromNative(nativeRect, newScreen); QPlatformWindow::setGeometry(rect); QWindowSystemInterface::handleGeometryChange(window(), rect); if (newScreen != currentScreen) - QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); + QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); m_configureNotifyPending = false; @@ -2109,11 +2038,10 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const if (!m_embedded) return pos; - const int dpr = int(devicePixelRatio()); QPoint ret; xcb_translate_coordinates_cookie_t cookie = xcb_translate_coordinates(xcb_connection(), xcb_window(), xcbScreen()->root(), - pos.x() * dpr, pos.y() * dpr); + pos.x(), pos.y()); xcb_translate_coordinates_reply_t *reply = xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL); if (reply) { @@ -2122,7 +2050,7 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const free(reply); } - return mapFromNative(ret, xcbScreen()); + return ret; } QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const @@ -2130,17 +2058,15 @@ QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const if (!m_embedded) return pos; - const int dpr = int(devicePixelRatio()); QPoint ret; - QPoint xPos = mapToNative(pos, xcbScreen()); xcb_translate_coordinates_cookie_t cookie = xcb_translate_coordinates(xcb_connection(), xcbScreen()->root(), xcb_window(), - xPos.x(), xPos.y()); + pos.x(), pos.y()); xcb_translate_coordinates_reply_t *reply = xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL); if (reply) { - ret.setX(reply->dst_x / dpr); - ret.setY(reply->dst_y / dpr); + ret.setX(reply->dst_x); + ret.setY(reply->dst_y); free(reply); } @@ -2156,7 +2082,7 @@ void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event) if (m_configureNotifyPending) m_deferredExpose = true; else - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size() * int(devicePixelRatio()))); + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); } } @@ -2188,9 +2114,8 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in sendXEmbedMessage(container->xcb_window(), XEMBED_REQUEST_FOCUS); } } - const int dpr = int(devicePixelRatio()); - QPoint local(event_x / dpr, event_y / dpr); - QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y)); + QPoint local(event_x, event_y); + QPoint global(root_x, root_y); if (isWheel) { if (!connection()->isAtLeastXI21()) { @@ -2212,9 +2137,8 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y, int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) { - const int dpr = int(devicePixelRatio()); - QPoint local(event_x / dpr, event_y / dpr); - QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y)); + QPoint local(event_x, event_y); + QPoint global(root_x, root_y); if (detail >= 4 && detail <= 7) { // mouse wheel, handled in handleButtonPressEvent() @@ -2227,11 +2151,8 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) { - if (!xcbScreen()) - return; - const int dpr = int(devicePixelRatio()); - QPoint local(event_x / dpr, event_y / dpr); - QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y)); + QPoint local(event_x, event_y); + QPoint global(root_x, root_y); handleMouseEvent(timestamp, local, global, modifiers); } @@ -2359,11 +2280,10 @@ void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event) if (ignoreEnterEvent(event)) return; - const int dpr = int(devicePixelRatio()); - const QPoint local(event->event_x/dpr, event->event_y/dpr); + const QPoint local(event->event_x, event->event_y); if (!xcbScreen()) return; - QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); + QPoint global = QPoint(event->root_x, event->root_y); QWindowSystemInterface::handleEnterEvent(window(), local, global); } @@ -2379,11 +2299,10 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event) QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : 0; if (enterWindow) { - const int dpr = int(devicePixelRatio()); - QPoint local(enter->event_x/dpr, enter->event_y/dpr); + QPoint local(enter->event_x, enter->event_y); if (!xcbScreen()) return; - QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); + QPoint global = QPoint(event->root_x, event->root_y); QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global); } else { @@ -2439,6 +2358,8 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev m_windowState = newState; } return; + } else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) { + m_dirtyFrameMargins = true; } else if (event->atom == atom(QXcbAtom::_NET_WORKAREA) && xcbScreen() && event->window == xcbScreen()->root()) { xcbScreen()->updateGeometry(event->time); } @@ -2560,7 +2481,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) xev.type = moveResize; xev.window = xcb_window(); xev.format = 32; - const QPoint globalPos = mapToNative(window()->mapToGlobal(pos), xcbScreen()); + const QPoint globalPos = window()->mapToGlobal(pos); xev.data.data32[0] = globalPos.x(); xev.data.data32[1] = globalPos.y(); const bool bottom = corner == Qt::BottomRightCorner || corner == Qt::BottomLeftCorner; @@ -2686,10 +2607,11 @@ void QXcbWindow::setMask(const QRegion ®ion) xcb_shape_mask(connection()->xcb_connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, xcb_window(), 0, 0, XCB_NONE); } else { - const int dpr = devicePixelRatio(); QVector<xcb_rectangle_t> rects; - foreach (const QRect &r, region.rects()) - rects.push_back(qRectToXCBRectangle(mapLocalGeometryToNative(r, dpr))); + const QVector<QRect> regionRects = region.rects(); + rects.reserve(regionRects.count()); + foreach (const QRect &r, regionRects) + rects.push_back(qRectToXCBRectangle(r)); xcb_shape_rectangles(connection()->xcb_connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, xcb_window(), 0, 0, rects.size(), &rects[0]); @@ -2727,11 +2649,6 @@ void QXcbWindow::postSyncWindowRequest() } } -qreal QXcbWindow::devicePixelRatio() const -{ - return xcbScreen() ? xcbScreen()->devicePixelRatio() : 1.0; -} - QXcbScreen *QXcbWindow::xcbScreen() const { return static_cast<QXcbScreen *>(screen()); diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 07019223c864c48168fed5eabd52b2a08f201c5d..8968664badd2dd7e06b04c3c366d630f0f316d2a 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -144,7 +144,7 @@ public: static uint visualIdStatic(QWindow *window); QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const; - void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types); + void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::WindowFlags flags); static void setWindowIconTextStatic(QWindow *window, const QString &text); @@ -163,8 +163,6 @@ public: void postSyncWindowRequest(); void clearSyncWindowRequest() { m_pendingSyncRequest = 0; } - qreal devicePixelRatio() const Q_DECL_OVERRIDE; - QXcbScreen *xcbScreen() const; virtual void create(); @@ -180,17 +178,12 @@ protected: virtual void *createVisual() { return Q_NULLPTR; } virtual bool supportsSyncProtocol() { return !window()->supportsOpenGL(); } - QPoint mapToNative(const QPoint &pos, const QXcbScreen *screen) const; - QPoint mapFromNative(const QPoint &pos, const QXcbScreen *screen) const; - QRect mapToNative(const QRect &rect, const QXcbScreen *screen) const; - QRect mapFromNative(const QRect &rect, const QXcbScreen *screen) const; QXcbScreen *parentScreen(); void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0); NetWmStates netWmStates(); void setNetWmStates(NetWmStates); - void setNetWmWindowFlags(Qt::WindowFlags flags); void setMotifWindowFlags(Qt::WindowFlags flags); void updateMotifWmHintsBeforeMap(); diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 9fc6b78644623d5ba683a7bb21714c11a90feba8..2dbd1ace7198e422ddf86e0c453ae1072bd8fe74 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -1,8 +1,15 @@ TEMPLATE = subdirs +load(qfeatures) SUBDIRS *= sqldrivers -!nacl:!winrt:qtHaveModule(network): SUBDIRS += bearer -qtHaveModule(gui): SUBDIRS *= imageformats platforms platforminputcontexts platformthemes generic +!nacl:!winrt:qtHaveModule(network):!contains(QT_DISABLED_FEATURES, bearermanagement): SUBDIRS += bearer +qtHaveModule(gui) { + SUBDIRS *= platforms platforminputcontexts platformthemes + !contains(QT_DISABLED_FEATURES, imageformatplugin): SUBDIRS *= imageformats + !contains(QT_DISABLED_FEATURES, library): SUBDIRS *= generic +} qtHaveModule(widgets): SUBDIRS *= styles -!winrt:!wince*:qtHaveModule(widgets):SUBDIRS += printsupport +!winrt:!wince*:qtHaveModule(widgets):!contains(QT_DISABLED_FEATURES, printer) { + SUBDIRS += printsupport +} diff --git a/src/plugins/printsupport/cocoa/main.cpp b/src/plugins/printsupport/cocoa/main.cpp index 2037724719e60a2200f197749cfc9ba9baf2aed6..3db7b49ba4ca75b1ca0b4620ac439049dd23a7da 100644 --- a/src/plugins/printsupport/cocoa/main.cpp +++ b/src/plugins/printsupport/cocoa/main.cpp @@ -38,8 +38,6 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_PRINTER - class QCocoaPrinterSupportPlugin : public QPlatformPrinterSupportPlugin { Q_OBJECT @@ -67,8 +65,6 @@ QPlatformPrinterSupport *QCocoaPrinterSupportPlugin::create(const QString &key) return platformPrinterSupport; } -#endif - QT_END_NAMESPACE #include "main.moc" diff --git a/src/plugins/printsupport/cups/main.cpp b/src/plugins/printsupport/cups/main.cpp index 82485114ab24e3111c7f55ea12eb67ec237ee8eb..abd24d411ae33ed18e422c4f765aaf6485573a6c 100644 --- a/src/plugins/printsupport/cups/main.cpp +++ b/src/plugins/printsupport/cups/main.cpp @@ -37,8 +37,6 @@ #include <qpa/qplatformprintplugin.h> #include <QtCore/QStringList> -#ifndef QT_NO_PRINTER - QT_BEGIN_NAMESPACE class QCupsPrinterSupportPlugin : public QPlatformPrinterSupportPlugin @@ -65,6 +63,4 @@ QPlatformPrinterSupport *QCupsPrinterSupportPlugin::create(const QString &key) QT_END_NAMESPACE -#endif // QT_NO_PRINTER - #include "main.moc" diff --git a/src/plugins/printsupport/cups/qcupsprintengine.cpp b/src/plugins/printsupport/cups/qcupsprintengine.cpp index c00d7f302cceac268cfe3792d82771d98c722fee..7ca81986b4185fdb231a1e7ab1d1c00875a05d1c 100644 --- a/src/plugins/printsupport/cups/qcupsprintengine.cpp +++ b/src/plugins/printsupport/cups/qcupsprintengine.cpp @@ -33,8 +33,6 @@ #include "qcupsprintengine_p.h" -#ifndef QT_NO_PRINTER - #include <qpa/qplatformprintplugin.h> #include <qpa/qplatformprintersupport.h> @@ -226,7 +224,9 @@ void QCupsPrintEnginePrivate::closePrintDevice() it += 2; } - for (int c = 0; c < options.size(); ++c) { + const int numOptions = options.size(); + cupsOptStruct.reserve(numOptions); + for (int c = 0; c < numOptions; ++c) { cups_option_t opt; opt.name = options[c].first.data(); opt.value = options[c].second.data(); @@ -315,5 +315,3 @@ void QCupsPrintEnginePrivate::setPageSize(const QPageSize &pageSize) } QT_END_NAMESPACE - -#endif // QT_NO_PRINTER diff --git a/src/plugins/printsupport/cups/qcupsprintengine_p.h b/src/plugins/printsupport/cups/qcupsprintengine_p.h index b589d40b6ca3e166e7cdf9522db93a652ff3b020..a611740e0909930628afe4259e77094bd5692a22 100644 --- a/src/plugins/printsupport/cups/qcupsprintengine_p.h +++ b/src/plugins/printsupport/cups/qcupsprintengine_p.h @@ -47,8 +47,6 @@ #include "QtPrintSupport/qprintengine.h" -#ifndef QT_NO_PRINTER - #include <QtCore/qstring.h> #include <QtGui/qpaintengine.h> @@ -100,6 +98,4 @@ private: QT_END_NAMESPACE -#endif // QT_NO_PRINTER - #endif // QCUPSPRINTENGINE_P_H diff --git a/src/plugins/printsupport/cups/qcupsprintersupport.cpp b/src/plugins/printsupport/cups/qcupsprintersupport.cpp index ea7c116e3c360e3db9fbd3ce0a41b0df0e132a71..b257918acf7f2ef1cfe4f1580218863691c1d3da 100644 --- a/src/plugins/printsupport/cups/qcupsprintersupport.cpp +++ b/src/plugins/printsupport/cups/qcupsprintersupport.cpp @@ -34,8 +34,6 @@ #include "qcupsprintersupport_p.h" -#ifndef QT_NO_PRINTER - #include "qcupsprintengine_p.h" #include "qppdprintdevice.h" #include <private/qprinterinfo_p.h> @@ -80,6 +78,7 @@ QStringList QCupsPrinterSupport::availablePrintDeviceIds() const QStringList list; cups_dest_t *dests; int count = cupsGetDests(&dests); + list.reserve(count); for (int i = 0; i < count; ++i) { QString printerId = QString::fromLocal8Bit(dests[i].name); if (dests[i].instance) @@ -109,5 +108,3 @@ QString QCupsPrinterSupport::defaultPrintDeviceId() const } QT_END_NAMESPACE - -#endif // QT_NO_PRINTER diff --git a/src/plugins/printsupport/cups/qcupsprintersupport_p.h b/src/plugins/printsupport/cups/qcupsprintersupport_p.h index ea913deeaa4a4c1affa6fb011906b3b39eb55b23..6dcaa4e8933b702b20f641112557ee06b67a0368 100644 --- a/src/plugins/printsupport/cups/qcupsprintersupport_p.h +++ b/src/plugins/printsupport/cups/qcupsprintersupport_p.h @@ -48,8 +48,6 @@ #include <qpa/qplatformprintersupport.h> -#ifndef QT_NO_PRINTER - #include <QtCore/qstringlist.h> QT_BEGIN_NAMESPACE @@ -73,5 +71,4 @@ private: QT_END_NAMESPACE -#endif // QT_NO_PRINTER #endif // QCUPSPRINTERSUPPORT_H diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp index 808424b1ed19a2e64809bf41c9ffc286c9fa028a..1b9ff98fca6f5eb9a90da96462d6cf858452641e 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.cpp +++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp @@ -42,8 +42,6 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_PRINTER - QPpdPrintDevice::QPpdPrintDevice() : QPlatformPrintDevice(), m_cupsDest(0), @@ -269,6 +267,7 @@ void QPpdPrintDevice::loadInputSlots() const if (m_ppd) { ppd_option_t *inputSlots = ppdFindOption(m_ppd, "InputSlot"); if (inputSlots) { + m_inputSlots.reserve(inputSlots->num_choices); for (int i = 0; i < inputSlots->num_choices; ++i) m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[i])); } @@ -309,6 +308,7 @@ void QPpdPrintDevice::loadOutputBins() const if (m_ppd) { ppd_option_t *outputBins = ppdFindOption(m_ppd, "OutputBin"); if (outputBins) { + m_outputBins.reserve(outputBins->num_choices); for (int i = 0; i < outputBins->num_choices; ++i) m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[i])); } @@ -350,6 +350,7 @@ void QPpdPrintDevice::loadDuplexModes() const if (m_ppd) { ppd_option_t *duplexModes = ppdFindOption(m_ppd, "Duplex"); if (duplexModes) { + m_duplexModes.reserve(duplexModes->num_choices); for (int i = 0; i < duplexModes->num_choices; ++i) m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[i].choice)); } @@ -472,6 +473,4 @@ cups_ptype_e QPpdPrintDevice::printerTypeFlags() const return static_cast<cups_ptype_e>(printerOption("printer-type").toUInt()); } -#endif // QT_NO_PRINTER - QT_END_NAMESPACE diff --git a/src/plugins/printsupport/cups/qppdprintdevice.h b/src/plugins/printsupport/cups/qppdprintdevice.h index 64eb872bd19fa7426fae68f51e3b7c928ec2d22c..a28348eb605be9122f71da95feaab2e831199223 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.h +++ b/src/plugins/printsupport/cups/qppdprintdevice.h @@ -47,8 +47,6 @@ #include <qpa/qplatformprintdevice.h> -#ifndef QT_NO_PRINTER - #include <QtCore/qbytearray.h> #include <QtCore/qhash.h> #include <QtCore/qmargins.h> @@ -111,5 +109,4 @@ private: QT_END_NAMESPACE -#endif // QT_NO_PRINTER #endif // QPPDPRINTDEVICE_H diff --git a/src/plugins/printsupport/printsupport.pro b/src/plugins/printsupport/printsupport.pro index ed201f07442117735d487da0cc325057cf9cb075..bd6681f53ccb7a74b97e4d3df11ec2093f2269f4 100644 --- a/src/plugins/printsupport/printsupport.pro +++ b/src/plugins/printsupport/printsupport.pro @@ -2,4 +2,7 @@ TEMPLATE = subdirs osx: SUBDIRS += cocoa win32: SUBDIRS += windows -unix:!mac:contains(QT_CONFIG, cups): SUBDIRS += cups +unix:!mac:contains(QT_CONFIG, cups) { + load(qfeatures) + !contains(QT_DISABLED_FEATURES, cups): SUBDIRS += cups +} diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp index 505f3138cac08d45d72effaa8d87931d5f68c099..d378ff313064cd5bcab5dba123d9a1d3409188fa 100644 --- a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp +++ b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp @@ -41,8 +41,6 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_PRINTER - QT_WARNING_DISABLE_GCC("-Wsign-compare") extern qreal qt_pointMultiplier(QPageLayout::Unit unit); @@ -471,6 +469,4 @@ QString QWindowsPrintDevice::defaultPrintDeviceId() return QString::fromWCharArray(name.data()); } -#endif // QT_NO_PRINTER - QT_END_NAMESPACE diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.h b/src/plugins/printsupport/windows/qwindowsprintdevice.h index 8ab487a59cc7b7ea2839c77133a4031a26bb364d..2c232d22c5ad23cd9881b113d3e04ad1ffd0b21a 100644 --- a/src/plugins/printsupport/windows/qwindowsprintdevice.h +++ b/src/plugins/printsupport/windows/qwindowsprintdevice.h @@ -47,8 +47,6 @@ #include <qpa/qplatformprintdevice.h> -#ifndef QT_NO_PRINTER - #include <QtCore/qt_windows.h> QT_BEGIN_NAMESPACE @@ -95,5 +93,4 @@ private: QT_END_NAMESPACE -#endif // QT_NO_PRINTER #endif // QWINDOWSPRINTDEVICE_H diff --git a/src/printsupport/dialogs/qabstractprintdialog.cpp b/src/printsupport/dialogs/qabstractprintdialog.cpp index 47350bebcb90c3fbc16047f1febdc4bb6e0b96cb..68027fdae8c4cdc49f8a327edfb181e0d8fd35fc 100644 --- a/src/printsupport/dialogs/qabstractprintdialog.cpp +++ b/src/printsupport/dialogs/qabstractprintdialog.cpp @@ -387,13 +387,13 @@ void QAbstractPrintDialogPrivate::setPrinter(QPrinter *newPrinter) settings for each available printer can be modified via the dialog's \uicontrol{Properties} push button. - On Windows and Mac OS X, the native print dialog is used, which means that + On Windows and OS X, the native print dialog is used, which means that some QWidget and QDialog properties set on the dialog won't be respected. - The native print dialog on Mac OS X does not support setting printer options, + The native print dialog on OS X does not support setting printer options, i.e. setOptions() and setOption() have no effect. In Qt 4.4, it was possible to use the static functions to show a sheet on - Mac OS X. This is no longer supported in Qt 4.5. If you want this + OS X. This is no longer supported in Qt 4.5. If you want this functionality, use QPrintDialog::open(). \sa QPageSetupDialog, QPrinter diff --git a/src/printsupport/dialogs/qabstractprintdialog.h b/src/printsupport/dialogs/qabstractprintdialog.h index cf55cfade8062f9d9eab0525531d131ec7857c35..6148502096a0b83636a96fa70f9a5e49853a45c0 100644 --- a/src/printsupport/dialogs/qabstractprintdialog.h +++ b/src/printsupport/dialogs/qabstractprintdialog.h @@ -74,7 +74,7 @@ public: Q_DECLARE_FLAGS(PrintDialogOptions, PrintDialogOption) #ifndef QT_NO_PRINTDIALOG - explicit QAbstractPrintDialog(QPrinter *printer, QWidget *parent = 0); + explicit QAbstractPrintDialog(QPrinter *printer, QWidget *parent = Q_NULLPTR); ~QAbstractPrintDialog(); virtual int exec() = 0; @@ -101,7 +101,7 @@ public: QPrinter *printer() const; protected: - QAbstractPrintDialog(QAbstractPrintDialogPrivate &ptr, QPrinter *printer, QWidget *parent = 0); + QAbstractPrintDialog(QAbstractPrintDialogPrivate &ptr, QPrinter *printer, QWidget *parent = Q_NULLPTR); private: Q_DISABLE_COPY(QAbstractPrintDialog) diff --git a/src/printsupport/dialogs/qpagesetupdialog.cpp b/src/printsupport/dialogs/qpagesetupdialog.cpp index 72d80885af2fac64e6f56682661725adfe7bbce4..425a8cd9d50067b59c1bfba1c4380eb5a64309f6 100644 --- a/src/printsupport/dialogs/qpagesetupdialog.cpp +++ b/src/printsupport/dialogs/qpagesetupdialog.cpp @@ -50,12 +50,12 @@ QT_BEGIN_NAMESPACE \ingroup printing \inmodule QtPrintSupport - On Windows and Mac OS X the page setup dialog is implemented using + On Windows and OS X the page setup dialog is implemented using the native page setup dialogs. - Note that on Windows and Mac OS X custom paper sizes won't be + Note that on Windows and OS X custom paper sizes won't be reflected in the native page setup dialogs. Additionally, custom - page margins set on a QPrinter won't show in the native Mac OS X + page margins set on a QPrinter won't show in the native OS X page setup dialog. \sa QPrinter, QPrintDialog diff --git a/src/printsupport/dialogs/qpagesetupdialog.h b/src/printsupport/dialogs/qpagesetupdialog.h index 56cd48ee94d6e8fee2b76e8529134cd34f16668e..824d63f2d70546fda9c524e328abfcbc00dd192b 100644 --- a/src/printsupport/dialogs/qpagesetupdialog.h +++ b/src/printsupport/dialogs/qpagesetupdialog.h @@ -51,14 +51,14 @@ class Q_PRINTSUPPORT_EXPORT QPageSetupDialog : public QDialog Q_DECLARE_PRIVATE(QPageSetupDialog) public: - explicit QPageSetupDialog(QPrinter *printer, QWidget *parent = 0); - explicit QPageSetupDialog(QWidget *parent = 0); - virtual ~QPageSetupDialog(); + explicit QPageSetupDialog(QPrinter *printer, QWidget *parent = Q_NULLPTR); + explicit QPageSetupDialog(QWidget *parent = Q_NULLPTR); + ~QPageSetupDialog(); #if defined(Q_OS_MAC) || defined(Q_OS_WIN) - virtual void setVisible(bool visible); + void setVisible(bool visible) Q_DECL_OVERRIDE; #endif - virtual int exec() Q_DECL_OVERRIDE; + int exec() Q_DECL_OVERRIDE; using QDialog::open; void open(QObject *receiver, const char *member); diff --git a/src/printsupport/dialogs/qprintdialog.h b/src/printsupport/dialogs/qprintdialog.h index 1332fcc1fd38e0d3ea48e1d9e264daf74b078e6b..cf0115cc281806084f328f6516f344cf268ddc1e 100644 --- a/src/printsupport/dialogs/qprintdialog.h +++ b/src/printsupport/dialogs/qprintdialog.h @@ -53,8 +53,8 @@ class Q_PRINTSUPPORT_EXPORT QPrintDialog : public QAbstractPrintDialog Q_PROPERTY(PrintDialogOptions options READ options WRITE setOptions) public: - explicit QPrintDialog(QPrinter *printer, QWidget *parent = 0); - explicit QPrintDialog(QWidget *parent = 0); + explicit QPrintDialog(QPrinter *printer, QWidget *parent = Q_NULLPTR); + explicit QPrintDialog(QWidget *parent = Q_NULLPTR); ~QPrintDialog(); int exec() Q_DECL_OVERRIDE; diff --git a/src/printsupport/dialogs/qprintpreviewdialog.h b/src/printsupport/dialogs/qprintpreviewdialog.h index 15e0271ba0d777c47d2f561a4a721a4e1a99ec20..228cd24f48ed906c9c977beab1f9032ff721043e 100644 --- a/src/printsupport/dialogs/qprintpreviewdialog.h +++ b/src/printsupport/dialogs/qprintpreviewdialog.h @@ -52,8 +52,9 @@ class Q_PRINTSUPPORT_EXPORT QPrintPreviewDialog : public QDialog Q_DECLARE_PRIVATE(QPrintPreviewDialog) public: - explicit QPrintPreviewDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0); - explicit QPrintPreviewDialog(QPrinter *printer, QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit QPrintPreviewDialog(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); + explicit QPrintPreviewDialog(QPrinter *printer, QWidget *parent = Q_NULLPTR, + Qt::WindowFlags flags = Qt::WindowFlags()); ~QPrintPreviewDialog(); using QDialog::open; diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp index 8c67b416a9c19333c666aae9881751af350ed126..2f0f1205caba38b06972d88360532b687bb356ba 100644 --- a/src/printsupport/kernel/qcups.cpp +++ b/src/printsupport/kernel/qcups.cpp @@ -59,6 +59,16 @@ void QCUPSSupport::setCupsOption(QStringList &cupsOptions, const QString &option } } +void QCUPSSupport::clearCupsOption(QStringList &cupsOptions, const QString &option) +{ + // ### use const_iterator once QList::erase takes them + const QStringList::iterator it = std::find(cupsOptions.begin(), cupsOptions.end(), option); + if (it != cupsOptions.end()) { + Q_ASSERT(it + 1 < cupsOptions.end()); + cupsOptions.erase(it, it+1); + } +} + static inline QString jobHoldToString(const QCUPSSupport::JobHoldUntil jobHold, const QTime holdUntilTime) { switch (jobHold) { @@ -94,14 +104,16 @@ static inline QString jobHoldToString(const QCUPSSupport::JobHoldUntil jobHold, void QCUPSSupport::setJobHold(QPrinter *printer, const JobHoldUntil jobHold, const QTime &holdUntilTime) { + QStringList cupsOptions = cupsOptionsList(printer); const QString jobHoldUntilArgument = jobHoldToString(jobHold, holdUntilTime); if (!jobHoldUntilArgument.isEmpty()) { - QStringList cupsOptions = cupsOptionsList(printer); setCupsOption(cupsOptions, QStringLiteral("job-hold-until"), jobHoldUntilArgument); - setCupsOptions(printer, cupsOptions); + } else { + clearCupsOption(cupsOptions, QStringLiteral("job-hold-until")); } + setCupsOptions(printer, cupsOptions); } void QCUPSSupport::setJobBilling(QPrinter *printer, const QString &jobBilling) diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h index afcb2c6f3b306deb05bf957024dc0e7247073c21..f6ba983e9f5d3f5ed089ffbf00370be495fdca62 100644 --- a/src/printsupport/kernel/qcups_p.h +++ b/src/printsupport/kernel/qcups_p.h @@ -117,6 +117,7 @@ public: static QStringList cupsOptionsList(QPrinter *printer); static void setCupsOptions(QPrinter *printer, const QStringList &cupsOptions); static void setCupsOption(QStringList &cupsOptions, const QString &option, const QString &value); + static void clearCupsOption(QStringList &cupsOptions, const QString &option); static void setJobHold(QPrinter *printer, const JobHoldUntil jobHold = NoHold, const QTime &holdUntilTime = QTime()); static void setJobBilling(QPrinter *printer, const QString &jobBilling = QString()); @@ -127,6 +128,11 @@ public: const PagesPerSheetLayout pagesPerSheetLayout); static void setPageRange(QPrinter *printer, int pageFrom, int pageTo); }; +Q_DECLARE_TYPEINFO(QCUPSSupport::JobHoldUntil, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(QCUPSSupport::BannerPage, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(QCUPSSupport::PageSet, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(QCUPSSupport::PagesPerSheetLayout, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(QCUPSSupport::PagesPerSheet, Q_PRIMITIVE_TYPE); QT_END_NAMESPACE diff --git a/src/printsupport/kernel/qpaintengine_alpha.cpp b/src/printsupport/kernel/qpaintengine_alpha.cpp index 010a628e4fbf96641a8f43244ca571ca4929532e..710691453aba74e2e4f9240eccb5aef2ca2d3b3a 100644 --- a/src/printsupport/kernel/qpaintengine_alpha.cpp +++ b/src/printsupport/kernel/qpaintengine_alpha.cpp @@ -178,7 +178,8 @@ void QAlphaPaintEngine::drawPolygon(const QPointF *points, int pointCount, Polyg Q_D(QAlphaPaintEngine); QPolygonF poly; - for (int i=0; i<pointCount; ++i) + poly.reserve(pointCount); + for (int i = 0; i < pointCount; ++i) poly.append(points[i]); QPainterPath path; diff --git a/src/printsupport/kernel/qplatformprintplugin.cpp b/src/printsupport/kernel/qplatformprintplugin.cpp index 091cc6f008fcb66dd520800761343c4eae87574e..9adf39ffcd9fb114aa0f9840a0e409e6ff5434f3 100644 --- a/src/printsupport/kernel/qplatformprintplugin.cpp +++ b/src/printsupport/kernel/qplatformprintplugin.cpp @@ -55,6 +55,7 @@ QPlatformPrinterSupportPlugin::~QPlatformPrinterSupportPlugin() static QPlatformPrinterSupport *printerSupport = 0; +#ifndef QT_NO_LIBRARY static void cleanupPrinterSupport() { #ifndef QT_NO_PRINTER @@ -62,6 +63,7 @@ static void cleanupPrinterSupport() #endif printerSupport = 0; } +#endif // !QT_NO_LIBRARY /*! \internal @@ -73,6 +75,7 @@ static void cleanupPrinterSupport() */ QPlatformPrinterSupport *QPlatformPrinterSupportPlugin::get() { +#ifndef QT_NO_LIBRARY if (!printerSupport) { const QMultiMap<int, QString> keyMap = loader()->keyMap(); if (!keyMap.isEmpty()) @@ -80,6 +83,7 @@ QPlatformPrinterSupport *QPlatformPrinterSupportPlugin::get() if (printerSupport) qAddPostRoutine(cleanupPrinterSupport); } +#endif // !QT_NO_LIBRARY return printerSupport; } diff --git a/src/printsupport/kernel/qprint_p.h b/src/printsupport/kernel/qprint_p.h index a097d26a9e3fbd1efd9f1fda31fae5f809ce799d..6a05cc15894c7512e1bec69bc21bb2e4fb360abd 100644 --- a/src/printsupport/kernel/qprint_p.h +++ b/src/printsupport/kernel/qprint_p.h @@ -245,7 +245,7 @@ public: // but where would it live? Not in base module as don't want to link to CUPS. // May have to have two copies in plugins to keep in sync. - static QPrint::InputSlot ppdChoiceToInputSlot(ppd_choice_t choice) + static QPrint::InputSlot ppdChoiceToInputSlot(const ppd_choice_t &choice) { QPrint::InputSlot input; input.key = choice.choice; @@ -255,7 +255,7 @@ public: return input; } - static QPrint::OutputBin ppdChoiceToOutputBin(ppd_choice_t choice) + static QPrint::OutputBin ppdChoiceToOutputBin(const ppd_choice_t &choice) { QPrint::OutputBin output; output.key = choice.choice; diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index a106a585026ad849ec357469199cb26894684942..4f8eaba85a6cb0fad78df14b5b46dc8b083057d2 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -160,7 +160,7 @@ void QPrinterPrivate::changeEngines(QPrinter::OutputFormat format, const QPrinte initEngines(format, printer); if (oldPrintEngine) { - foreach (QPrintEngine::PrintEnginePropertyKey key, m_properties.values()) { + foreach (QPrintEngine::PrintEnginePropertyKey key, m_properties) { QVariant prop; // PPK_NumberOfCopies need special treatmeant since it in most cases // will return 1, disregarding the actual value that was set @@ -311,7 +311,7 @@ public: features, such as orientation and resolution, and to step through the pages in a document as it is generated. - When printing directly to a printer on Windows or Mac OS X, QPrinter uses + When printing directly to a printer on Windows or OS X, QPrinter uses the built-in printer drivers. On X11, QPrinter uses the \l{Common Unix Printing System (CUPS)} to send PDF output to the printer. As an alternative, @@ -909,7 +909,7 @@ QString QPrinter::outputFileName() const QPrinter uses Qt's cross-platform PDF print engines respectively. If you can produce this format natively, for example - Mac OS X can generate PDF's from its print engine, set the output format + OS X can generate PDF's from its print engine, set the output format back to NativeFormat. \sa outputFileName(), setOutputFormat() @@ -1371,7 +1371,7 @@ QPrinter::ColorMode QPrinter::colorMode() const \obsolete Returns the number of copies to be printed. The default value is 1. - On Windows, Mac OS X and X11 systems that support CUPS, this will always + On Windows, OS X and X11 systems that support CUPS, this will always return 1 as these operating systems can internally handle the number of copies. @@ -1934,7 +1934,9 @@ QList<int> QPrinter::supportedResolutions() const QList<QVariant> varlist = d->printEngine->property(QPrintEngine::PPK_SupportedResolutions).toList(); QList<int> intlist; - for (int i=0; i<varlist.size(); ++i) + const int numSupportedResolutions = varlist.size(); + intlist.reserve(numSupportedResolutions); + for (int i = 0; i < numSupportedResolutions; ++i) intlist << varlist.at(i).toInt(); return intlist; } diff --git a/src/printsupport/kernel/qprinterinfo.cpp b/src/printsupport/kernel/qprinterinfo.cpp index ad488a10ed22436366c44bf6610aa3d57dc38ef4..1be574891b9375f87a54c116573f3182c611eda6 100644 --- a/src/printsupport/kernel/qprinterinfo.cpp +++ b/src/printsupport/kernel/qprinterinfo.cpp @@ -316,7 +316,9 @@ QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const { Q_D(const QPrinterInfo); QList<QPrinter::PaperSize> list; - foreach (const QPageSize &pageSize, d->m_printDevice.supportedPageSizes()) + const QList<QPageSize> supportedPageSizes = d->m_printDevice.supportedPageSizes(); + list.reserve(supportedPageSizes.size()); + foreach (const QPageSize &pageSize, supportedPageSizes) list.append(QPrinter::PaperSize(pageSize.id())); return list; } @@ -336,7 +338,9 @@ QList<QPair<QString, QSizeF> > QPrinterInfo::supportedSizesWithNames() const { Q_D(const QPrinterInfo); QList<QPair<QString, QSizeF> > list; - foreach (const QPageSize &pageSize, d->m_printDevice.supportedPageSizes()) + const QList<QPageSize> supportedPageSizes = d->m_printDevice.supportedPageSizes(); + list.reserve(supportedPageSizes.size()); + foreach (const QPageSize &pageSize, supportedPageSizes) list.append(qMakePair(pageSize.name(), pageSize.size(QPageSize::Millimeter))); return list; } @@ -376,7 +380,9 @@ QList<QPrinter::DuplexMode> QPrinterInfo::supportedDuplexModes() const { Q_D(const QPrinterInfo); QList<QPrinter::DuplexMode> list; - foreach (QPrint::DuplexMode mode, d->m_printDevice.supportedDuplexModes()) + const QList<QPrint::DuplexMode> supportedDuplexModes = d->m_printDevice.supportedDuplexModes(); + list.reserve(supportedDuplexModes.size()); + foreach (QPrint::DuplexMode mode, supportedDuplexModes) list << QPrinter::DuplexMode(mode); return list; } @@ -416,7 +422,9 @@ QList<QPrinterInfo> QPrinterInfo::availablePrinters() QList<QPrinterInfo> list; QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get(); if (ps) { - foreach (const QString &id, ps->availablePrintDeviceIds()) + const QStringList availablePrintDeviceIds = ps->availablePrintDeviceIds(); + list.reserve(availablePrintDeviceIds.size()); + foreach (const QString &id, availablePrintDeviceIds) list.append(QPrinterInfo(id)); } return list; diff --git a/src/printsupport/widgets/qcupsjobwidget.cpp b/src/printsupport/widgets/qcupsjobwidget.cpp index ce8b0d1ed347018c0672084daf8fe6d271f5a5c5..43ec37e1190c58e830bf71c2ba891b1815754d6f 100644 --- a/src/printsupport/widgets/qcupsjobwidget.cpp +++ b/src/printsupport/widgets/qcupsjobwidget.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_PRINTER +#if !defined(QT_NO_PRINTER) && !defined(QT_NO_CUPS) /*! \internal @@ -206,6 +206,6 @@ QCUPSSupport::BannerPage QCupsJobWidget::endBannerPage() const return m_ui.endBannerPageCombo->itemData(m_ui.endBannerPageCombo->currentIndex()).value<QCUPSSupport::BannerPage>(); } -#endif // QT_NO_PRINTER +#endif // QT_NO_PRINTER / QT_NO_CUPS QT_END_NAMESPACE diff --git a/src/printsupport/widgets/qcupsjobwidget_p.h b/src/printsupport/widgets/qcupsjobwidget_p.h index dfd2016130b8031c40baf64407b105ed934c6b28..65fea24d2aa162f9c20d6e60c6c38a8d9625cad8 100644 --- a/src/printsupport/widgets/qcupsjobwidget_p.h +++ b/src/printsupport/widgets/qcupsjobwidget_p.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_PRINTER +#if !defined(QT_NO_PRINTER) && !defined(QT_NO_CUPS) class QString; class QTime; @@ -100,7 +100,7 @@ private: Q_DISABLE_COPY(QCupsJobWidget) }; -#endif // QT_NO_PRINTER +#endif // QT_NO_PRINTER / QT_NO_CUPS QT_END_NAMESPACE diff --git a/src/printsupport/widgets/qprintpreviewwidget.h b/src/printsupport/widgets/qprintpreviewwidget.h index e88b421ca9e9dd365eae524b3e178c01340338a9..16b388d9360a928eff59edf8adec18c58e38c240 100644 --- a/src/printsupport/widgets/qprintpreviewwidget.h +++ b/src/printsupport/widgets/qprintpreviewwidget.h @@ -62,8 +62,9 @@ public: FitInView }; - explicit QPrintPreviewWidget(QPrinter *printer, QWidget *parent = 0, Qt::WindowFlags flags = 0); - explicit QPrintPreviewWidget(QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit QPrintPreviewWidget(QPrinter *printer, QWidget *parent = Q_NULLPTR, + Qt::WindowFlags flags = Qt::WindowFlags()); + explicit QPrintPreviewWidget(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); ~QPrintPreviewWidget(); qreal zoomFactor() const; diff --git a/src/sql/doc/snippets/code/src_sql_kernel_qsqldatabase.cpp b/src/sql/doc/snippets/code/src_sql_kernel_qsqldatabase.cpp index c3b3b8e817197bd85904387590981f820d658b7c..95422c9e7bdf98658f44e29ca7208534c93cb106 100644 --- a/src/sql/doc/snippets/code/src_sql_kernel_qsqldatabase.cpp +++ b/src/sql/doc/snippets/code/src_sql_kernel_qsqldatabase.cpp @@ -80,7 +80,7 @@ if (db.open()) { //! [4] ... // MySQL connection -db.setConnectOptions("CLIENT_SSL=1;CLIENT_IGNORE_SPACE=1"); // use an SSL connection to the server +db.setConnectOptions("SSL_KEY=client-key.pem;SSL_CERT=client-cert.pem;SSL_CA=ca-cert.pem;CLIENT_IGNORE_SPACE=1"); // use an SSL connection to the server if (!db.open()) { db.setConnectOptions(); // clears the connect option string ... diff --git a/src/sql/doc/src/sql-driver.qdoc b/src/sql/doc/src/sql-driver.qdoc index 43455b163ff14b10c23b17e5c0506acd459cae03..5c75505d3cc1bcd100c1eb4628ff0881f5629ef3 100644 --- a/src/sql/doc/src/sql-driver.qdoc +++ b/src/sql/doc/src/sql-driver.qdoc @@ -77,7 +77,7 @@ \target building \section1 Building the Drivers Using Configure - On Unix and Mac OS X, the Qt \c configure script tries to + On Unix and OS X, the Qt \c configure script tries to automatically detect the available client libraries on your machine. Run \c{configure -help} to see what drivers can be built. You should get an output similar to this: @@ -139,7 +139,7 @@ Please refer to the MySQL documentation, chapter "libmysqld, the Embedded MySQL Server Library" for more information about the MySQL embedded server. - \section3 How to Build the QMYSQL Plugin on Unix and Mac OS X + \section3 How to Build the QMYSQL Plugin on Unix and OS X You need the MySQL header files and as well as the shared library \c{libmysqlclient.so}. Depending on your Linux distribution you may @@ -208,7 +208,7 @@ BLOBs are bound to placeholders or QSqlTableModel, which uses a prepared query to do this internally. - \section3 How to Build the OCI Plugin on Unix and Mac OS X + \section3 How to Build the OCI Plugin on Unix and OS X For Oracle 10g, all you need is the "Instant Client Package - Basic" and "Instant Client Package - SDK". For Oracle prior to 10g, you require @@ -343,7 +343,7 @@ "SQL_WCHAR support" in the ODBC driver manager otherwise Oracle will convert all Unicode strings to local 8-bit. - \section3 How to Build the ODBC Plugin on Unix and Mac OS X + \section3 How to Build the ODBC Plugin on Unix and OS X It is recommended that you use unixODBC. You can find the latest version and ODBC drivers at \l http://www.unixodbc.org. @@ -400,7 +400,7 @@ Binary Large Objects are supported through the \c BYTEA field type in PostgreSQL server versions >= 7.1. - \section3 How to Build the QPSQL Plugin on Unix and Mac OS X + \section3 How to Build the QPSQL Plugin on Unix and OS X You need the PostgreSQL client library and headers installed. @@ -440,7 +440,7 @@ Sybase client library. Refer to the Sybase documentation for information on how to set up a Sybase client configuration file to enable connections to databases on non-default ports. - \section3 How to Build the QTDS Plugin on Unix and Mac OS X + \section3 How to Build the QTDS Plugin on Unix and OS X Under Unix, two libraries are available which support the TDS protocol: @@ -493,7 +493,7 @@ We suggest using a forward-only query when calling stored procedures in DB2 (see QSqlQuery::setForwardOnly()). - \section3 How to Build the QDB2 Plugin on Unix and Mac OS X + \section3 How to Build the QDB2 Plugin on Unix and OS X \snippet code/doc_src_sql-driver.qdoc 18 @@ -643,7 +643,7 @@ \snippet code/doc_src_sql-driver.cpp 26 - \section3 How to Build the QIBASE Plugin on Unix and Mac OS X + \section3 How to Build the QIBASE Plugin on Unix and OS X The following assumes InterBase or Firebird is installed in \c{/opt/interbase}: diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp index 2d22682738fd8337cfc8f4dffd89f488b31d58b9..d68ac276efae9505a432185d0d9b1c9a6aa2022a 100644 --- a/src/sql/drivers/ibase/qsql_ibase.cpp +++ b/src/sql/drivers/ibase/qsql_ibase.cpp @@ -251,7 +251,7 @@ static ISC_TIME toTime(const QTime &t) static QTime fromTime(char *buffer) { - QTime t; + QTime t(0, 0); // have to demangle the structure ourselves because isc_decode_time // strips the msecs t = t.addMSecs(int((*(ISC_TIME*)buffer) / 10)); diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index d901008e007bbff79d7c81d83b3f51da20175fe3..086a232746ae0ec3d7cd1a48eb9d7743665cfa49 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -45,6 +45,7 @@ #include <qstringlist.h> #include <qtextcodec.h> #include <qvector.h> +#include <qfile.h> #include <qdebug.h> @@ -1211,7 +1212,7 @@ static void setOptionFlag(uint &optionFlags, const QString &opt) else if (opt == QLatin1String("CLIENT_ODBC")) optionFlags |= CLIENT_ODBC; else if (opt == QLatin1String("CLIENT_SSL")) - optionFlags |= CLIENT_SSL; + qWarning("QMYSQLDriver: SSL_KEY, SSL_CERT and SSL_CA should be used instead of CLIENT_SSL."); else qWarning("QMYSQLDriver::open: Unknown connect option '%s'", opt.toLocal8Bit().constData()); } @@ -1235,6 +1236,11 @@ bool QMYSQLDriver::open(const QString& db, unsigned int optionFlags = Q_CLIENT_MULTI_STATEMENTS; const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts)); QString unixSocket; + QString sslCert; + QString sslCA; + QString sslKey; + QString sslCAPath; + QString sslCipher; #if MYSQL_VERSION_ID >= 50000 my_bool reconnect=false; uint connectTimeout = 0; @@ -1263,6 +1269,16 @@ bool QMYSQLDriver::open(const QString& db, writeTimeout = val.toInt(); } #endif + else if (opt == QLatin1String("SSL_KEY")) + sslKey = val; + else if (opt == QLatin1String("SSL_CERT")) + sslCert = val; + else if (opt == QLatin1String("SSL_CA")) + sslCA = val; + else if (opt == QLatin1String("SSL_CAPATH")) + sslCAPath = val; + else if (opt == QLatin1String("SSL_CIPHER")) + sslCipher = val; else if (val == QLatin1String("TRUE") || val == QLatin1String("1")) setOptionFlag(optionFlags, tmp.left(idx).simplified()); else @@ -1273,39 +1289,60 @@ bool QMYSQLDriver::open(const QString& db, } } - if ((d->mysql = mysql_init((MYSQL*) 0))) { + if (!(d->mysql = mysql_init((MYSQL*) 0))) { + setLastError(qMakeError(tr("Unable to allocate a MYSQL object"), + QSqlError::ConnectionError, d)); + setOpenError(true); + return false; + } + + if (!sslKey.isNull() || !sslCert.isNull() || !sslCA.isNull() || + !sslCAPath.isNull() || !sslCipher.isNull()) { + mysql_ssl_set(d->mysql, + sslKey.isNull() ? static_cast<const char *>(0) + : QFile::encodeName(sslKey).constData(), + sslCert.isNull() ? static_cast<const char *>(0) + : QFile::encodeName(sslCert).constData(), + sslCA.isNull() ? static_cast<const char *>(0) + : QFile::encodeName(sslCA).constData(), + sslCAPath.isNull() ? static_cast<const char *>(0) + : QFile::encodeName(sslCAPath).constData(), + sslCipher.isNull() ? static_cast<const char *>(0) + : sslCipher.toLocal8Bit().constData()); + } + #if MYSQL_VERSION_ID >= 50000 - if (connectTimeout != 0) - mysql_options(d->mysql, MYSQL_OPT_CONNECT_TIMEOUT, &connectTimeout); - if (readTimeout != 0) - mysql_options(d->mysql, MYSQL_OPT_READ_TIMEOUT, &readTimeout); - if (writeTimeout != 0) - mysql_options(d->mysql, MYSQL_OPT_WRITE_TIMEOUT, &writeTimeout); + if (connectTimeout != 0) + mysql_options(d->mysql, MYSQL_OPT_CONNECT_TIMEOUT, &connectTimeout); + if (readTimeout != 0) + mysql_options(d->mysql, MYSQL_OPT_READ_TIMEOUT, &readTimeout); + if (writeTimeout != 0) + mysql_options(d->mysql, MYSQL_OPT_WRITE_TIMEOUT, &writeTimeout); #endif - if (mysql_real_connect(d->mysql, - host.isNull() ? static_cast<const char *>(0) - : host.toLocal8Bit().constData(), - user.isNull() ? static_cast<const char *>(0) - : user.toLocal8Bit().constData(), - password.isNull() ? static_cast<const char *>(0) - : password.toLocal8Bit().constData(), - db.isNull() ? static_cast<const char *>(0) - : db.toLocal8Bit().constData(), - (port > -1) ? port : 0, - unixSocket.isNull() ? static_cast<const char *>(0) - : unixSocket.toLocal8Bit().constData(), - optionFlags)) { - if (!db.isEmpty() && mysql_select_db(d->mysql, db.toLocal8Bit().constData())) { - setLastError(qMakeError(tr("Unable to open database '%1'").arg(db), QSqlError::ConnectionError, d)); - mysql_close(d->mysql); - setOpenError(true); - return false; - } + if (mysql_real_connect(d->mysql, + host.isNull() ? static_cast<const char *>(0) + : host.toLocal8Bit().constData(), + user.isNull() ? static_cast<const char *>(0) + : user.toLocal8Bit().constData(), + password.isNull() ? static_cast<const char *>(0) + : password.toLocal8Bit().constData(), + db.isNull() ? static_cast<const char *>(0) + : db.toLocal8Bit().constData(), + (port > -1) ? port : 0, + unixSocket.isNull() ? static_cast<const char *>(0) + : unixSocket.toLocal8Bit().constData(), + optionFlags)) + { + if (!db.isEmpty() && mysql_select_db(d->mysql, db.toLocal8Bit().constData())) { + setLastError(qMakeError(tr("Unable to open database '%1'").arg(db), QSqlError::ConnectionError, d)); + mysql_close(d->mysql); + setOpenError(true); + return false; + } #if MYSQL_VERSION_ID >= 50000 - if (reconnect) - mysql_options(d->mysql, MYSQL_OPT_RECONNECT, &reconnect); + if (reconnect) + mysql_options(d->mysql, MYSQL_OPT_RECONNECT, &reconnect); #endif - } } else { setLastError(qMakeError(tr("Unable to connect"), QSqlError::ConnectionError, d)); diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp index 240e19bf208635b12297b8b89d4caba00d5b5976..90c64d73315bed37f41dd2f5cf505a6617e4c1ac 100644 --- a/src/sql/kernel/qsqldatabase.cpp +++ b/src/sql/kernel/qsqldatabase.cpp @@ -1218,7 +1218,6 @@ QSqlRecord QSqlDatabase::record(const QString& tablename) const \li CLIENT_COMPRESS \li CLIENT_FOUND_ROWS \li CLIENT_IGNORE_SPACE - \li CLIENT_SSL \li CLIENT_ODBC \li CLIENT_NO_SCHEMA \li CLIENT_INTERACTIVE @@ -1227,6 +1226,11 @@ QSqlRecord QSqlDatabase::record(const QString& tablename) const \li MYSQL_OPT_CONNECT_TIMEOUT \li MYSQL_OPT_READ_TIMEOUT \li MYSQL_OPT_WRITE_TIMEOUT + \li SSL_KEY + \li SSL_CERT + \li SSL_CA + \li SSL_CAPATH + \li SSL_CIPHER \endlist \li diff --git a/src/sql/kernel/qsqldriver.h b/src/sql/kernel/qsqldriver.h index e8375765aa59bb6809f987742a0e537c521f2fe3..c53e1b81ee7b64beef3043bdc87999e7a9a45f68 100644 --- a/src/sql/kernel/qsqldriver.h +++ b/src/sql/kernel/qsqldriver.h @@ -83,7 +83,7 @@ public: DB2 }; - explicit QSqlDriver(QObject *parent=0); + explicit QSqlDriver(QObject *parent = Q_NULLPTR); ~QSqlDriver(); virtual bool isOpen() const; bool isOpenError() const; @@ -133,7 +133,7 @@ Q_SIGNALS: void notification(const QString &name, QSqlDriver::NotificationSource source, const QVariant &payload); protected: - QSqlDriver(QSqlDriverPrivate &dd, QObject *parent = 0); + QSqlDriver(QSqlDriverPrivate &dd, QObject *parent = Q_NULLPTR); virtual void setOpen(bool o); virtual void setOpenError(bool e); virtual void setLastError(const QSqlError& e); diff --git a/src/sql/kernel/qsqldriverplugin.h b/src/sql/kernel/qsqldriverplugin.h index 55b8c818789335f2371c1c83eaf5691cdeb7be8d..fd1a6203cbf1ad91adf62960d2b7289203c828b7 100644 --- a/src/sql/kernel/qsqldriverplugin.h +++ b/src/sql/kernel/qsqldriverplugin.h @@ -49,7 +49,7 @@ class Q_SQL_EXPORT QSqlDriverPlugin : public QObject { Q_OBJECT public: - explicit QSqlDriverPlugin(QObject *parent = 0); + explicit QSqlDriverPlugin(QObject *parent = Q_NULLPTR); ~QSqlDriverPlugin(); virtual QSqlDriver *create(const QString &key) = 0; diff --git a/src/sql/kernel/qsqlindex.cpp b/src/sql/kernel/qsqlindex.cpp index 53e13c85e65592c06096955fe03a8dd487bb56d5..bb80cf3e03494cd5dbaf3ea964f312451602880f 100644 --- a/src/sql/kernel/qsqlindex.cpp +++ b/src/sql/kernel/qsqlindex.cpp @@ -38,6 +38,9 @@ QT_BEGIN_NAMESPACE +// ### Qt 6: remove the static assertion, the 'sorts' field was changed from QList to QVector in Qt 5.6 +Q_STATIC_ASSERT((sizeof(QList<bool>) == sizeof(QVector<bool>))); + /*! \class QSqlIndex \brief The QSqlIndex class provides functions to manipulate and diff --git a/src/sql/kernel/qsqlindex.h b/src/sql/kernel/qsqlindex.h index d3d4a7c9aa541eb4c0b81b056c10a64f51a34f72..4a81d481611a3d0d434a92caf7496b4d0be5ac7a 100644 --- a/src/sql/kernel/qsqlindex.h +++ b/src/sql/kernel/qsqlindex.h @@ -36,7 +36,10 @@ #include <QtSql/qsqlrecord.h> #include <QtCore/qstring.h> +#include <QtCore/qvector.h> +#if QT_DEPRECATED_SINCE(5,6) #include <QtCore/qlist.h> +#endif QT_BEGIN_NAMESPACE @@ -63,7 +66,7 @@ private: QString createField(int i, const QString& prefix, bool verbose) const; QString cursor; QString nm; - QList<bool> sorts; + QVector<bool> sorts; }; QT_END_NAMESPACE diff --git a/src/sql/models/qsqlquerymodel.h b/src/sql/models/qsqlquerymodel.h index 2d37b9a482d11e3406f0fb0c5a0280c2b68790f1..5c7c22af1078a9f7a73b2c0ffebdd617d4ae32e5 100644 --- a/src/sql/models/qsqlquerymodel.h +++ b/src/sql/models/qsqlquerymodel.h @@ -51,7 +51,7 @@ class Q_SQL_EXPORT QSqlQueryModel: public QAbstractTableModel Q_DECLARE_PRIVATE(QSqlQueryModel) public: - explicit QSqlQueryModel(QObject *parent = 0); + explicit QSqlQueryModel(QObject *parent = Q_NULLPTR); virtual ~QSqlQueryModel(); int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; @@ -98,7 +98,7 @@ protected: virtual QModelIndex indexInQuery(const QModelIndex &item) const; void setLastError(const QSqlError &error); - QSqlQueryModel(QSqlQueryModelPrivate &dd, QObject *parent = 0); + QSqlQueryModel(QSqlQueryModelPrivate &dd, QObject *parent = Q_NULLPTR); }; QT_END_NAMESPACE diff --git a/src/sql/models/qsqlrelationaltablemodel.h b/src/sql/models/qsqlrelationaltablemodel.h index f7470142d60011514ce352b2c6ecb7e40143ecb2..f2a546dc1aecfe04148adb9b03f572ec6b48c216 100644 --- a/src/sql/models/qsqlrelationaltablemodel.h +++ b/src/sql/models/qsqlrelationaltablemodel.h @@ -70,7 +70,7 @@ public: LeftJoin }; - explicit QSqlRelationalTableModel(QObject *parent = 0, + explicit QSqlRelationalTableModel(QObject *parent = Q_NULLPTR, QSqlDatabase db = QSqlDatabase()); virtual ~QSqlRelationalTableModel(); diff --git a/src/sql/models/qsqltablemodel.h b/src/sql/models/qsqltablemodel.h index a06abefb1cb27632bc75201b13a0eb7ef7a1981a..5481a777a164cb176c8a5e256517a3177cdb4b55 100644 --- a/src/sql/models/qsqltablemodel.h +++ b/src/sql/models/qsqltablemodel.h @@ -53,7 +53,7 @@ class Q_SQL_EXPORT QSqlTableModel: public QSqlQueryModel public: enum EditStrategy {OnFieldChange, OnRowChange, OnManualSubmit}; - explicit QSqlTableModel(QObject *parent = 0, QSqlDatabase db = QSqlDatabase()); + explicit QSqlTableModel(QObject *parent = Q_NULLPTR, QSqlDatabase db = QSqlDatabase()); virtual ~QSqlTableModel(); virtual void setTable(const QString &tableName); @@ -115,7 +115,7 @@ Q_SIGNALS: void beforeDelete(int row); protected: - QSqlTableModel(QSqlTableModelPrivate &dd, QObject *parent = 0, QSqlDatabase db = QSqlDatabase()); + QSqlTableModel(QSqlTableModelPrivate &dd, QObject *parent = Q_NULLPTR, QSqlDatabase db = QSqlDatabase()); virtual bool updateRowInTable(int row, const QSqlRecord &values); virtual bool insertRowIntoTable(const QSqlRecord &values); diff --git a/src/src.pro b/src/src.pro index 6dc5c503c7b6a2374d43e91be026ff5d5be69db1..b884a448869bdb8e5eee24674b4506461f98c22e 100644 --- a/src/src.pro +++ b/src/src.pro @@ -181,7 +181,7 @@ contains(QT_CONFIG, concurrent):SUBDIRS += src_concurrent SUBDIRS += src_opengl src_plugins.depends += src_opengl } - !wince*:!winrt { + !wince:!winrt { SUBDIRS += src_printsupport src_plugins.depends += src_printsupport } diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc index 1e9ed34b4f3f83a6603609375e92e660ad138330..82651d5cbaa940c19d06704b3548c27d639ce4af 100644 --- a/src/testlib/doc/src/qttestlib-manual.qdoc +++ b/src/testlib/doc/src/qttestlib-manual.qdoc @@ -314,7 +314,7 @@ \li All platforms \row \li CPU tick counter \li -tickcounter - \li Windows, Mac OS X, Linux, many UNIX-like systems. + \li Windows, OS X, Linux, many UNIX-like systems. \row \li Event Counter \li -eventcounter \li All platforms diff --git a/src/testlib/qbenchmark_p.h b/src/testlib/qbenchmark_p.h index d785f3d4b7fa98cf92c78419c9d9b1c043e43d2e..6312a34cb86b1f45d32b2aaf6506d58406ca802a 100644 --- a/src/testlib/qbenchmark_p.h +++ b/src/testlib/qbenchmark_p.h @@ -91,6 +91,7 @@ struct QBenchmarkContext QBenchmarkContext() : checkpointIndex(-1) {} }; +Q_DECLARE_TYPEINFO(QBenchmarkContext, Q_MOVABLE_TYPE); class QBenchmarkResult { @@ -126,6 +127,7 @@ public: return (value / iterations) < (other.value / other.iterations); } }; +Q_DECLARE_TYPEINFO(QBenchmarkResult, Q_MOVABLE_TYPE); /* The QBenchmarkGlobalData class stores global benchmark-related data. diff --git a/src/testlib/qsignalspy.h b/src/testlib/qsignalspy.h index cfde89aec80d8262662fbe7deb7eef2c60b0f99c..1751220059a6a7ced2baac7cf9f9251605a80104 100644 --- a/src/testlib/qsignalspy.h +++ b/src/testlib/qsignalspy.h @@ -82,7 +82,7 @@ public: } if (!QMetaObject::connect(obj, sigIndex, this, memberOffset, - Qt::DirectConnection, 0)) { + Qt::DirectConnection, Q_NULLPTR)) { qWarning("QSignalSpy: QMetaObject::connect returned false. Unable to connect."); return; } diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index dc9a3fb8a343456b5e468561fda0ec6b999bea15..bb0966d778c6643f6ff38394437291ab6b1247c8 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -205,7 +205,7 @@ inline bool qCompare(QList<T> const &t1, QList<T> const &t2, const char *actual, delete [] val2; } } - return compare_helper(isOk, msg, 0, 0, actual, expected, file, line); + return compare_helper(isOk, msg, Q_NULLPTR, Q_NULLPTR, actual, expected, file, line); } template <> diff --git a/src/testlib/qtest_gui.h b/src/testlib/qtest_gui.h index 8941a27367ba793141c22dbe4c9d133bf6a7de03..0ad27a3d62ef7e61e3fade98ae62d35522adc392 100644 --- a/src/testlib/qtest_gui.h +++ b/src/testlib/qtest_gui.h @@ -87,24 +87,24 @@ inline bool qCompare(QImage const &t1, QImage const &t2, qsnprintf(msg, 1024, "Compared QImages differ.\n" " Actual (%s).isNull(): %d\n" " Expected (%s).isNull(): %d", actual, t1Null, expected, t2Null); - return compare_helper(false, msg, 0, 0, actual, expected, file, line); + return compare_helper(false, msg, Q_NULLPTR, Q_NULLPTR, actual, expected, file, line); } if (t1Null && t2Null) - return compare_helper(true, 0, 0, 0, actual, expected, file, line); + return compare_helper(true, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR, actual, expected, file, line); if (t1.width() != t2.width() || t1.height() != t2.height()) { qsnprintf(msg, 1024, "Compared QImages differ in size.\n" " Actual (%s): %dx%d\n" " Expected (%s): %dx%d", actual, t1.width(), t1.height(), expected, t2.width(), t2.height()); - return compare_helper(false, msg, 0, 0, actual, expected, file, line); + return compare_helper(false, msg, Q_NULLPTR, Q_NULLPTR, actual, expected, file, line); } if (t1.format() != t2.format()) { qsnprintf(msg, 1024, "Compared QImages differ in format.\n" " Actual (%s): %d\n" " Expected (%s): %d", actual, t1.format(), expected, t2.format()); - return compare_helper(false, msg, 0, 0, actual, expected, file, line); + return compare_helper(false, msg, Q_NULLPTR, Q_NULLPTR, actual, expected, file, line); } return compare_helper(t1 == t2, "Compared values are not the same", toString(t1), toString(t2), actual, expected, file, line); @@ -121,17 +121,17 @@ inline bool qCompare(QPixmap const &t1, QPixmap const &t2, const char *actual, c qsnprintf(msg, 1024, "Compared QPixmaps differ.\n" " Actual (%s).isNull(): %d\n" " Expected (%s).isNull(): %d", actual, t1Null, expected, t2Null); - return compare_helper(false, msg, 0, 0, actual, expected, file, line); + return compare_helper(false, msg, Q_NULLPTR, Q_NULLPTR, actual, expected, file, line); } if (t1Null && t2Null) - return compare_helper(true, 0, 0, 0, actual, expected, file, line); + return compare_helper(true, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR, actual, expected, file, line); if (t1.width() != t2.width() || t1.height() != t2.height()) { qsnprintf(msg, 1024, "Compared QPixmaps differ in size.\n" " Actual (%s): %dx%d\n" " Expected (%s): %dx%d", actual, t1.width(), t1.height(), expected, t2.width(), t2.height()); - return compare_helper(false, msg, 0, 0, actual, expected, file, line); + return compare_helper(false, msg, Q_NULLPTR, Q_NULLPTR, actual, expected, file, line); } return qCompare(t1.toImage(), t2.toImage(), actual, expected, file, line); } diff --git a/src/testlib/qtestaccessible.h b/src/testlib/qtestaccessible.h index f1ac625dbda1f0d24d060d9b962699286196d08e..628145f3b0b5fcab8acb3f7fb9d972858827942f 100644 --- a/src/testlib/qtestaccessible.h +++ b/src/testlib/qtestaccessible.h @@ -126,7 +126,7 @@ public: static void cleanup() { delete instance(); - instance() = 0; + instance() = Q_NULLPTR; } static void clearEvents() { eventList().clear(); } static EventList events() { return eventList(); } @@ -162,8 +162,8 @@ private: ~QTestAccessibility() { - QAccessible::installUpdateHandler(0); - QAccessible::installRootObjectHandler(0); + QAccessible::installUpdateHandler(Q_NULLPTR); + QAccessible::installRootObjectHandler(Q_NULLPTR); } static void rootObjectHandler(QObject *object) @@ -268,7 +268,7 @@ private: static QTestAccessibility *&instance() { - static QTestAccessibility *ta = 0; + static QTestAccessibility *ta = Q_NULLPTR; return ta; } diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp index f9ce908a008b7f23c4fac647f164083be82c3c80..eb7abdad46b2fda37bd989013bfdf9d229890429 100644 --- a/src/testlib/qtestblacklist.cpp +++ b/src/testlib/qtestblacklist.cpp @@ -166,6 +166,19 @@ static std::set<QByteArray> *gpuFeatures = 0; Q_TESTLIB_EXPORT std::set<QByteArray> *(*qgpu_features_ptr)(const QString &) = 0; +static bool isGPUTestBlacklisted(const char *slot, const char *data = 0) +{ + const QByteArray disableKey = QByteArrayLiteral("disable_") + QByteArray(slot); + if (gpuFeatures->find(disableKey) != gpuFeatures->end()) { + QByteArray msg = QByteArrayLiteral("Skipped due to GPU blacklist: ") + disableKey; + if (data) + msg += QByteArrayLiteral(":") + QByteArray(data); + QTest::qSkip(msg.constData(), __FILE__, __LINE__); + return true; + } + return false; +} + namespace QTestPrivate { void parseBlackList() @@ -230,10 +243,12 @@ void checkBlackLists(const char *slot, const char *data) // Tests blacklisted in GPU_BLACKLIST are to be skipped. Just ignoring the result is // not sufficient since these are expected to crash or behave in undefined ways. if (!ignore && gpuFeatures) { - const QByteArray disableKey = QByteArrayLiteral("disable_") + QByteArray(slot); - if (gpuFeatures->find(disableKey) != gpuFeatures->end()) { - const QByteArray msg = QByteArrayLiteral("Skipped due to GPU blacklist: ") + disableKey; - QTest::qSkip(msg.constData(), __FILE__, __LINE__); + QByteArray s_gpu = slot; + ignore = isGPUTestBlacklisted(s_gpu, data); + if (!ignore && data) { + s_gpu += ':'; + s_gpu += data; + isGPUTestBlacklisted(s_gpu); } } } diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 11450eb14192382703418128eabd910150bcb655..f571ed476f4489d97feba6a28e1df645e9f1db5e 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -113,7 +113,7 @@ static void stackTrace() char cmd[512]; qsnprintf(cmd, 512, "gdb --pid %d 2>/dev/null <<EOF\n" "set prompt\n" - "thread apply all where\n" + "thread apply all where full\n" "detach\n" "quit\n" "EOF\n", @@ -247,7 +247,7 @@ static void stackTrace() \note This macro can only be used in a test function that is invoked by the test framework. - \sa QTRY_VERIFY(), QVERIFY(), QCOMPARE(), QTRY_COMPARE() + \sa QTRY_VERIFY(), QTRY_VERIFY2_WITH_TIMEOUT(), QVERIFY(), QCOMPARE(), QTRY_COMPARE() */ @@ -261,7 +261,47 @@ static void stackTrace() \note This macro can only be used in a test function that is invoked by the test framework. - \sa QTRY_VERIFY_WITH_TIMEOUT(), QVERIFY(), QCOMPARE(), QTRY_COMPARE() + \sa QTRY_VERIFY_WITH_TIMEOUT(), QTRY_VERIFY2(), QVERIFY(), QCOMPARE(), QTRY_COMPARE() +*/ + +/*! \macro QTRY_VERIFY2_WITH_TIMEOUT(condition, message, timeout) + \since 5.6 + + \relates QTest + + The QTRY_VERIFY2_WITH_TIMEOUT macro is similar to QTRY_VERIFY_WITH_TIMEOUT() + except that it outputs a verbose \a message when \a condition is still false + after the specified timeout. The \a message is a plain C string. + + Example: + \code + QTRY_VERIFY2_WITH_TIMEOUT(list.size() > 2, QByteArray::number(list.size()).constData(), 10000); + \endcode + + \note This macro can only be used in a test function that is invoked + by the test framework. + + \sa QTRY_VERIFY(), QTRY_VERIFY_WITH_TIMEOUT(), QVERIFY(), QCOMPARE(), QTRY_COMPARE() +*/ + +/*! \macro QTRY_VERIFY2(condition, message) + \since 5.6 + + \relates QTest + + Checks the \a condition by invoking QTRY_VERIFY2_WITH_TIMEOUT() with a timeout + of five seconds. If \a condition is then still false, \a message is output. + The \a message is a plain C string. + + Example: + \code + QTRY_VERIFY2_WITH_TIMEOUT(list.size() > 2, QByteArray::number(list.size()).constData()); + \endcode + + \note This macro can only be used in a test function that is invoked + by the test framework. + + \sa QTRY_VERIFY2_WITH_TIMEOUT(), QTRY_VERIFY2(), QVERIFY(), QCOMPARE(), QTRY_COMPARE() */ /*! \macro QTRY_COMPARE_WITH_TIMEOUT(actual, expected, timeout) @@ -1318,7 +1358,7 @@ static void stackTrace() */ /*! - \fn QTouchEventSequence QTest::touchEvent(QWindow *window, QTouchDevice *device, bool autoCommit = true) + \fn QTouchEventSequence QTest::touchEvent(QWindow *window, QTouchDevice *device, bool autoCommit) \since 5.0 Creates and returns a QTouchEventSequence for the \a device to @@ -1335,7 +1375,7 @@ static void stackTrace() */ /*! - \fn QTouchEventSequence QTest::touchEvent(QWidget *widget, QTouchDevice *device, bool autoCommit = true) + \fn QTouchEventSequence QTest::touchEvent(QWidget *widget, QTouchDevice *device, bool autoCommit) Creates and returns a QTouchEventSequence for the \a device to simulate events for \a widget. @@ -1925,7 +1965,7 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml) QTestLog::addLogger(logFormat, logFilename); } -QBenchmarkResult qMedian(const QList<QBenchmarkResult> &container) +QBenchmarkResult qMedian(const QVector<QBenchmarkResult> &container) { const int count = container.count(); if (count == 0) @@ -1934,7 +1974,7 @@ QBenchmarkResult qMedian(const QList<QBenchmarkResult> &container) if (count == 1) return container.front(); - QList<QBenchmarkResult> containerCopy = container; + QVector<QBenchmarkResult> containerCopy = container; std::sort(containerCopy.begin(), containerCopy.end()); const int middle = count / 2; @@ -1971,7 +2011,7 @@ static void qInvokeTestMethodDataEntry(char *slot) bool isBenchmark = false; int i = (QBenchmarkGlobalData::current->measurer->needsWarmupIteration()) ? -1 : 0; - QList<QBenchmarkResult> results; + QVector<QBenchmarkResult> results; bool minimumTotalReached = false; do { QBenchmarkTestMethodData::current->beginDataRun(); @@ -2539,7 +2579,7 @@ FatalSignalHandler::FatalSignalHandler() sigemptyset(&handledSignals); const int fatalSignals[] = { - SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGFPE, SIGSEGV, SIGPIPE, SIGTERM, 0 }; + SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGBUS, SIGFPE, SIGSEGV, SIGPIPE, SIGTERM, 0 }; struct sigaction act; memset(&act, 0, sizeof(act)); @@ -2549,6 +2589,24 @@ FatalSignalHandler::FatalSignalHandler() #if !defined(Q_OS_INTEGRITY) && !defined(Q_OS_NACL_NEWLIB) act.sa_flags = SA_RESETHAND; #endif + +#ifdef SA_ONSTACK + // Let the signal handlers use an alternate stack + // This is necessary if SIGSEGV is to catch a stack overflow +# if defined(Q_CC_GNU) && defined(Q_OF_ELF) + // Put the alternate stack in the .lbss (large BSS) section so that it doesn't + // interfere with normal .bss symbols + __attribute__((section(".lbss.altstack"), aligned(4096))) +# endif + static char alternate_stack[16 * 1024]; + stack_t stack; + stack.ss_flags = 0; + stack.ss_size = sizeof alternate_stack; + stack.ss_sp = alternate_stack; + sigaltstack(&stack, 0); + act.sa_flags |= SA_ONSTACK; +#endif + // Block all fatal signals in our signal handler so we don't try to close // the testlog twice. sigemptyset(&act.sa_mask); @@ -2599,13 +2657,137 @@ FatalSignalHandler::~FatalSignalHandler() } // namespace #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) + +// Helper class for resolving symbol names by dynamically loading "dbghelp.dll". +class DebugSymbolResolver +{ + Q_DISABLE_COPY(DebugSymbolResolver) +public: + struct Symbol { + Symbol() : name(Q_NULLPTR), address(0) {} + + const char *name; // Must be freed by caller. + DWORD64 address; + }; + + explicit DebugSymbolResolver(HANDLE process); + ~DebugSymbolResolver() { cleanup(); } + + bool isValid() const { return m_symFromAddr; } + + Symbol resolveSymbol(DWORD64 address) const; + +private: + // typedefs from DbgHelp.h/.dll + struct DBGHELP_SYMBOL_INFO { // SYMBOL_INFO + ULONG SizeOfStruct; + ULONG TypeIndex; // Type Index of symbol + ULONG64 Reserved[2]; + ULONG Index; + ULONG Size; + ULONG64 ModBase; // Base Address of module comtaining this symbol + ULONG Flags; + ULONG64 Value; // Value of symbol, ValuePresent should be 1 + ULONG64 Address; // Address of symbol including base address of module + ULONG Register; // register holding value or pointer to value + ULONG Scope; // scope of the symbol + ULONG Tag; // pdb classification + ULONG NameLen; // Actual length of name + ULONG MaxNameLen; + CHAR Name[1]; // Name of symbol + }; + + typedef BOOL (__stdcall *SymInitializeType)(HANDLE, PCSTR, BOOL); + typedef BOOL (__stdcall *SymFromAddrType)(HANDLE, DWORD64, PDWORD64, DBGHELP_SYMBOL_INFO *); + + void cleanup(); + + const HANDLE m_process; + HMODULE m_dbgHelpLib; + SymFromAddrType m_symFromAddr; +}; + +void DebugSymbolResolver::cleanup() +{ + if (m_dbgHelpLib) + FreeLibrary(m_dbgHelpLib); + m_dbgHelpLib = 0; + m_symFromAddr = Q_NULLPTR; +} + +DebugSymbolResolver::DebugSymbolResolver(HANDLE process) + : m_process(process), m_dbgHelpLib(0), m_symFromAddr(Q_NULLPTR) +{ + bool success = false; + m_dbgHelpLib = LoadLibraryW(L"dbghelp.dll"); + if (m_dbgHelpLib) { + SymInitializeType symInitialize = (SymInitializeType)(GetProcAddress(m_dbgHelpLib, "SymInitialize")); + m_symFromAddr = (SymFromAddrType)(GetProcAddress(m_dbgHelpLib, "SymFromAddr")); + success = symInitialize && m_symFromAddr && symInitialize(process, NULL, TRUE); + } + if (!success) + cleanup(); +} + +DebugSymbolResolver::Symbol DebugSymbolResolver::resolveSymbol(DWORD64 address) const +{ + // reserve additional buffer where SymFromAddr() will store the name + struct NamedSymbolInfo : public DBGHELP_SYMBOL_INFO { + enum { symbolNameLength = 255 }; + + char name[symbolNameLength + 1]; + }; + + Symbol result; + if (!isValid()) + return result; + NamedSymbolInfo symbolBuffer; + memset(&symbolBuffer, 0, sizeof(NamedSymbolInfo)); + symbolBuffer.MaxNameLen = NamedSymbolInfo::symbolNameLength; + symbolBuffer.SizeOfStruct = sizeof(DBGHELP_SYMBOL_INFO); + if (!m_symFromAddr(m_process, address, 0, &symbolBuffer)) + return result; + result.name = qstrdup(symbolBuffer.Name); + result.address = symbolBuffer.Address; + return result; +} + static LONG WINAPI windowsFaultHandler(struct _EXCEPTION_POINTERS *exInfo) { + enum { maxStackFrames = 100 }; char appName[MAX_PATH]; if (!GetModuleFileNameA(NULL, appName, MAX_PATH)) appName[0] = 0; - fprintf(stderr, "A crash occurred in %s (exception code 0x%lx).", - appName, exInfo->ExceptionRecord->ExceptionCode); + + const void *exceptionAddress = exInfo->ExceptionRecord->ExceptionAddress; + fprintf(stderr, "A crash occurred in %s.\n\n" + "Exception address: 0x%p\n" + "Exception code : 0x%lx\n", + appName, exceptionAddress, exInfo->ExceptionRecord->ExceptionCode); + + DebugSymbolResolver resolver(GetCurrentProcess()); + if (resolver.isValid()) { + DebugSymbolResolver::Symbol exceptionSymbol = resolver.resolveSymbol(DWORD64(exceptionAddress)); + if (exceptionSymbol.name) { + fprintf(stderr, "Nearby symbol : %s\n", exceptionSymbol.name); + delete [] exceptionSymbol.name; + } + void *stack[maxStackFrames]; + fputs("\nStack:\n", stderr); + const unsigned frameCount = CaptureStackBackTrace(0, DWORD(maxStackFrames), stack, NULL); + for (unsigned f = 0; f < frameCount; ++f) { + DebugSymbolResolver::Symbol symbol = resolver.resolveSymbol(DWORD64(stack[f])); + if (symbol.name) { + fprintf(stderr, "#%3u: %s() - 0x%p\n", f + 1, symbol.name, (const void *)symbol.address); + delete [] symbol.name; + } else { + fprintf(stderr, "#%3u: Unable to obtain symbol\n", f + 1); + } + } + } + + fputc('\n', stderr); + return EXCEPTION_EXECUTE_HANDLER; } #endif // Q_OS_WIN) && !Q_OS_WINCE && !Q_OS_WINRT @@ -2894,36 +3076,39 @@ static inline bool isWindowsBuildDirectory(const QString &dirName) #endif /*! - Extract a directory from resources to disk. The content is extracted - recursively to a temporary folder. The extracted content is not removed - automatically. + Extracts a directory from resources to disk. The content is extracted + recursively to a temporary folder. The extracted content is removed + automatically once the last reference to the return value goes out of scope. \a dirName is the name of the directory to extract from resources. - Returns the path where the data was extracted or an empty string in case of + Returns the temporary directory where the data was extracted or null in case of errors. */ -QString QTest::qExtractTestData(const QString &dirName) +QSharedPointer<QTemporaryDir> QTest::qExtractTestData(const QString &dirName) { - QTemporaryDir temporaryDir; - temporaryDir.setAutoRemove(false); + QSharedPointer<QTemporaryDir> result; // null until success, then == tempDir - if (!temporaryDir.isValid()) - return QString(); + QSharedPointer<QTemporaryDir> tempDir = QSharedPointer<QTemporaryDir>::create(); - const QString dataPath = temporaryDir.path(); + tempDir->setAutoRemove(true); + + if (!tempDir->isValid()) + return result; + + const QString dataPath = tempDir->path(); const QString resourcePath = QLatin1Char(':') + dirName; const QFileInfo fileInfo(resourcePath); if (!fileInfo.isDir()) { qWarning("Resource path '%s' is not a directory.", qPrintable(resourcePath)); - return QString(); + return result; } QDirIterator it(resourcePath, QDirIterator::Subdirectories); if (!it.hasNext()) { qWarning("Resource directory '%s' is empty.", qPrintable(resourcePath)); - return QString(); + return result; } while (it.hasNext()) { @@ -2932,17 +3117,23 @@ QString QTest::qExtractTestData(const QString &dirName) QFileInfo fileInfo = it.fileInfo(); if (!fileInfo.isDir()) { - const QString destination = dataPath + QLatin1Char('/') + fileInfo.filePath().mid(resourcePath.length()); + const QString destination = dataPath + QLatin1Char('/') + fileInfo.filePath().midRef(resourcePath.length()); QFileInfo destinationFileInfo(destination); QDir().mkpath(destinationFileInfo.path()); if (!QFile::copy(fileInfo.filePath(), destination)) { qWarning("Failed to copy '%s'.", qPrintable(fileInfo.filePath())); - return QString(); + return result; + } + if (!QFile::setPermissions(destination, QFile::ReadUser | QFile::WriteUser | QFile::ReadGroup)) { + qWarning("Failed to set permissions on '%s'.", qPrintable(destination)); + return result; } } } - return dataPath; + result = qMove(tempDir); + + return result; } /*! \internal @@ -3310,6 +3501,8 @@ TO_STRING_IMPL(quint64, %llu) #endif TO_STRING_IMPL(bool, %d) TO_STRING_IMPL(char, %c) +TO_STRING_IMPL(signed char, %hhd) +TO_STRING_IMPL(unsigned char, %hhu) TO_STRING_IMPL(float, %g) TO_STRING_IMPL(double, %lg) diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index 2c6a94faa1c9f2024eedad289317b7f003693077..7d2fd2e701a171c2f224e8ee2352ad99368d8a96 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -39,7 +39,10 @@ #include <QtCore/qstring.h> #include <QtCore/qnamespace.h> #include <QtCore/qmetatype.h> +#include <QtCore/qmetaobject.h> #include <QtCore/qtypetraits.h> +#include <QtCore/qsharedpointer.h> +#include <QtCore/qtemporarydir.h> #include <string.h> @@ -155,6 +158,15 @@ do { \ #define QTRY_VERIFY(__expr) QTRY_VERIFY_WITH_TIMEOUT((__expr), 5000) +// Will try to wait for the expression to become true while allowing event processing +#define QTRY_VERIFY2_WITH_TIMEOUT(__expr, __messageExpression, __timeout) \ +do { \ + QTRY_IMPL((__expr), __timeout);\ + QVERIFY2(__expr, __messageExpression); \ +} while (0) + +#define QTRY_VERIFY2(__expr, __messageExpression) QTRY_VERIFY2_WITH_TIMEOUT((__expr), (__messageExpression), 5000) + // Will try to wait for the comparison to become successful while allowing event processing #define QTRY_COMPARE_WITH_TIMEOUT(__expr, __expected, __timeout) \ do { \ @@ -220,12 +232,28 @@ class QTestData; namespace QTest { - template <typename T> - inline char *toString(const T &) + namespace Internal { + + template<typename T> // Output registered enums + inline typename QtPrivate::QEnableIf<QtPrivate::IsQEnumHelper<T>::Value, char*>::Type toString(T e) + { + QMetaEnum me = QMetaEnum::fromType<T>(); + return qstrdup(me.key(e)); + } + + template <typename T> // Fallback + inline typename QtPrivate::QEnableIf<!QtPrivate::IsQEnumHelper<T>::Value, char*>::Type toString(const T &) { - return 0; + return Q_NULLPTR; } + } // namespace Internal + + template<typename T> + inline char *toString(const T &t) + { + return Internal::toString(t); + } Q_TESTLIB_EXPORT char *toHexRepresentation(const char *ba, int length); Q_TESTLIB_EXPORT char *toPrettyCString(const char *unicode, int length); @@ -233,10 +261,10 @@ namespace QTest Q_TESTLIB_EXPORT char *toString(const char *); Q_TESTLIB_EXPORT char *toString(const void *); - Q_TESTLIB_EXPORT int qExec(QObject *testObject, int argc = 0, char **argv = 0); + Q_TESTLIB_EXPORT int qExec(QObject *testObject, int argc = 0, char **argv = Q_NULLPTR); Q_TESTLIB_EXPORT int qExec(QObject *testObject, const QStringList &arguments); - Q_TESTLIB_EXPORT void setMainSourcePath(const char *file, const char *builddir = 0); + Q_TESTLIB_EXPORT void setMainSourcePath(const char *file, const char *builddir = Q_NULLPTR); Q_TESTLIB_EXPORT bool qVerify(bool statement, const char *statementStr, const char *description, const char *file, int line); @@ -244,15 +272,15 @@ namespace QTest Q_TESTLIB_EXPORT void qSkip(const char *message, const char *file, int line); Q_TESTLIB_EXPORT bool qExpectFail(const char *dataIndex, const char *comment, TestFailMode mode, const char *file, int line); - Q_TESTLIB_EXPORT void qWarn(const char *message, const char *file = 0, int line = 0); + Q_TESTLIB_EXPORT void qWarn(const char *message, const char *file = Q_NULLPTR, int line = 0); Q_TESTLIB_EXPORT void ignoreMessage(QtMsgType type, const char *message); #ifndef QT_NO_REGULAREXPRESSION Q_TESTLIB_EXPORT void ignoreMessage(QtMsgType type, const QRegularExpression &messagePattern); #endif - Q_TESTLIB_EXPORT QString qExtractTestData(const QString &dirName); - Q_TESTLIB_EXPORT QString qFindTestData(const char* basepath, const char* file = 0, int line = 0, const char* builddir = 0); - Q_TESTLIB_EXPORT QString qFindTestData(const QString& basepath, const char* file = 0, int line = 0, const char* builddir = 0); + Q_TESTLIB_EXPORT QSharedPointer<QTemporaryDir> qExtractTestData(const QString &dirName); + Q_TESTLIB_EXPORT QString qFindTestData(const char* basepath, const char* file = Q_NULLPTR, int line = 0, const char* builddir = Q_NULLPTR); + Q_TESTLIB_EXPORT QString qFindTestData(const QString& basepath, const char* file = Q_NULLPTR, int line = 0, const char* builddir = Q_NULLPTR); Q_TESTLIB_EXPORT void *qData(const char *tagName, int typeId); Q_TESTLIB_EXPORT void *qGlobalData(const char *tagName, int typeId); @@ -321,6 +349,8 @@ namespace QTest QTEST_COMPARE_DECL(float) QTEST_COMPARE_DECL(double) QTEST_COMPARE_DECL(char) + QTEST_COMPARE_DECL(signed char) + QTEST_COMPARE_DECL(unsigned char) QTEST_COMPARE_DECL(bool) #endif @@ -390,14 +420,6 @@ namespace QTest return compare_string_helper(t1, t2, actual, expected, file, line); } - // NokiaX86 and RVCT do not like implicitly comparing bool with int - inline bool qCompare(bool const &t1, int const &t2, - const char *actual, const char *expected, const char *file, int line) - { - return qCompare(int(t1), t2, actual, expected, file, line); - } - - template <class T> inline bool qTest(const T& actual, const char *elementName, const char *actualStr, const char *expected, const char *file, int line) diff --git a/src/testlib/qtestevent.h b/src/testlib/qtestevent.h index a3e5f02ec18cbb15bb6e0ccae941e8c45ad7fc38..9794b15f4a4dce1b111cdf2c66a45e636671499b 100644 --- a/src/testlib/qtestevent.h +++ b/src/testlib/qtestevent.h @@ -185,20 +185,20 @@ public: inline void addKeyEvent(QTest::KeyAction action, char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1) { append(new QTestKeyEvent(action, ascii, modifiers, msecs)); } - inline void addMousePress(Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, + inline void addMousePress(Qt::MouseButton button, Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay=-1) { append(new QTestMouseEvent(QTest::MousePress, button, stateKey, pos, delay)); } - inline void addMouseRelease(Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, + inline void addMouseRelease(Qt::MouseButton button, Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay=-1) { append(new QTestMouseEvent(QTest::MouseRelease, button, stateKey, pos, delay)); } - inline void addMouseClick(Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, + inline void addMouseClick(Qt::MouseButton button, Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay=-1) { append(new QTestMouseEvent(QTest::MouseClick, button, stateKey, pos, delay)); } - inline void addMouseDClick(Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, + inline void addMouseDClick(Qt::MouseButton button, Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay=-1) { append(new QTestMouseEvent(QTest::MouseDClick, button, stateKey, pos, delay)); } inline void addMouseMove(QPoint pos = QPoint(), int delay=-1) - { append(new QTestMouseEvent(QTest::MouseMove, Qt::NoButton, 0, pos, delay)); } + { append(new QTestMouseEvent(QTest::MouseMove, Qt::NoButton, Qt::KeyboardModifiers(), pos, delay)); } #endif //QT_GUI_LIB inline void addDelay(int msecs) diff --git a/src/testlib/qtesteventloop.h b/src/testlib/qtesteventloop.h index a9f611f306e7e85268773d2abb4bd81f68c9aa29..a8ce619d4e3f762f8b5c9ab0ccf5bbdad010e4a6 100644 --- a/src/testlib/qtesteventloop.h +++ b/src/testlib/qtesteventloop.h @@ -50,8 +50,8 @@ class Q_TESTLIB_EXPORT QTestEventLoop : public QObject Q_OBJECT public: - inline QTestEventLoop(QObject *aParent = 0) - : QObject(aParent), inLoop(false), _timeout(false), timerId(-1), loop(0) {} + inline QTestEventLoop(QObject *aParent = Q_NULLPTR) + : QObject(aParent), inLoop(false), _timeout(false), timerId(-1), loop(Q_NULLPTR) {} inline void enterLoopMSecs(int ms); inline void enterLoop(int secs) { enterLoopMSecs(secs * 1000); } @@ -97,7 +97,7 @@ inline void QTestEventLoop::enterLoopMSecs(int ms) loop = &l; l.exec(); - loop = 0; + loop = Q_NULLPTR; } inline void QTestEventLoop::exitLoop() diff --git a/src/testlib/qtestkeyboard.h b/src/testlib/qtestkeyboard.h index 39520d621f4c28f7f0a1d8fce1dea70a24e19128..82dd6fa098910345e5bfb03f2a0a578ae9c441d4 100644 --- a/src/testlib/qtestkeyboard.h +++ b/src/testlib/qtestkeyboard.h @@ -97,7 +97,7 @@ namespace QTest if (action == Press) { if (modifier & Qt::ShiftModifier) - simulateEvent(window, true, Qt::Key_Shift, 0, QString(), false, delay); + simulateEvent(window, true, Qt::Key_Shift, Qt::KeyboardModifiers(), QString(), false, delay); if (modifier & Qt::ControlModifier) simulateEvent(window, true, Qt::Key_Control, modifier & Qt::ShiftModifier, QString(), false, delay); @@ -220,7 +220,7 @@ namespace QTest if (action == Press) { if (modifier & Qt::ShiftModifier) - simulateEvent(widget, true, Qt::Key_Shift, 0, QString(), false, delay); + simulateEvent(widget, true, Qt::Key_Shift, Qt::KeyboardModifiers(), QString(), false, delay); if (modifier & Qt::ControlModifier) simulateEvent(widget, true, Qt::Key_Control, modifier & Qt::ShiftModifier, QString(), false, delay); diff --git a/src/testlib/qtestmouse.h b/src/testlib/qtestmouse.h index cd3901ae6fed7e50d69ec4a3924ac6425f450cdc..c422a990ef9888ff736e2b9e16922aba5ec04950 100644 --- a/src/testlib/qtestmouse.h +++ b/src/testlib/qtestmouse.h @@ -133,20 +133,24 @@ namespace QTest waitForEvents(); } - inline void mousePress(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, + inline void mousePress(QWindow *window, Qt::MouseButton button, + Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay=-1) { mouseEvent(MousePress, window, button, stateKey, pos, delay); } - inline void mouseRelease(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, + inline void mouseRelease(QWindow *window, Qt::MouseButton button, + Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay=-1) { mouseEvent(MouseRelease, window, button, stateKey, pos, delay); } - inline void mouseClick(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, + inline void mouseClick(QWindow *window, Qt::MouseButton button, + Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay=-1) { mouseEvent(MouseClick, window, button, stateKey, pos, delay); } - inline void mouseDClick(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, + inline void mouseDClick(QWindow *window, Qt::MouseButton button, + Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay=-1) { mouseEvent(MouseDClick, window, button, stateKey, pos, delay); } inline void mouseMove(QWindow *window, QPoint pos = QPoint(), int delay=-1) - { mouseEvent(MouseMove, window, Qt::NoButton, 0, pos, delay); } + { mouseEvent(MouseMove, window, Qt::NoButton, Qt::KeyboardModifiers(), pos, delay); } #ifdef QT_WIDGETS_LIB static void mouseEvent(MouseAction action, QWidget *widget, Qt::MouseButton button, @@ -186,7 +190,7 @@ namespace QTest me = QMouseEvent(QEvent::MouseButtonPress, pos, widget->mapToGlobal(pos), button, button, stateKey); break; case MouseRelease: - me = QMouseEvent(QEvent::MouseButtonRelease, pos, widget->mapToGlobal(pos), button, 0, stateKey); + me = QMouseEvent(QEvent::MouseButtonRelease, pos, widget->mapToGlobal(pos), button, Qt::MouseButton(), stateKey); break; case MouseDClick: me = QMouseEvent(QEvent::MouseButtonDblClick, pos, widget->mapToGlobal(pos), button, button, stateKey); @@ -212,20 +216,24 @@ namespace QTest #endif } - inline void mousePress(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, + inline void mousePress(QWidget *widget, Qt::MouseButton button, + Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay=-1) { mouseEvent(MousePress, widget, button, stateKey, pos, delay); } - inline void mouseRelease(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, + inline void mouseRelease(QWidget *widget, Qt::MouseButton button, + Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay=-1) { mouseEvent(MouseRelease, widget, button, stateKey, pos, delay); } - inline void mouseClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, + inline void mouseClick(QWidget *widget, Qt::MouseButton button, + Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay=-1) { mouseEvent(MouseClick, widget, button, stateKey, pos, delay); } - inline void mouseDClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, + inline void mouseDClick(QWidget *widget, Qt::MouseButton button, + Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay=-1) { mouseEvent(MouseDClick, widget, button, stateKey, pos, delay); } inline void mouseMove(QWidget *widget, QPoint pos = QPoint(), int delay=-1) - { mouseEvent(MouseMove, widget, Qt::NoButton, 0, pos, delay); } + { mouseEvent(MouseMove, widget, Qt::NoButton, Qt::KeyboardModifiers(), pos, delay); } #endif // QT_WIDGETS_LIB } diff --git a/src/testlib/qtestsystem.h b/src/testlib/qtestsystem.h index 50acc6136dbe44e91fa5ac36849b1aeae747c908..f81ede519c46ff7b8d128df393d29afc2873a50b 100644 --- a/src/testlib/qtestsystem.h +++ b/src/testlib/qtestsystem.h @@ -56,7 +56,7 @@ namespace QTest timer.start(); do { QCoreApplication::processEvents(QEventLoop::AllEvents, ms); - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::sendPostedEvents(Q_NULLPTR, QEvent::DeferredDelete); QTest::qSleep(10); } while (timer.elapsed() < ms); } @@ -71,7 +71,7 @@ namespace QTest if (remaining <= 0) break; QCoreApplication::processEvents(QEventLoop::AllEvents, remaining); - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::sendPostedEvents(Q_NULLPTR, QEvent::DeferredDelete); QTest::qSleep(10); } // Try ensuring the platform window receives the real position. @@ -100,7 +100,7 @@ namespace QTest if (remaining <= 0) break; QCoreApplication::processEvents(QEventLoop::AllEvents, remaining); - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::sendPostedEvents(Q_NULLPTR, QEvent::DeferredDelete); QTest::qSleep(10); } return window->isExposed(); diff --git a/src/testlib/qtesttouch.h b/src/testlib/qtesttouch.h index 5dcdca808b0c2dcac46af1c085794aa71e5b4fb6..8e782d17d7afd7bc7026529f338387ebfbea01fb 100644 --- a/src/testlib/qtesttouch.h +++ b/src/testlib/qtesttouch.h @@ -68,21 +68,21 @@ namespace QTest if (commitWhenDestroyed) commit(); } - QTouchEventSequence& press(int touchId, const QPoint &pt, QWindow *window = 0) + QTouchEventSequence& press(int touchId, const QPoint &pt, QWindow *window = Q_NULLPTR) { QTouchEvent::TouchPoint &p = point(touchId); p.setScreenPos(mapToScreen(window, pt)); p.setState(Qt::TouchPointPressed); return *this; } - QTouchEventSequence& move(int touchId, const QPoint &pt, QWindow *window = 0) + QTouchEventSequence& move(int touchId, const QPoint &pt, QWindow *window = Q_NULLPTR) { QTouchEvent::TouchPoint &p = point(touchId); p.setScreenPos(mapToScreen(window, pt)); p.setState(Qt::TouchPointMoved); return *this; } - QTouchEventSequence& release(int touchId, const QPoint &pt, QWindow *window = 0) + QTouchEventSequence& release(int touchId, const QPoint &pt, QWindow *window = Q_NULLPTR) { QTouchEvent::TouchPoint &p = point(touchId); p.setScreenPos(mapToScreen(window, pt)); @@ -97,21 +97,21 @@ namespace QTest } #ifdef QT_WIDGETS_LIB - QTouchEventSequence& press(int touchId, const QPoint &pt, QWidget *widget = 0) + QTouchEventSequence& press(int touchId, const QPoint &pt, QWidget *widget = Q_NULLPTR) { QTouchEvent::TouchPoint &p = point(touchId); p.setScreenPos(mapToScreen(widget, pt)); p.setState(Qt::TouchPointPressed); return *this; } - QTouchEventSequence& move(int touchId, const QPoint &pt, QWidget *widget = 0) + QTouchEventSequence& move(int touchId, const QPoint &pt, QWidget *widget = Q_NULLPTR) { QTouchEvent::TouchPoint &p = point(touchId); p.setScreenPos(mapToScreen(widget, pt)); p.setState(Qt::TouchPointMoved); return *this; } - QTouchEventSequence& release(int touchId, const QPoint &pt, QWidget *widget = 0) + QTouchEventSequence& release(int touchId, const QPoint &pt, QWidget *widget = Q_NULLPTR) { QTouchEvent::TouchPoint &p = point(touchId); p.setScreenPos(mapToScreen(widget, pt)); @@ -143,14 +143,14 @@ namespace QTest private: #ifdef QT_WIDGETS_LIB QTouchEventSequence(QWidget *widget, QTouchDevice *aDevice, bool autoCommit) - : targetWidget(widget), targetWindow(0), device(aDevice), commitWhenDestroyed(autoCommit) + : targetWidget(widget), targetWindow(Q_NULLPTR), device(aDevice), commitWhenDestroyed(autoCommit) { } #endif QTouchEventSequence(QWindow *window, QTouchDevice *aDevice, bool autoCommit) : #ifdef QT_WIDGETS_LIB - targetWidget(0), + targetWidget(Q_NULLPTR), #endif targetWindow(window), device(aDevice), commitWhenDestroyed(autoCommit) { diff --git a/src/testlib/qxctestlogger.mm b/src/testlib/qxctestlogger.mm index 833e566af59f5c767034714b4f23b93d881abd9b..34116a26701dde10abc8a30d058cb351d11563fe 100644 --- a/src/testlib/qxctestlogger.mm +++ b/src/testlib/qxctestlogger.mm @@ -126,7 +126,7 @@ private: if (!([NSDate timeIntervalSinceReferenceDate] > 0)) qFatal("error: Device date '%s' is bad, likely set to update automatically. Please correct.", - [NSDate date].description.UTF8String); + [[NSDate date] description].UTF8String); XCTestDriver *testDriver = nil; if ([QtTestLibWrapper usingTestManager]) diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 9d3cbcd47b423f083e1d46457530f113d7f552b9..9a61cd038a96d841ecfacd8579cd2afd6a94829b 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -4,9 +4,6 @@ TARGET = QtBootstrap QT = CONFIG += internal_module force_bootstrap -# otherwise mingw headers do not declare common functions like putenv -mingw:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x - MODULE_DEFINES = \ QT_BOOTSTRAPPED \ QT_LITE_UNICODE \ @@ -49,6 +46,9 @@ QMAKE_SYNCQT_OPTIONS += -version $$QT_VERSION load(qt_module) +# otherwise mingw headers do not declare common functions like putenv +mingw: CONFIG -= strict_c++ + SOURCES += \ ../../corelib/codecs/qlatincodec.cpp \ ../../corelib/codecs/qtextcodec.cpp \ diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index f253c49995cbffd9746fbef28e444eeeee8b94d7..d036c40f354fcd67588138e42c679ae957d05b32 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -529,7 +529,7 @@ Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocesso return symbols; } -Symbols Preprocessor::macroExpand(Preprocessor *that, Symbols &toExpand, int &index, +void Preprocessor::macroExpand(Symbols *into, Preprocessor *that, const Symbols &toExpand, int &index, int lineNum, bool one, const QSet<QByteArray> &excludeSymbols) { SymbolStack symbols; @@ -539,16 +539,18 @@ Symbols Preprocessor::macroExpand(Preprocessor *that, Symbols &toExpand, int &in sf.excludedSymbols = excludeSymbols; symbols.push(sf); - Symbols result; if (toExpand.isEmpty()) - return result; + return; for (;;) { QByteArray macro; Symbols newSyms = macroExpandIdentifier(that, symbols, lineNum, ¯o); if (macro.isEmpty()) { - result += newSyms; + // not a macro + Symbol s = symbols.symbol(); + s.lineNum = lineNum; + *into += s; } else { SafeSymbols sf; sf.symbols = newSyms; @@ -565,8 +567,6 @@ Symbols Preprocessor::macroExpand(Preprocessor *that, Symbols &toExpand, int &in index = symbols.top().index; else index = toExpand.size(); - - return result; } @@ -576,10 +576,7 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym // not a macro if (s.token != PP_IDENTIFIER || !that->macros.contains(s) || symbols.dontReplaceSymbol(s.lexem())) { - Symbols syms; - syms += s; - syms.last().lineNum = lineNum; - return syms; + return Symbols(); } const Macro ¯o = that->macros.value(s); @@ -600,7 +597,7 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym syms.last().lineNum = lineNum; return syms; } - QList<Symbols> arguments; + QVarLengthArray<Symbols, 5> arguments; while (symbols.hasNext()) { Symbols argument; // strip leading space @@ -653,7 +650,7 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym if (i == macro.symbols.size() - 1 || macro.symbols.at(i + 1).token != PP_HASHHASH) { Symbols arg = arguments.at(index); int idx = 1; - expansion += macroExpand(that, arg, idx, lineNum, false, symbols.excludeSymbols()); + macroExpand(&expansion, that, arg, idx, lineNum, false, symbols.excludeSymbols()); } else { expansion += arguments.at(index); } @@ -726,7 +723,7 @@ void Preprocessor::substituteUntilNewline(Symbols &substituted) while (hasNext()) { Token token = next(); if (token == PP_IDENTIFIER) { - substituted += macroExpand(this, symbols, index, symbol().lineNum, true); + macroExpand(&substituted, this, symbols, index, symbol().lineNum, true); } else if (token == PP_DEFINED) { bool braces = test(PP_LPAREN); next(PP_IDENTIFIER); @@ -1148,7 +1145,7 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) } case PP_IDENTIFIER: { // substitute macros - preprocessed += macroExpand(this, symbols, index, symbol().lineNum, true); + macroExpand(&preprocessed, this, symbols, index, symbol().lineNum, true); continue; } case PP_HASH: diff --git a/src/tools/moc/preprocessor.h b/src/tools/moc/preprocessor.h index 28691d316b3c1eb617b7b33fd6e7b623562bf070..9c81f86f9c4435f44398c68135bcfb4658c297ae 100644 --- a/src/tools/moc/preprocessor.h +++ b/src/tools/moc/preprocessor.h @@ -76,7 +76,7 @@ public: void substituteUntilNewline(Symbols &substituted); static Symbols macroExpandIdentifier(Preprocessor *that, SymbolStack &symbols, int lineNum, QByteArray *macroName); - static Symbols macroExpand(Preprocessor *that, Symbols &toExpand, int &index, int lineNum, bool one, + static void macroExpand(Symbols *into, Preprocessor *that, const Symbols &toExpand, int &index, int lineNum, bool one, const QSet<QByteArray> &excludeSymbols = QSet<QByteArray>()); int evaluateCondition(); diff --git a/src/tools/moc/symbols.h b/src/tools/moc/symbols.h index 13f9ada606eda5f95f29d2b1ec8c05306369c81c..5f442e75ed7295ea0540550e4a387f60c482a95e 100644 --- a/src/tools/moc/symbols.h +++ b/src/tools/moc/symbols.h @@ -113,8 +113,11 @@ struct Symbol Token token; inline QByteArray lexem() const { return lex.mid(from, len); } inline QByteArray unquotedLexem() const { return lex.mid(from+1, len-2); } - inline operator QByteArray() const { return lex.mid(from, len); } inline operator SubArray() const { return SubArray(lex, from, len); } + bool operator==(const Symbol& o) const + { + return SubArray(lex, from, len) == SubArray(o.lex, o.from, o.len); + } QByteArray lex; int from, len; @@ -130,6 +133,7 @@ struct SafeSymbols { QSet<QByteArray> excludedSymbols; int index; }; +Q_DECLARE_TYPEINFO(SafeSymbols, Q_MOVABLE_TYPE); class SymbolStack : public QStack<SafeSymbols> { diff --git a/src/tools/qdoc/codemarker.cpp b/src/tools/qdoc/codemarker.cpp index 9889993fe2d1e41cd692c5dd4dd6b2e65db37ac6..458799fc27095893831e5d1ed9191e790f02a72b 100644 --- a/src/tools/qdoc/codemarker.cpp +++ b/src/tools/qdoc/codemarker.cpp @@ -194,6 +194,22 @@ QString CodeMarker::protect(const QString& str) return marked; } +void CodeMarker::appendProtectedString(QString *output, const QStringRef &str) +{ + int n = str.length(); + output->reserve(output->size() + n * 2 + 30); + const QChar *data = str.constData(); + for (int i = 0; i != n; ++i) { + switch (data[i].unicode()) { + case '&': *output += samp; break; + case '<': *output += slt; break; + case '>': *output += sgt; break; + case '"': *output += squot; break; + default : *output += data[i]; + } + } +} + QString CodeMarker::typified(const QString &string) { QString result; @@ -361,8 +377,7 @@ QString CodeMarker::sortName(const Node *node, const QString* name) else sortNo = QLatin1String("E"); } - return sortNo + nodeName + QLatin1Char(' ') - + QString::number(func->overloadNumber(), 36); + return sortNo + nodeName + QLatin1Char(' ') + QString::number(func->overloadNumber(), 36); } if (node->type() == Node::Class) diff --git a/src/tools/qdoc/codemarker.h b/src/tools/qdoc/codemarker.h index c5226fff040af07717a51b1cbab1ea551399006c..31a9f3a2545de9d4a229e7b134ecf5aeaa428529 100644 --- a/src/tools/qdoc/codemarker.h +++ b/src/tools/qdoc/codemarker.h @@ -163,7 +163,8 @@ public: protected: virtual QString sortName(const Node *node, const QString* name = 0); - QString protect(const QString &string); + static QString protect(const QString &string); + static void appendProtectedString(QString *output, const QStringRef &str); QString taggedNode(const Node* node); QString taggedQmlNode(const Node* node); QString linkTag(const Node *node, const QString& body); diff --git a/src/tools/qdoc/codeparser.cpp b/src/tools/qdoc/codeparser.cpp index 4f80ec80d99666bb762dab403723dadeeb3926b1..92a0d52129c67824d6d64decdde798d6ce1c6273 100644 --- a/src/tools/qdoc/codeparser.cpp +++ b/src/tools/qdoc/codeparser.cpp @@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE #define COMMAND_THREADSAFE Doc::alias(QLatin1String("threadsafe")) #define COMMAND_TITLE Doc::alias(QLatin1String("title")) #define COMMAND_WRAPPER Doc::alias(QLatin1String("wrapper")) +#define COMMAND_NOAUTOLIST Doc::alias(QLatin1String("noautolist")) QList<CodeParser *> CodeParser::parsers; bool CodeParser::showInternal_ = false; @@ -219,8 +220,9 @@ const QSet<QString>& CodeParser::commonMetaCommands() << COMMAND_THREADSAFE << COMMAND_TITLE << COMMAND_WRAPPER - << COMMAND_INJSMODULE; - } + << COMMAND_INJSMODULE + << COMMAND_NOAUTOLIST; + } return commonMetaCommands_; } @@ -317,6 +319,9 @@ void CodeParser::processCommonMetaCommand(const Location& location, location.warning(tr("Command '\\%1' is only meanigfule in '\\module' and '\\qmlmodule'.") .arg(COMMAND_QTVARIABLE)); } + else if (command == COMMAND_NOAUTOLIST) { + node->setNoAutoList(true); + } } /*! diff --git a/src/tools/qdoc/config.cpp b/src/tools/qdoc/config.cpp index 13add7332208bda658ad0e18179e73572941fd77..beb0bae291bdb9fdd755af2fd1af6859f273d4bb 100644 --- a/src/tools/qdoc/config.cpp +++ b/src/tools/qdoc/config.cpp @@ -91,6 +91,7 @@ QString ConfigStrings::OUTPUTENCODING = QStringLiteral("outputencoding"); QString ConfigStrings::OUTPUTLANGUAGE = QStringLiteral("outputlanguage"); QString ConfigStrings::OUTPUTFORMATS = QStringLiteral("outputformats"); QString ConfigStrings::OUTPUTPREFIXES = QStringLiteral("outputprefixes"); +QString ConfigStrings::OUTPUTSUFFIXES = QStringLiteral("outputsuffixes"); QString ConfigStrings::PROJECT = QStringLiteral("project"); QString ConfigStrings::REDIRECTDOCUMENTATIONTODEVNULL = QStringLiteral("redirectdocumentationtodevnull"); QString ConfigStrings::QHP = QStringLiteral("qhp"); @@ -134,6 +135,7 @@ public: QStringList accum; QStringList next; }; +Q_DECLARE_TYPEINFO(MetaStackEntry, Q_MOVABLE_TYPE); /*! Start accumulating values in a list by appending an empty diff --git a/src/tools/qdoc/config.h b/src/tools/qdoc/config.h index 802bcf929dc396d62068aac00c86ed82c37aa17f..8d6a124bd1e1b5fc24c7997984b4c50028f04a7b 100644 --- a/src/tools/qdoc/config.h +++ b/src/tools/qdoc/config.h @@ -203,6 +203,7 @@ struct ConfigStrings static QString OUTPUTLANGUAGE; static QString OUTPUTFORMATS; static QString OUTPUTPREFIXES; + static QString OUTPUTSUFFIXES; static QString PROJECT; static QString REDIRECTDOCUMENTATIONTODEVNULL; static QString QHP; @@ -278,6 +279,7 @@ struct ConfigStrings #define CONFIG_OUTPUTLANGUAGE ConfigStrings::OUTPUTLANGUAGE #define CONFIG_OUTPUTFORMATS ConfigStrings::OUTPUTFORMATS #define CONFIG_OUTPUTPREFIXES ConfigStrings::OUTPUTPREFIXES +#define CONFIG_OUTPUTSUFFIXES ConfigStrings::OUTPUTSUFFIXES #define CONFIG_PROJECT ConfigStrings::PROJECT #define CONFIG_REDIRECTDOCUMENTATIONTODEVNULL ConfigStrings::REDIRECTDOCUMENTATIONTODEVNULL #define CONFIG_QHP ConfigStrings::QHP diff --git a/src/tools/qdoc/cppcodemarker.cpp b/src/tools/qdoc/cppcodemarker.cpp index 43ba29faa03831e89501d2a7e6daed608242c823..868b2492905a7abaf904a646a4e0a30ba7741c0f 100644 --- a/src/tools/qdoc/cppcodemarker.cpp +++ b/src/tools/qdoc/cppcodemarker.cpp @@ -537,11 +537,9 @@ QList<Section> CppCodeMarker::sections(const Aggregate *inner, isSlot = (func->metaness() == FunctionNode::Slot); isSignal = (func->metaness() == FunctionNode::Signal); isStatic = func->isStatic(); - if (func->associatedProperty()) { - if (func->associatedProperty()->status() == Node::Obsolete) { - ++c; - continue; - } + if (func->hasAssociatedProperties() && !func->hasActiveAssociatedProperty()) { + ++c; + continue; } } else if ((*c)->type() == Node::Variable) { @@ -685,7 +683,7 @@ QList<Section> CppCodeMarker::sections(const Aggregate *inner, } else if ((*c)->type() == Node::Function) { FunctionNode *function = static_cast<FunctionNode *>(*c); - if (!function->associatedProperty()) + if (!function->hasAssociatedProperties() || !function->doc().isEmpty()) insert(memberFunctions, function, style, status); } ++c; @@ -895,8 +893,8 @@ QString CppCodeMarker::addMarkUp(const QString &in, ch = (i < (int)code.length()) ? code[i++].cell() : EOF QString code = in; - QStringList out; - QString text; + QString out; + QStringRef text; int braceDepth = 0; int parenDepth = 0; int i = 0; @@ -931,8 +929,7 @@ QString CppCodeMarker::addMarkUp(const QString &in, } else if (keywords.contains(ident)) { tag = QStringLiteral("keyword"); } else if (braceDepth == 0 && parenDepth == 0) { - if (QString(code.unicode() + i - 1, code.length() - (i - 1)) - .indexOf(findFunctionRegExp) == 0) + if (code.indexOf(findFunctionRegExp, i - 1) == i - 1) tag = QStringLiteral("func"); target = true; } @@ -1071,27 +1068,34 @@ QString CppCodeMarker::addMarkUp(const QString &in, } } - text = code.mid(start, finish - start); + text = code.midRef(start, finish - start); start = finish; if (!tag.isEmpty()) { - out << QStringLiteral("<@") << tag; - if (target) - out << QStringLiteral(" target=\"") << text << QStringLiteral("()\""); - out << QStringLiteral(">"); + out += QStringLiteral("<@"); + out += tag; + if (target) { + out += QStringLiteral(" target=\""); + out += text; + out += QStringLiteral("()\""); + } + out += QStringLiteral(">"); } - out << protect(text); + appendProtectedString(&out, text); - if (!tag.isEmpty()) - out << QStringLiteral("</@") << tag << QStringLiteral(">"); + if (!tag.isEmpty()) { + out += QStringLiteral("</@"); + out += tag; + out += QStringLiteral(">"); + } } if (start < code.length()) { - out << protect(code.mid(start)); + appendProtectedString(&out, code.midRef(start)); } - return out.join(QString()); + return out; } /*! diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp index 0468f3691edee5ef02ad00d3a9a8867fa7310325..cab416370a36d493ae06c75373309b3da56810ae 100644 --- a/src/tools/qdoc/cppcodeparser.cpp +++ b/src/tools/qdoc/cppcodeparser.cpp @@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE /* qmake ignore Q_OBJECT */ static bool inMacroCommand_ = false; +static bool parsingHeaderFile_ = false; QStringList CppCodeParser::exampleFiles; QStringList CppCodeParser::exampleDirs; @@ -166,7 +167,9 @@ void CppCodeParser::parseHeaderFile(const Location& location, const QString& fil Tokenizer fileTokenizer(fileLocation, in); tokenizer = &fileTokenizer; readToken(); + parsingHeaderFile_ = true; matchDeclList(qdb_->primaryTreeRoot()); + parsingHeaderFile_ = false; if (!fileTokenizer.version().isEmpty()) qdb_->setVersion(fileTokenizer.version()); in.close(); @@ -250,16 +253,11 @@ void CppCodeParser::doneParsingHeaderFiles() /*! This is called after all the source files (i.e., not the - header files) have been parsed. It traverses the tree to - resolve property links, normalize overload signatures, and - do other housekeeping of the database. + header files) have been parsed. Currently nothing to do. */ void CppCodeParser::doneParsingSourceFiles() { - qdb_->primaryTreeRoot()->normalizeOverloads(); - qdb_->fixInheritance(); - qdb_->resolveProperties(); - qdb_->primaryTreeRoot()->makeUndocumentedChildrenInternal(); + // contents moved to QdocDatabase::resolveIssues() } static QSet<QString> topicCommands_; @@ -886,13 +884,10 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, } } else if (command == COMMAND_OVERLOAD) { - if (node != 0 && node->type() == Node::Function) { - ((FunctionNode *) node)->setOverload(true); - } - else { - doc.location().warning(tr("Ignored '\\%1'") - .arg(COMMAND_OVERLOAD)); - } + if (node && node->isFunction()) + ((FunctionNode *) node)->setOverloadFlag(true); + else + doc.location().warning(tr("Ignored '\\%1'").arg(COMMAND_OVERLOAD)); } else if (command == COMMAND_REIMP) { if (node != 0 && node->parent() && !node->parent()->isInternal()) { @@ -1084,8 +1079,7 @@ bool CppCodeParser::match(int target) readToken(); return true; } - else - return false; + return false; } /*! @@ -1224,8 +1218,9 @@ bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var) dataType->append(previousLexeme()); } else if (match(Tok_void) || match(Tok_int) || match(Tok_char) || - match(Tok_double) || match(Tok_Ellipsis)) + match(Tok_double) || match(Tok_Ellipsis)) { dataType->append(previousLexeme()); + } else { return false; } @@ -1311,36 +1306,71 @@ bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var) return true; } -bool CppCodeParser::matchParameter(FunctionNode *func) +/*! + Parse the next function parameter, if there is one, and + append it to parameter list \a p. Return true if a parameter + is parsed and appended to \a p. Otherwise return false. + */ +bool CppCodeParser::matchParameter(ParsedParameterList& pplist) { - CodeChunk dataType; - QString name; - CodeChunk defaultValue; - + ParsedParameter pp; if (match(Tok_QPrivateSignal)) { - func->setPrivateSignal(); + pp.qPrivateSignal_ = true; + pplist.append(pp); return true; } - if (!matchDataType(&dataType, &name)) { + CodeChunk chunk; + if (!matchDataType(&chunk, &pp.name_)) { return false; } + pp.dataType_ = chunk.toString(); + chunk.clear(); match(Tok_Comment); if (match(Tok_Equal)) { - int parenDepth0 = tokenizer->parenDepth(); - - while (tokenizer->parenDepth() >= parenDepth0 && - (tok != Tok_Comma || - tokenizer->parenDepth() > parenDepth0) && + int pdepth = tokenizer->parenDepth(); + while (tokenizer->parenDepth() >= pdepth && + (tok != Tok_Comma || (tokenizer->parenDepth() > pdepth)) && tok != Tok_Eoi) { - defaultValue.append(lexeme()); + chunk.append(lexeme()); readToken(); } } - func->addParameter(Parameter(dataType.toString(), "", name, defaultValue.toString())); // ### + pp.defaultValue_ = chunk.toString(); + pplist.append(pp); return true; } +/*! + If the current token is any of several function modifiers, + return that token value after reading the next token. If it + is not one of the function modieifer tokens, return -1 but + don\t read the next token. + */ +int CppCodeParser::matchFunctionModifier() +{ + switch (tok) { + case Tok_friend: + case Tok_inline: + case Tok_explicit: + case Tok_static: + case Tok_QT_DEPRECATED: + readToken(); + return tok; + case Tok_QT_COMPAT: + case Tok_QT_COMPAT_CONSTRUCTOR: + case Tok_QT_MOC_COMPAT: + case Tok_QT3_SUPPORT: + case Tok_QT3_SUPPORT_CONSTRUCTOR: + case Tok_QT3_MOC_SUPPORT: + readToken(); + return Tok_QT_COMPAT; + default: + break; + } + return -1; +} + bool CppCodeParser::matchFunctionDecl(Aggregate *parent, QStringList *parentPathPtr, FunctionNode **funcPtr, @@ -1350,25 +1380,44 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent, CodeChunk returnType; QStringList parentPath; QString name; - bool compat = false; - if (match(Tok_friend)) { - return false; - } - match(Tok_explicit); - if (matchCompat()) - compat = true; - bool sta = false; - if (match(Tok_static)) { - sta = true; - if (matchCompat()) - compat = true; + bool matched_QT_DEPRECATED = false; + bool matched_friend = false; + bool matched_static = false; + bool matched_inline = false; + bool matched_explicit = false; + bool matched_compat = false; + + int token = tok; + while (token != -1) { + switch (token) { + case Tok_friend: + matched_friend = true; + break; + case Tok_inline: + matched_inline = true; + break; + case Tok_explicit: + matched_explicit = true; + break; + case Tok_static: + matched_static = true; + break; + case Tok_QT_DEPRECATED: + // no break here. + matched_QT_DEPRECATED = true; + case Tok_QT_COMPAT: + matched_compat = true; + break; + } + token = matchFunctionModifier(); } - FunctionNode::Virtualness vir = FunctionNode::NonVirtual; + + FunctionNode::Virtualness virtuality = FunctionNode::NonVirtual; if (match(Tok_virtual)) { - vir = FunctionNode::NormalVirtual; - if (matchCompat()) - compat = true; + virtuality = FunctionNode::NormalVirtual; + if (!matched_compat) + matched_compat = matchCompat(); } if (!matchDataType(&returnType)) { @@ -1385,8 +1434,8 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent, if (returnType.toString() == "QBool") returnType = CodeChunk("bool"); - if (matchCompat()) - compat = true; + if (!matched_compat) + matched_compat = matchCompat(); if (tok == Tok_operator && (returnType.toString().isEmpty() || @@ -1425,12 +1474,10 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent, else { while (match(Tok_Ident)) { name = previousLexeme(); - /* This is a hack to let QML module identifiers through. */ matchModuleQualifier(name); - matchTemplateAngles(); if (match(Tok_Gulbrandsen)) @@ -1484,68 +1531,113 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent, var->setLocation(location()); var->setLeftType(returnType.left()); var->setRightType(returnType.right()); - if (compat) + if (matched_compat) var->setStatus(Node::Compat); - var->setStatic(sta); + var->setStatic(matched_static); return false; } - if (tok != Tok_LeftParen) { + if (tok != Tok_LeftParen) return false; - } } readToken(); - FunctionNode *func = new FunctionNode(extra.type, parent, name, extra.isAttached); - func->setAccess(access); - func->setLocation(location()); - func->setReturnType(returnType.toString()); - func->setParentPath(parentPath); - func->setTemplateStuff(templateStuff); - if (compat) - func->setStatus(Node::Compat); - - func->setMetaness(metaness_); - if (parent) { - if (name == parent->name()) { - func->setMetaness(FunctionNode::Ctor); - } else if (name.startsWith(QLatin1Char('~'))) { - func->setMetaness(FunctionNode::Dtor); - } - } - func->setStatic(sta); - + // A left paren was seen. Parse the parameters + ParsedParameterList pplist; if (tok != Tok_RightParen) { do { - if (!matchParameter(func)) { + if (!matchParameter(pplist)) return false; - } } while (match(Tok_Comma)); } - if (!match(Tok_RightParen)) { + // The parameters must end with a right paren + if (!match(Tok_RightParen)) return false; - } - func->setConst(match(Tok_const)); + // look for const + bool matchedConst = match(Tok_const); + // look for 0 indicating pure virtual if (match(Tok_Equal) && match(Tok_Number)) - vir = FunctionNode::PureVirtual; - func->setVirtualness(vir); + virtuality = FunctionNode::PureVirtual; + // look for colon indicating ctors which must be skipped if (match(Tok_Colon)) { while (tok != Tok_LeftBrace && tok != Tok_Eoi) readToken(); } + // If no ';' expect a body, which must be skipped. + bool body_expected = false; + bool body_present = false; if (!match(Tok_Semicolon) && tok != Tok_Eoi) { - int braceDepth0 = tokenizer->braceDepth(); - - if (!match(Tok_LeftBrace)) { + body_expected = true; + int nesting = tokenizer->braceDepth(); + if (!match(Tok_LeftBrace)) return false; - } - while (tokenizer->braceDepth() >= braceDepth0 && tok != Tok_Eoi) + // skip the body + while (tokenizer->braceDepth() >= nesting && tok != Tok_Eoi) readToken(); + body_present = true; match(Tok_RightBrace); } + + FunctionNode *func = 0; + bool createFunctionNode = false; + if (parsingHeaderFile_) { + if (matched_friend) { + if (matched_inline) { + // nothing yet + } + if (body_present) { + if (body_expected) { + // nothing yet + } + createFunctionNode = true; + if (parent && parent->parent()) + parent = parent->parent(); + else + return false; + } + } + else + createFunctionNode = true; + } + else + createFunctionNode = true; + + if (createFunctionNode) { + func = new FunctionNode(extra.type, parent, name, extra.isAttached); + if (matched_friend) + access = Node::Public; + func->setAccess(access); + func->setLocation(location()); + func->setReturnType(returnType.toString()); + func->setParentPath(parentPath); + func->setTemplateStuff(templateStuff); + if (matched_compat) + func->setStatus(Node::Compat); + if (matched_QT_DEPRECATED) + func->setStatus(Node::Deprecated); + if (matched_explicit) { /* What can be done? */ } + func->setMetaness(metaness_); + if (parent) { + if (name == parent->name()) + func->setMetaness(FunctionNode::Ctor); + else if (name.startsWith(QLatin1Char('~'))) + func->setMetaness(FunctionNode::Dtor); + } + func->setStatic(matched_static); + func->setConst(matchedConst); + func->setVirtualness(virtuality); + if (!pplist.isEmpty()) { + foreach (const ParsedParameter& pp, pplist) { + if (pp.qPrivateSignal_) + func->setPrivateSignal(); + else + func->addParameter(Parameter(pp.dataType_, "", pp.name_, pp.defaultValue_)); + } + } + } if (parentPathPtr != 0) *parentPathPtr = parentPath; if (funcPtr != 0) diff --git a/src/tools/qdoc/cppcodeparser.h b/src/tools/qdoc/cppcodeparser.h index 31964699a2075533fbb4492d7e3556c9a88bd505..733418e27addfaa595fc6bdfebcdbde292657ec2 100644 --- a/src/tools/qdoc/cppcodeparser.h +++ b/src/tools/qdoc/cppcodeparser.h @@ -51,6 +51,16 @@ class CppCodeParser : public CodeParser { Q_DECLARE_TR_FUNCTIONS(QDoc::CppCodeParser) + struct ParsedParameter { + bool qPrivateSignal_; + QString dataType_; + QString name_; + QString defaultValue_; + ParsedParameter() : qPrivateSignal_(false) { } + }; + friend class QTypeInfo<ParsedParameter>; + typedef QVector<ParsedParameter> ParsedParameterList; + struct ExtraFuncData { Aggregate* root; // Used as the parent. Node::NodeType type; // The node type: Function, etc. @@ -116,7 +126,7 @@ protected: bool matchTemplateAngles(CodeChunk *type = 0); bool matchTemplateHeader(); bool matchDataType(CodeChunk *type, QString *var = 0); - bool matchParameter(FunctionNode *func); + bool matchParameter(ParsedParameterList& pplist); bool matchFunctionDecl(Aggregate *parent, QStringList *parentPathPtr, FunctionNode **funcPtr, @@ -149,6 +159,7 @@ protected: const QString &includeFile, const QString ¯oDef); void createExampleFileNodes(DocumentNode *dn); + int matchFunctionModifier(); protected: QMap<QString, Node::NodeType> nodeTypeMap; @@ -176,6 +187,7 @@ protected: QString exampleNameFilter; QString exampleImageFilter; }; +Q_DECLARE_TYPEINFO(CppCodeParser::ParsedParameter, Q_MOVABLE_TYPE); #define COMMAND_ABSTRACT Doc::alias("abstract") #define COMMAND_CLASS Doc::alias("class") diff --git a/src/tools/qdoc/doc.cpp b/src/tools/qdoc/doc.cpp index f322bd936009b7a1bd387632d83639f552242d27..4ed589454379cc3e2da17b24df1fcc7e51e2b693 100644 --- a/src/tools/qdoc/doc.cpp +++ b/src/tools/qdoc/doc.cpp @@ -308,7 +308,7 @@ public: Doc::Sections granularity_; Doc::Sections section_; // ### QList<Atom*> tableOfContents_; - QList<int> tableOfContentsLevels_; + QVector<int> tableOfContentsLevels_; QList<Atom*> keywords_; QList<Atom*> targets_; QStringMultiMap metaMap_; @@ -3087,7 +3087,7 @@ const QList<Atom *> &Doc::tableOfContents() const return priv->extra->tableOfContents_; } -const QList<int> &Doc::tableOfContentsLevels() const +const QVector<int> &Doc::tableOfContentsLevels() const { priv->constructExtra(); return priv->extra->tableOfContentsLevels_; diff --git a/src/tools/qdoc/doc.h b/src/tools/qdoc/doc.h index 80d47287bb1cfbde9c3ce41ff7c8561bce058083..b064b5878ea8b7916884ea45729e9727ef3b816d 100644 --- a/src/tools/qdoc/doc.h +++ b/src/tools/qdoc/doc.h @@ -168,7 +168,7 @@ public: bool hasKeywords() const; bool hasTargets() const; const QList<Atom *> &tableOfContents() const; - const QList<int> &tableOfContentsLevels() const; + const QVector<int> &tableOfContentsLevels() const; const QList<Atom *> &keywords() const; const QList<Atom *> &targets() const; const QStringMultiMap &metaTagMap() const; @@ -188,6 +188,7 @@ private: DocPrivate *priv; static const Config* config_; }; +Q_DECLARE_TYPEINFO(Doc, Q_MOVABLE_TYPE); typedef QList<Doc> DocList; QT_END_NAMESPACE diff --git a/src/tools/qdoc/doc/examples/examples.qdoc b/src/tools/qdoc/doc/examples/examples.qdoc index 777c869c657d6b69509ec77be7c8d4dc725350c2..ce67dea20e0bc9de121eafb01b6c780091b4b015 100644 --- a/src/tools/qdoc/doc/examples/examples.qdoc +++ b/src/tools/qdoc/doc/examples/examples.qdoc @@ -89,10 +89,9 @@ \title UI Components \brief Basic set of UI components - This is a listing of a list of UI components implemented by QML types. These - - files are available for general import and they are based off the \l{Qt - Quick Code Samples}. + This is a listing of a list of UI components implemented by QML types. + These files are available for general import and they are based off the + \e {Qt Quick Code Samples}. This module is part of the \l{componentset}{UIComponents} example. */ diff --git a/src/tools/qdoc/doc/qdoc-guide/qdoc-guide.qdoc b/src/tools/qdoc/doc/qdoc-guide/qdoc-guide.qdoc index a8c9c73b5cf33802dc314485ae94b8b2fd67b867..af1fa1ba149ab222a2584bf32aa4e9a30f7ae5c0 100644 --- a/src/tools/qdoc/doc/qdoc-guide/qdoc-guide.qdoc +++ b/src/tools/qdoc/doc/qdoc-guide/qdoc-guide.qdoc @@ -112,7 +112,7 @@ Specifying the path to the source directories allow QDoc to find sources and generate documentation. - \code + \badcode sourcedirs = <path to source code> exampledirs = <path to examples directory> imagedirs = <path to image directory> @@ -129,7 +129,7 @@ Likewise, QDoc needs the path to the output directory. The \c outputformats variable determines the type of documentation. These variables should be in separate configuration files to modularize the documentation build. - \code + \badcode outputdir = $SAMPLE_PROJECT/doc/html outputformats = HTML \endcode @@ -144,8 +144,8 @@ the \l{Input and Output Directories}{output} directory. It is also possible to specify extra files that QDoc should export. - \code - extraimages.HTML = extraImage.png \ + \badcode + HTML.extraimages = extraImage.png \ extraImage2.png \endcode @@ -169,7 +169,7 @@ generated documentation into the directory specified by the \c outputdir variable. - \code + \badcode outputformats = HTML outputdir = <path to output directory> \endcode @@ -178,12 +178,12 @@ are located. Typically, the templates directory contains a \c scripts, \c images, and a \c style directory, containing scripts and CSS files. - \code + \badcode HTML.templatedir = <path to templates> \endcode The main configuration variables are: - \code + \badcode HTML.postheader HTML.postpostheader HTML.postheader @@ -210,7 +210,7 @@ documentation, QDoc does not need HTML style templates for generating documentation in DITA XML format. - \code + \badcode outputformats = DITAXML outputdir \endcode @@ -222,7 +222,7 @@ the articles. Other projects can use the links in the index file so that they can link to other articles and API documentation within Qt. - \code + \badcode indexes = $QT_INSTALL_DOCS/html/qt.index $OTHER_PROJECT/html/qt.index \endcode It is possible to specify multiple index files from several projects. @@ -232,7 +232,7 @@ Macros for substituting HTML characters exist and are helpful for generating specific HTML-valid characters. - \code + \badcode macro.pi.HTML = "Π" \endcode The snippet code will replace any instances of \c{\\pi} with \c Π in the @@ -245,18 +245,17 @@ with the QML extension, \c{.qml}, if the extension type is included in the \l{Input and Output Directories}{fileextensions} variable. - Also, the generated HTML files can have a prefix, specified in the QDoc - configuration file. - \code + Also, the generated HTML files can have a prefix and a suffix following the + QML module name, specified in the QDoc configuration file. + \badcode outputprefixes = QML outputprefixes.QML = uicomponents- + outputsuffixes = QML + outputsuffixes.QML = -tp \endcode - The outputprefixes will, for example, prefix QML type HTML filenames. - \code - files: - uicomponents-button.html - uicomponents-scrollbar.html - \endcode + + \b {See also}: \l {outputprefixes-variable}{outputprefixes}, + \l {outputsuffixes-variable}{outputsuffixes}. */ diff --git a/src/tools/qdoc/doc/qdoc-manual-cmdindex.qdoc b/src/tools/qdoc/doc/qdoc-manual-cmdindex.qdoc index 63fcee6469a2e4b0af733663d24dee0d11a6b7e8..d3f188c265cd552f02dbfae4fcccec68d44d0265 100644 --- a/src/tools/qdoc/doc/qdoc-manual-cmdindex.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-cmdindex.qdoc @@ -89,6 +89,7 @@ \li \l {namespace-command} {\\namespace} \li \l {nextpage-command} {\\nextpage} \li \l {newcode-command} {\\newcode} + \li \l {noautolist-command} {\\noautolist} \li \l {nonreentrant-command} {\\nonreentrant} \li \l {note-command} {\\note} \li \l {li-command} {\\o} \span {class="newStuff"} {(deprecated, use \\li)} diff --git a/src/tools/qdoc/doc/qdoc-manual-contextcmds.qdoc b/src/tools/qdoc/doc/qdoc-manual-contextcmds.qdoc index 3bf63214ad404a32dccedf30fe15d66e95ee4b29..a2e851293cd93dc20dd1046a076d1ecd8bd29dca 100644 --- a/src/tools/qdoc/doc/qdoc-manual-contextcmds.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-contextcmds.qdoc @@ -77,7 +77,7 @@ \page 15-qdoc-commands-navigation.html \previouspage Context Commands \contentspage QDoc Manual - \nextpage Reporting Status + \nextpage Status \title Document Navigation @@ -522,7 +522,7 @@ /*! \page 17-qdoc-commands-thread.html - \previouspage Reporting Status + \previouspage Status \contentspage QDoc Manual \nextpage Relating Things @@ -700,8 +700,6 @@ \l{threadsafe-command} {\\threadsafe}. */ - / *! - /*! \page 18-qdoc-commands-relating.html \previouspage Thread Support diff --git a/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc b/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc index 9458d96045bce78d526d8c8fabba0d126e9e6c47..0f9ca463bba3001056978bb88420b76cc2e2e741 100644 --- a/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc @@ -67,6 +67,7 @@ \li \l {li-command} {\\li} \span {class="newStuff"} \li \l {list-command} {\\list} \li \l {meta-command} {\\meta} + \li \l {noautolist-command} {\\noautolist} \li \l {newcode-command} {\\newcode} \li \l {li-command} {\\o} \span {class="newStuff"} {(deprecated, use \\li)} \li \l {note-command} {\\note} @@ -2091,8 +2092,11 @@ {sa-command} {\\sa (see also)} commands. The \\keyword command is like the \l {target-command} {\\target} - command, but stronger. A keyword can be linked from anywhere using - a simple syntax. + command, except when linking to keyword the link goes to the top of + the QDoc comment where the \\keyword appears in. If you want to + create a link target to a \c section unit within a \\page, use + \\target instead. A keyword can be linked from anywhere using a + simple syntax. Keywords must be unique over all the documents processed during the QDoc run. The command uses the rest of the line as its @@ -2178,7 +2182,7 @@ \image happyguy.jpg "Happy guy" Qt provides single-source portability across Microsoft - Windows, Mac OS X, Linux, and all major commercial Unix + Windows, OS X, Linux, and all major commercial Unix variants. It is also available for embedded devices. * / \endcode @@ -2191,7 +2195,7 @@ \image happyguy.jpg image "Happy guy" Qt provides single-source portability across Microsoft - Windows, Mac OS X, Linux, and all major commercial Unix + Windows, OS X, Linux, and all major commercial Unix variants. It is also available for embedded devices. \endquotation @@ -3282,7 +3286,7 @@ / *! Qt::HANDLE is a platform-specific handle type for system objects. This is equivalent to - \c{void *} on Windows and Mac OS X, and to + \c{void *} on Windows and OS X, and to \c{unsigned long} on X11. \warning Using this type is not portable. @@ -3294,7 +3298,7 @@ \quotation Qt::HANDLE is a platform-specific handle type for system objects. This is equivalent to - \c{void *} on Windows and Mac OS X, and to + \c{void *} on Windows and OS X, and to \c{unsigned long} on X11. \warning Using this type is not portable. @@ -3451,6 +3455,20 @@ with the \l {inmodule-command} {\\inmodule} command in its \\class comment. + \section2 \c qmltypesbymodule + + Similar to \c classesbymodule argument, but used for listing the + QML types from the QML module specified with the second argument. + + \note Support for this argument was introduced in QDoc 5.6. + + \section2 \c jstypesbymodule + + Similar to \c classesbymodule argument, but used for listing the + JavaScript types from the module specified with the second argument. + + \note Support for this argument was introduced in QDoc 5.6. + \section2 \c compatclasses The \c compatclasses argument generates a list in alphabetical @@ -3881,6 +3899,28 @@ values obtained from the QDoc configuration file. See \l {Generating DITA XML Output} for details. + \target noautolist-command + \section1 \\noautolist + + The \\noautolist command indicates that the annotated list of C++ + classes or QML types, which is automatically generated at the + bottom of the C++ or QML module page should be omitted, because + the classes or types have been listed manually. This command can + also be used with the \l {group-command}{\\group} command to omit + the list of group members, when they are listed manually. + + The command must stand on its own line. See \l {Qt Sensors QML Types} for + an example. The page is generated from \c {qtsensors5.qdoc}. There you will + find a qdoc comment containing the \c{\qmlmodule} command for the QtSensors + module. The same qdoc comment contains two \c {\annotated-list} commands to + list the QML types in two separate groups. The QML types have been divided + into these two groups because it makes more sense to list them this way than + it does to list them in a single alphabetical list. At the bottom of the + comment, \c {\noautolist} has been used to tell qdoc not to generate the + automatic annotated list. + + This command was introduced in QDoc 5.6. + \target omit-command \section1 \\omit diff --git a/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc b/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc index 226c107e3a012d7776092de553e8409ea4e922a8..2472b0f4fb31925b58c9aedfdad6b489627a30ee 100644 --- a/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc @@ -69,14 +69,14 @@ you to use special characters like '=' and ' \" ' within the value string, for example: - \code + \badcode HTML.postheader = "<a href=\"index.html\">Home</a>" \endcode If an entry spans many lines, use a backslash at the end of every line but the last: - \code + \badcode sourcedirs = kernel \ tools \ widgets @@ -113,6 +113,8 @@ \li \l {manifestmeta-variable} {manifestmeta} \li \l {outputdir-variable} {outputdir} \li \l {outputformats-variable} {outputformats} + \li \l {outputprefixes-variable} {outputprefixes} + \li \l {outputsuffixes-variable} {outputsuffixes} \li \l {sourcedirs-variable} {sourcedirs} \li \l {sources-variable} {sources} \li \l {sources.fileextensions-variable} {sources.fileextensions} @@ -161,7 +163,7 @@ The general syntax is \tt {alias.\e{original-command-name} = \e temporary-command-name}. - \code + \badcode alias.e = i \endcode @@ -198,7 +200,7 @@ for details). By default, no symbol is defined, meaning that code protected with #ifdef...#endif will be ignored. - \code + \badcode defines = Q_QDOC \ QT_.*_SUPPORT \ QT_.*_LIB \ @@ -226,7 +228,7 @@ You can also define preprocessor symbols manually on the command line using the -D option. For example: - \code + \badcode currentdirectory$ qdoc -Dconsoleedition qtgui.qdocconf \endcode @@ -249,7 +251,7 @@ The \c edition variable is always used with a particular edition name to define the modules for that edition: - \code + \badcode edition.Console = QtCore QtNetwork QtSql QtXml edition.Desktop = QtCore QtGui QtNetwork QtOpenGL QtSql QtXml \ QtDesigner QtAssistant Qt3Support QAxContainer \ @@ -263,7 +265,7 @@ {generatelist} command is used to generate a list of classes for this edition: - \code + \badcode \generatelist{classesbyedition Console} \endcode @@ -286,7 +288,7 @@ and accept the first matching file it finds. It will only search in the specified directories, \e not in subdirectories. - \code + \badcode exampledirs = $QTDIR/doc/src \ $QTDIR/examples \ $QTDIR \ @@ -297,7 +299,7 @@ When processing - \code + \badcode \quotefromfile widgets/calculator/calculator.cpp \endcode @@ -306,13 +308,13 @@ there isn't, it will search in the \c exampledirs variable, and first see if there exists a file called - \code + \badcode $QTDIR/doc/src/widgets/calculator/calculator.cpp \endcode If it doesn't, QDoc will continue looking for a file called - \code + \badcode $QTDIR/examples/widgets/calculator/calculator.cpp \endcode @@ -343,7 +345,7 @@ exampledirs} command. But note that if you know the file is listed in the \c examples variable, you don't need to specify its path: - \code + \badcode \quotefromfile calculator.cpp \endcode @@ -362,7 +364,7 @@ The extensions are given as standard wildcard expressions. You can add a file extension to the filter using '+='. For example: - \code + \badcode examples.fileextensions += *.qrc \endcode @@ -378,7 +380,7 @@ For example: - \code + \badcode sourcedirs = src/corelib excludedirs = src/corelib/tmp \endcode @@ -395,7 +397,7 @@ The \c excludefiles variable allows you to specify individual files that should \e{not} be processed by qdoc. - \code + \badcode excludefiles += $QT_CORE_SOURCES/../../src/widgets/kernel/qwidget.h \ $QT_CORE_SOURCES/../../src/widgets/kernel/qwidget.cpp \endcode @@ -427,7 +429,7 @@ reason, these images are specified using the \c extraimages variable: - \code + \badcode extraimages.HTML = qt-logo \endcode @@ -468,7 +470,7 @@ preprocessor symbol is specified within the \c falsehoods variable entry: - \code + \badcode falsehoods = NOTYET \endcode @@ -494,7 +496,7 @@ the header files associated with the \c .cpp source files used in the documentation. - \code + \badcode headerdirs = $QTDIR/src \ $QTDIR/extensions/activeqt \ $QTDIR/extensions/motif \ @@ -536,7 +538,7 @@ files in addition to those located in the directories specified by the \l {headerdirs} {\c headerdirs} variable. - \code + \badcode headers = $QTDIR/src/gui/widgets/qlineedit.h \ $QTDIR/src/gui/widgets/qpushbutton.h \endcode @@ -566,7 +568,7 @@ The extensions are given as standard wildcard expressions. You can add a file extension to the filter using '+='. For example: - \code + \badcode header.fileextensions += *.H \endcode @@ -590,7 +592,7 @@ and accept the first matching file it finds. It will only search in the specified directories, \e not in subdirectories. - \code + \badcode imagedirs = $QTDIR/doc/src/images \ $QTDIR/examples @@ -599,7 +601,7 @@ When processing - \code + \badcode \image calculator-example.png \endcode @@ -608,13 +610,13 @@ variable. If there isn't, it will search in the \c imagedirs variable for: - \code + \badcode $QTDIR/doc/src/images/calculator-example.png \endcode If the file doesn't exist, QDoc will look for a file called - \code + \badcode $QTDIR/examples/calculator-example.png \endcode @@ -636,7 +638,7 @@ files in addition to those located in the directories specified by the \l {imagedirs} {\c imagedirs} variable. - \code + \badcode images = $QTDIR/doc/src/images/calculator-example.png \endcode @@ -660,7 +662,7 @@ The idea is to enable different image format for different output format. - \code + \badcode images.fileextensions.HTML = *.png images.fileextensions.LOUT = *.eps \endcode @@ -679,7 +681,7 @@ You can add a file extension to the filter using '+='. For example: - \code + \badcode images.fileextensions.HTML += *.eps \endcode @@ -696,7 +698,7 @@ specified. However, a possible example of a language variable statement: - \code + \badcode language = Cpp \endcode @@ -715,7 +717,7 @@ appending \c {.DITAXML} to the macro name, the macro is only used when generating DITA XML. - \code + \badcode macro.gui = "\\b" macro.raisedaster.HTML = "<sup>*</sup>" \endcode @@ -741,7 +743,7 @@ The \c naturallanguage variable specifies the natural language used for the documentation generated by qdoc. - \code + \badcode naturallanguage = zh-Hans \endcode @@ -764,7 +766,7 @@ The \c outputdir variable specifies the directory where QDoc will put the generated documentation. - \code + \badcode outputdir = $QTDIR/doc/html \endcode @@ -772,7 +774,7 @@ $QTDIR/doc/html. For example, the documentation of the QWidget class is located in - \code + \badcode $QTDIR/doc/html/qwidget.html \endcode @@ -787,7 +789,7 @@ The \c outputencoding variable specifies the encoding used for the documentation generated by qdoc. - \code + \badcode outputencoding = UTF-8 \endcode @@ -814,21 +816,48 @@ Currently, QDoc only supports the HTML format. It is also the default format, and doesn't need to be specified. - \target outputprefixes + \target outputprefixes-variable \section1 outputprefixes The \c outputprefixes variable specifies a mapping between types of files and the prefixes to prepend to the HTML file names in the generated documentation. - \code - outputprefixes = QML + \badcode + outputprefixes = QML JS outputprefixes.QML = uicomponents- + outputprefixes.JS = uicomponents- \endcode By default, files containing the API documentation for QML types - are prefixed with "qml-". In the above example, the - prefix \c "uicomponents" is used instead. + are prefixed with "qml-", and javaScript types with "js-". In the + above example, the prefix \c "uicomponents" is used instead for + both. + + The output prefix is applied to file names for documentation on + QML and JS types. + + \target outputsuffixes-variable + \section1 outputsuffixes + + The \c outputsuffixes variable specifies a mapping between types of + files and module name suffixes to append to the HTML file names. + + \badcode + outputsuffixes = QML + outputsuffixes.QML = -tp + \endcode + + Given a QML module name \e FooBar and the default + \l {outputprefixes-variable}{output prefix} ("qml-"), the file name of + the generated HTML page for a QML type \e FooWidget would be + \c qml-foobar-tp-foowidget.html. + + By default, no suffix is used. The output suffix, if defined, is applied + to file names for documentation on QML and JS types, and their respective + module pages. + + The \c outputsuffixes variable was introduced in QDoc 5.6. \target qhp-variable \section1 qhp @@ -845,7 +874,7 @@ The \c sourcedirs variable specifies the directories containing the \c .cpp or \c .qdoc files used in the documentation. - \code + \badcode sourcedirs += .. \ ../../../examples/gui/doc/src \endcode @@ -881,7 +910,7 @@ The \c sourceencoding variable specifies the encoding used for the source code and documentation. - \code + \badcode sourceencoding = UTF-8 \endcode @@ -906,7 +935,7 @@ files in addition to those located in the directories specified by the \l {sourcedirs-variable} {sourcedirs} variable. - \code + \badcode sources = $QTDIR/src/gui/widgets/qlineedit.cpp \ $QTDIR/src/gui/widgets/qpushbutton.cpp \endcode @@ -935,7 +964,7 @@ The extensions are given as standard wildcard expressions. You can add a file extension to the filter using '+='. For example: - \code + \badcode sources.fileextensions += *.CC \endcode @@ -952,7 +981,7 @@ output. The warnings are specified using standard wildcard expressions. - \code + \badcode spurious = "Cannot find .*" \ "Missing .*" \endcode @@ -961,8 +990,8 @@ will not be part of the output when running QDoc. For example would the following warning be omitted from the output: - \code - qt-4.0/src/opengl/qgl_mac.cpp:156: Missing parameter name + \badcode + src/opengl/qgl_mac.cpp:156: Missing parameter name \endcode \target syntaxhighlighting @@ -972,7 +1001,7 @@ perform syntax highlighting on source code quoted in the documentation it generates. - \code + \badcode syntaxhighlighting = true \endcode @@ -984,7 +1013,7 @@ The \c tabsize variable defines the size of a tab character. - \code + \badcode tabsize = 4 \endcode @@ -1003,8 +1032,8 @@ The \c version variable specifies the version number of the documented software. - \code - version = 4.0.1 + \badcode + version = 5.6.0 \endcode When a version number is specified (using the \tt{\l version} or @@ -1023,13 +1052,13 @@ The \c versionsym variable specifies a C++ preprocessor symbol that defines the version number of the documented software. - \code + \badcode versionsym = QT_VERSION_STR \endcode QT_VERSION_STR is defined in qglobal.h as follows - \code + \badcode #define QT_VERSION_STR "4.0.1" \endcode @@ -1054,42 +1083,106 @@ \section1 Overview - Starting with Qt 4.4, Qt Assistant uses a different system for managing - Qt documentation that requires QDoc to generate inventories of files in a - format that is similar to the old style DCF format, but with additional - features. + Qt Assistant uses a system for managing Qt documentation that requires + QDoc to generate inventories of files in a format that is similar to the + old style DCF format, but with additional features. - Instead of hard-coding information about the documentation sets for Qt, QDoc allows configuration variables to be used to specify which pages are to be used in each documentation set it generates. These are specified as - subvariables of the \c qch variable with each set declared using a unique + subvariables of the \c qhp variable with each set declared using a unique identifier as a subvariable. - For example, the configuration file for the Qt documentation defines a - \c Qt documentation set by specifying information about the set as - subvariables with the \c{qhp.Qt} prefix: - - \code - qhp.Qt.file = qt.qhp - qhp.Qt.namespace = org.qt-project.qtcore.$QT_VERSION_TAG - qhp.Qt.virtualFolder = qdoc - qhp.Qt.indexTitle = Qt Reference Documentation - qhp.Qt.indexRoot = - qhp.Qt.extraFiles = classic.css images/qt-logo.png - qhp.Qt.filterAttributes = qt 4.4.0 qtrefdoc - qhp.Qt.customFilters.Qt.name = Qt 4.4.0 - qhp.Qt.customFilters.Qt.filterAttributes = qt 4.4.0 - qhp.Qt.subprojects = classes overviews examples - qhp.Qt.subprojects.classes.title = Classes - qhp.Qt.subprojects.classes.indexTitle = Qt's Classes - qhp.Qt.subprojects.classes.selectors = class - qhp.Qt.subprojects.overviews.title = Overviews - qhp.Qt.subprojects.overviews.indexTitle = All Overviews and HOWTOs - qhp.Qt.subprojects.overviews.selectors = fake:page,group,module - qhp.Qt.subprojects.examples.title = Tutorials and Examples - qhp.Qt.subprojects.examples.indexTitle = Qt Examples - qhp.Qt.subprojects.examples.selectors = fake:example - \endcode + For example, the configuration file for the Qt Quick documentation set + specifies information about the set as subvariables with the + \c{qhp.QtQuick} prefix: + + \badcode + qhp.projects = QtQuick + + qhp.QtQuick.file = qtquick.qhp + qhp.QtQuick.namespace = org.qt-project.qtquick.$QT_VERSION_TAG + qhp.QtQuick.virtualFolder = qtquick + qhp.QtQuick.indexTitle = Qt Quick + qhp.QtQuick.indexRoot = + + qhp.QtQuick.filterAttributes = qtquick $QT_VERSION qtrefdoc + qhp.QtQuick.customFilters.Qt.name = QtQuick $QT_VERSION + qhp.QtQuick.customFilters.Qt.filterAttributes = qtquick $QT_VERSION + + qhp.QtQuick.subprojects = qmltypes classes examples + + qhp.QtQuick.subprojects.qmltypes.title = QML Types + qhp.QtQuick.subprojects.qmltypes.indexTitle = Qt Quick QML Types + qhp.QtQuick.subprojects.qmltypes.selectors = qmlclass + qhp.QtQuick.subprojects.qmltypes.sortPages = true + + qhp.QtQuick.subprojects.classes.title = Classes + qhp.QtQuick.subprojects.classes.title = C++ Classes + qhp.QtQuick.subprojects.classes.indexTitle = Qt Quick C++ Classes + qhp.QtQuick.subprojects.classes.selectors = class fake:headerfile + qhp.QtQuick.subprojects.classes.sortPages = true + + qhp.QtQuick.subprojects.examples.title = Examples + qhp.QtQuick.subprojects.examples.indexTitle = Qt Quick Examples and Tutorials + qhp.QtQuick.subprojects.examples.selectors = fake:example + \endcode + + The documentation set may include one or more subprojects, which are added + to the table of contents under the name specified by \c title. The page + in the documentation referred to by the \c indexTitle acts as the index page + for the subproject. The page types to list under the subproject are specified + by \c selectors. The entries are alphabetically sorted if \c sortPages is set + to \c true. + + \section2 Using Selectors + + The \c selectors property specifies which page types are listed under the + table of contents entry for a subproject. Multiple selectors can be listed, + separated by whitespace. + + \table + \header \li Selector \li Description + \row \li \c namespace \li Namespaces + \row \li \c class \li Classes + \row \li \c qmltype \li QML Types + \row \li \c qmlclass \li Alias for \c qmltype. + \row \li \c module \li C++ Modules + \row \li \c qmlmodule \li QML Modules + \row \li \c doc[:subtype] \li Documentation pages with a specified + \c subtype. Multiple subtypes can be + listed as a comma-separated list. + \row \li \c fake \li Alias for \c doc. + \row \li \c group[:groupname] \li Documentation pages for members of a + specified group, as added using the + \l {ingroup-command} + {\\ingroup} groupname command. + Multiple group names can be listed as + a comma-separated list. + (Introduced in QDoc 5.6). + \endtable + + Available subtypes for the \c doc selector: + + \table + \header \li Subtype \li Description + \row \li \c example \li Examples + \row \li \c headerfile \li Header files + \row \li \c page \li Documentation pages defined with the + \l {page-command} {\\page} command. + \endtable + + For example, the following configuration would select example pages and + pages that include the \c {\ingroup tutorials} command: + + \badcode + qhp.QtQuickControls.subprojects = examples + qhp.QtQuickControls.subprojects.examples.title = Examples and Tutorials + qhp.QtQuickControls.subprojects.examples.indexTitle = Qt Quick Controls Examples + qhp.QtQuickControls.subprojects.examples.selectors = doc:example group:tutorials + qhp.QtQuickControls.subprojects.examples.sortPages = true + \endcode + + \section2 Adding Table of Contents To create a table of contents for a manual, create a subproject with a \c{type} property and set it to \c{manual}. The page in the documentation @@ -1101,7 +1194,7 @@ subproject for its documentation, including all the documentation in a single manual: - \code + \badcode qhp.QtCreator.subprojects = manual qhp.QtCreator.subprojects.manual.title = Qt Creator Manual qhp.QtCreator.subprojects.manual.indexTitle = Qt Creator Manual @@ -1133,7 +1226,7 @@ Cpp.ignoredirectives} variables, non-standard constructs (typically macros) can result in erroneous documentation. - \code + \badcode Cpp.ignoredirectives = Q_DECLARE_INTERFACE \ Q_DECLARE_OPERATORS_FOR_FLAGS \ Q_DECLARE_PRIVATE \ @@ -1187,7 +1280,7 @@ In \l qtgui.qdocconf: - \code + \badcode Cpp.ignoretokens = QAXFACTORY_EXPORT \ QM_EXPORT_CANVAS \ ... @@ -1250,15 +1343,12 @@ quotation marks. Note that if the value spans several lines, each line needs to be enclosed by quotation marks. - \code + \badcode HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \ ... "</tr></table></div></address>" \endcode - The complete variable entry provides the standard footer of the - \l {http://doc.qt.digia.com/4.0/index.html} {Qt Reference Documentation}. - \target HTML.postheader-variable \section1 HTML.postheader @@ -1272,7 +1362,7 @@ marks. Note that if the value spans several lines, each line needs to be enclosed by quotation marks. - \code + \badcode HTML.postheader = "<table border=\"0\"..." \ ... "<img src=\"images/qt-logo.png\" \ @@ -1296,7 +1386,7 @@ marks. Note that if the value spans several lines, each line needs to be enclosed by quotation marks. - \code + \badcode HTML.style = "h3.fn,span.fn" \ "{ margin-left: 1cm; text-indent: -1cm; }\n" \ "a:link { color: #004faf; text-decoration: none }\n" \ @@ -1307,10 +1397,6 @@ "body { background: #ffffff; color: black; }" \endcode - provides the HTML style for the \l - {http://doc.qt.digia.com/4.0/index.html} {Qt Reference - Documentation}. - \target HTML.stylesheets-variable \section1 HTML.stylesheets @@ -1322,7 +1408,7 @@ has been generated. Typically, it is only necessary to define a single stylesheet for any set of documentation; for example: - \code + \badcode HTML.stylesheets = classic.css \endcode @@ -1371,7 +1457,7 @@ Reference documentation, you need to specify the associated index file: - \code + \badcode indexes = $QTDIR/doc/html/qt.index \endcode @@ -1386,7 +1472,7 @@ The project's name is used to form a file name for the associated project's \e index file. - \code + \badcode project = QtCreator \endcode @@ -1406,7 +1492,7 @@ the base URL when constructing links to classes, functions, and other things listed in the index. - \code + \badcode project = Qt description = Qt Reference Documentation url = http://doc.qt.io/qt-4.8/ @@ -1429,7 +1515,7 @@ For example, \l qtgui.qdocconf (the configuration file for Qt) contains the following variable definitions: - \code + \badcode project = Qt description = Qt Reference Documentation url = http://doc.qt.io/qt-4.8/ @@ -1461,7 +1547,7 @@ A manifest file has the following structure: - \code + \badcode <?xml version="1.0" encoding="UTF-8"?> <instructionals module="QtGui"> <examples> @@ -1503,7 +1589,7 @@ Example: - \code + \badcode manifestmeta.filters = highlighted sql webkit global manifestmeta.highlighted.names = "QtGui/Analog Clock Window Example" \ @@ -1539,7 +1625,7 @@ In your configuration file, set your \c {outputformats} variable to \c {DITAXML}, and send the output to an appropriate directory: - \code + \badcode outputdir = $QTDIR/doc/ditaxml outputformats = DITAXML \endcode @@ -1547,7 +1633,7 @@ And include these macros in your configuration file to prevent QDoc from doing some escaping that doesn't validate in XML: - \code + \badcode macro.aacute.DITAXML = "á" macro.Aring.DITAXML = "Å" macro.aring.DITAXML = "å" @@ -1571,7 +1657,7 @@ You can also set default values for some of the tags in the DITA \c {<prolog>} and \c {<metadata>} elements: - \code + \badcode dita.metadata.default.author = Qt Development Frameworks dita.metadata.default.permissions = all dita.metadata.default.publisher = Qt Project diff --git a/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc b/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc index 4ebe0e6cb047cf45b40186d7531bad326670b969..306fc40cb85c644f6162d789c0aea44a62f6e109 100644 --- a/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc @@ -851,6 +851,9 @@ \endquotation + The \l {noautolist-command} {\\noautolist} command can be used here + to omit the automatically generated list of classes at the end. + See also \l {inmodule-command} {\\inmodule} \target namespace-command @@ -947,7 +950,7 @@ Qt is a C++ toolkit for cross-platform GUI application development. Qt provides single-source - portability across Microsoft Windows, Mac OS X, Linux, + portability across Microsoft Windows, OS X, Linux, and all major commercial Unix variants. Qt provides application developers with all the @@ -1372,6 +1375,9 @@ The \l{componentset}{UIComponents} example demonstrates proper usage of QDoc commands to document QML types and QML modules. + The \l {noautolist-command} {\\noautolist} command can be used here + to omit the automatically generated list of types at the end. + \target instantiates-command \section1 \\instantiates diff --git a/src/tools/qdoc/doc/qdoc-manual.qdoc b/src/tools/qdoc/doc/qdoc-manual.qdoc index c0a1afaa52b417744c05eaf25be5da6a8281d070..a0e35c2e9c4d81d7d093fa8ea8e6bd0fea5488a8 100644 --- a/src/tools/qdoc/doc/qdoc-manual.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual.qdoc @@ -39,7 +39,7 @@ \li \l {Context Commands} \list \li \l {Document Navigation} - \li \l {Reporting Status} + \li \l {Status} \li \l {Thread Support} \li \l {Relating Things} \li \l {Grouping Things} diff --git a/src/tools/qdoc/doc/qdoc-minimum-qdocconf.qdoc b/src/tools/qdoc/doc/qdoc-minimum-qdocconf.qdoc index 77d252b24c9b5a477bee09afbe85643b2d9dbc84..66ceed4a3d4ba175bf19eaaf1e131fd5cddfb8f0 100644 --- a/src/tools/qdoc/doc/qdoc-minimum-qdocconf.qdoc +++ b/src/tools/qdoc/doc/qdoc-minimum-qdocconf.qdoc @@ -27,7 +27,7 @@ /*! \page qdoc-minimum-qdocconf.html \target minimal-qdocconf -\title A minimal qdocconf file +\title A Minimal qdocconf File \brief Describes a minimal .qdocconf file @@ -37,8 +37,8 @@ will discuss every statement in the qdocconf file. Each line from the qdocconf file is first quoted. Below each statement you will find the meaning. -\code - #include(compat.qdocconf) +\badcode + include(compat.qdocconf) outputdir = html headerdirs = . sourcedirs = . @@ -46,10 +46,10 @@ find the meaning. imagedirs = ./images \endcode -\title Notes +\b Notes: -\code - #include(compat.qdocconf) +\badcode + include(compat.qdocconf) \endcode For compatibility with older versions of Qt, it is recommended @@ -61,32 +61,29 @@ to include compat.qdocconf. QDoc will put the documentation generated in the html directory. -\code +\badcode headerdirs = . \endcode The header file associated with the \e .cpp source files can be found in the current directory. -\code +\badcode sourcedirs = . \endcode The current directory is the directory containing the source files: the \e .cpp and \e .qdoc files used in the documentation. -\code +\badcode exampledirs = . \endcode The source code of the example files can be found in the current directory. -\code +\badcode imagedirs = ./images \endcode -The image files can be found in the underlying directory "images". - -\note Please take care with this minimal qdocconf file. Using it in the wrong directory -could cause qdoc to include a large number of files. +The image files can be found in the underlying directory \c images. */ diff --git a/src/tools/qdoc/doc/qtgui-qdocconf.qdoc b/src/tools/qdoc/doc/qtgui-qdocconf.qdoc index 3dcd2482d6d3a40781a3117082adb7d3be3d2393..d90584ff4246b65a5d0f24ddc374f95607a31b55 100644 --- a/src/tools/qdoc/doc/qtgui-qdocconf.qdoc +++ b/src/tools/qdoc/doc/qtgui-qdocconf.qdoc @@ -30,20 +30,20 @@ \page qtgui-qdocconf.html \title qtgui.qdocconf with Comments -\brief A walkthrough of a typical qdocconf file +\brief A walkthrough of a typical qdocconf file. This document goes through a typical Qt 5 qdocconf file. The contents is taken from Qt GUI's \e qtgui.qdocconf file. -Below you will find the full contents of qtgui.qdocconf. The subsequent section will discuss +Below you will find the full contents of \c qtgui.qdocconf. The subsequent section will discuss every statement in the qdocconf file. -\code +\badcode include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) project = QtGui description = Qt GUI Reference Documentation - url = http://doc.qt.io/qt-$QT_VER/qtgui-index.html + url = http://doc.qt.io/qt-5 version = $QT_VERSION examplesinstallpath = gui @@ -95,20 +95,20 @@ every statement in the qdocconf file. \title Qtgui.qdocconf with notes -\code +\badcode include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) \endcode QDoc inherits the default templates, macros, and settings from the directory specified from the \c $QT_INSTALL_DOCS variable. \c qmake prints the value of the variable. -\code +\badcode qmake -query \endcode -\sa include +\b {See also}: \l {include}. -\code +\badcode project = QtGui \endcode @@ -116,22 +116,22 @@ The \c project variable sets the name of the QDoc build. This name is also used to form the index file, which, in this case, will be \e qtgui.index. The name of the index file doesn't adopt the uppercase letters of the project name. -\sa project +\b {See also}: \l {project}. -\code +\badcode description = Qt GUI Reference Documentation \endcode A short description of the project concerned. -\code - url = http://doc.qt.io/qt-$QT_VER/qtgui-index.html +\badcode + url = http://doc.qt.io/qt-5 \endcode The \c url variable holds the base url of the project. The URL is stored in the generated index file for the project. -QDoc will use this as the base URL when constructing links +QDoc will use this as the base URL when constructing external links to content listed in the index. \note QDoc omits this value when the -installdir argument @@ -139,27 +139,29 @@ is specified when running QDoc. \keyword examplesinstallpath -\code +\badcode examplesinstallpath = gui \endcode -This \e examplesinstallpath variable indicates that the examples will be installed -in the \e gui directory under the parent examples directory (for Qt, this is -$QT_INSTALL_EXAMPLES). +This \c examplesinstallpath variable indicates that the examples will be +installed in the \e gui directory under the parent examples directory +(for Qt, this is $QT_INSTALL_EXAMPLES). -\note The examplepath variable has to match the example directory specified in exampledirs. -\sa exampledirs +\note The examplepath variable has to match the example directory specified in + \c exampledirs. -\code +\b {See also}: \l {exampledirs}. + +\badcode qhp.projects = QtGui qhp.QtGui.file = qtgui.qhp \endcode -The following parameters are for creating a QHP file (\e .qhp). The qhelpgenerator -program can convert the QHP file into a QCH file (\e .qch), which can be opened in -Qt Assistant or Qt Creator. +The following parameters are for creating a QHP file (\e .qhp). The +\e qhelpgenerator program can convert the QHP file into a QCH file (\e .qch), +which can be opened in Qt Assistant or Qt Creator. -\code +\badcode qhp.QtGui.namespace = org.qt-project.qtgui.$QT_VERSION_TAG \endcode @@ -167,32 +169,32 @@ A unique identifier which enables QHelpEngine to retrieve the helpfile from a given link. This namespace is also used as a base url for links to the helpfile. -\code +\badcode qhp.QtGui.virtualFolder = qtgui \endcode Virtual folders group documentation together into a single location. A -virtual folder will become the root directory of all files referenced in a -compressed help file. +virtual folder will become the root directory of all files referenced in +a compressed help file. -When two manuals are located in the same virtual folder, it is possible to refer - to sections of the other manual using relative paths. -The virtual folder tag is mandatory and the folder must not contain any '/'. +When two manuals are located in the same virtual folder, it is possible to +refer to sections of the other manual using relative paths. The virtual +folder tag is mandatory and the folder must not contain any '/'. -\code - qhp.QtGui.indexTitle = Qt GUI the title of the page that has the contents +\badcode + qhp.QtGui.indexTitle = Qt GUI \endcode This is the title of the page that has the contents. -\code - qhp.QtGui.indexRoot = to be checked +\badcode + qhp.QtGui.indexRoot = \endcode Specifies the title of the root (namespace) page to generate the documentation for. Typically defined as an empty string. -\code +\badcode qhp.QtGui.filterAttributes = qtgui $QT_VERSION qtrefdoc qhp.QtGui.customFilters.Qt.name = QtGui $QT_VERSION qhp.QtGui.customFilters.Qt.filterAttributes = qtgui $QT_VERSION @@ -206,7 +208,7 @@ filter in its \gui{Filtered by} drop-down list. Only the documentation sets that have their filter attributes match the attributes of the selected custom filter will be shown. -\code +\badcode qhp.QtGui.subprojects = classes qhp.QtGui.subprojects.classes.title = C++ Classes qhp.QtGui.subprojects.classes.indexTitle = Qt GUI C++ Classes @@ -216,34 +218,22 @@ for this project. In this example, the subproject, which is displayed in the Assistant's sidebar, is named "C++ Classes" and its index is the page titled "QT GUI C++ Classes". -\code +\badcode qhp.QtGui.subprojects.classes.selectors = class fake:headerfile \endcode -Lists all headerfiles. - -A ‘fake’ type specifies a generic documentation node, and is followed by -a c\ : and a \e subtype specifier. - -Possible values: -\code - example - headerfile - file - group - module - page - externalpage - qmlclass - qmlpropertygroup - qmlbasictype +Lists all C++ classes and header files. + +See \l {Creating Help Project Files} for more information. + +\badcode + tagfile = ../../../doc/qtgui/qtgui.tags \endcode -tagfile = ../../../doc/qtgui/qtgui.tags This specifies the Doxygen tag file that needs to be written when the html is generated by QDoc. -\code +\badcode depends += \ qtcore \ qtnetwork \ @@ -259,14 +249,14 @@ Specifies the modules QDoc needs to load for generating output for Qt GUI. QDoc loads the index files for all modules listed in the depends statement in order to enable linking to pages in these modules. -\code +\badcode headerdirs += .. \endcode Add the parent directory to the list of directories containing the header files associated with the \e .cpp source files. -\code +\badcode sourcedirs += .. \ ../../../examples/gui/doc/src \endcode @@ -274,7 +264,7 @@ associated with the \e .cpp source files. Add the specified directories to the list of directories containing the \e .cpp and \e .qdoc files used in the documentation. -\code +\badcode excludedirs = ../../../examples/gui/doc/src/tmp \endcode @@ -283,14 +273,13 @@ by qdoc, even if the same directories are included by the \c sourcedirs or \c he variables. When executed, QDoc will ignore the directories listed. -\sa excludefiles +\b {See also}: \l {excludefiles}. -\code +\badcode exampledirs += ../../../examples/gui \ snippets \endcode -\sa {examples-variable}{examples} -\sa examplesinstallpath +\b {See also}: \l {examples-variable}{examples}, \l {examplesinstallpath}. Add the two directories specified to the list of directories containing the source code of the example files. @@ -299,7 +288,7 @@ If QDoc encounters both \c exampledirs and \c examples, it will look first in th \c examples directory. QDoc will accept the first matching file it finds. QDoc will search in the directories specified, not in their subdirectories. -\code +\badcode imagedirs += images \ ../../../examples/gui/doc/images \ ../../../doc/src/images \ diff --git a/src/tools/qdoc/generator.cpp b/src/tools/qdoc/generator.cpp index 7b7fd45f21cddf73f840c6bc42340f03eb9de8da..9f722abe9b4a5e412191a79f69947dc886c68092 100644 --- a/src/tools/qdoc/generator.cpp +++ b/src/tools/qdoc/generator.cpp @@ -63,6 +63,7 @@ QString Generator::outSubdir_; QStringList Generator::outFileNames_; QSet<QString> Generator::outputFormats; QHash<QString, QString> Generator::outputPrefixes; +QHash<QString, QString> Generator::outputSuffixes; QString Generator::project_; QStringList Generator::scriptDirs; QStringList Generator::scriptFiles; @@ -329,21 +330,21 @@ QString Generator::fileBase(const Node *node) const else if (node->isQmlType() || node->isQmlBasicType() || node->isJsType() || node->isJsBasicType()) { base = node->name(); - if (!node->logicalModuleName().isEmpty()) { - base.prepend(node->logicalModuleName() + QLatin1Char('-')); - } /* To avoid file name conflicts in the html directory, - we prepend a prefix (by default, "qml-") to the file name of QML - element doc files. + we prepend a prefix (by default, "qml-") and an optional suffix + to the file name. The suffix, if one exists, is appended to the + module name. */ - if (node->isQmlType() || node->isQmlBasicType()) - base.prepend(outputPrefix(QLatin1String("QML"))); - else - base.prepend(outputPrefix(QLatin1String("JS"))); + if (!node->logicalModuleName().isEmpty()) { + base.prepend(node->logicalModuleName() + + outputSuffix(node) + + QLatin1Char('-')); + } + base.prepend(outputPrefix(node)); } else if (node->isCollectionNode()) { - base = node->name(); + base = node->name() + outputSuffix(node); if (base.endsWith(".html")) base.truncate(base.length() - 5); @@ -356,7 +357,7 @@ QString Generator::fileBase(const Node *node) const else if (node->isModule()) { base.append("-module"); } - // Why not add "-group" for gropup pages? + // Why not add "-group" for group pages? } else { const Node *p = node; @@ -519,9 +520,7 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir) else if (node->isQmlType() || node->isQmlBasicType() || node->isJsType() || node->isJsBasicType()) { QString fb = fileBase(node); - if (fb.startsWith(Generator::outputPrefix(QLatin1String("QML")))) - return fb + QLatin1Char('.') + currentGenerator()->fileExtension(); - else if (fb.startsWith(Generator::outputPrefix(QLatin1String("JS")))) + if (fb.startsWith(outputPrefix(node))) return fb + QLatin1Char('.') + currentGenerator()->fileExtension(); else { QString mq; @@ -529,10 +528,7 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir) mq = node->logicalModuleName().replace(QChar('.'),QChar('-')); mq = mq.toLower() + QLatin1Char('-'); } - QLatin1String prefix = QLatin1String("QML"); - if (node->isJsType() || node->isJsBasicType()) - prefix = QLatin1String("JS"); - return fdl+ Generator::outputPrefix(prefix) + mq + fileBase(node) + + return fdl + outputPrefix(node) + mq + fileBase(node) + QLatin1Char('.') + currentGenerator()->fileExtension(); } } @@ -564,20 +560,19 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir) break; case Node::Function: { - const FunctionNode *functionNode = - static_cast<const FunctionNode *>(node); + const FunctionNode *fn = static_cast<const FunctionNode *>(node); - if (functionNode->metaness() == FunctionNode::Dtor) - anchorRef = "#dtor." + functionNode->name().mid(1); + if (fn->metaness() == FunctionNode::Dtor) + anchorRef = "#dtor." + fn->name().mid(1); - else if (functionNode->associatedProperty()) - return fullDocumentLocation(functionNode->associatedProperty()); + else if (fn->hasOneAssociatedProperty() && fn->doc().isEmpty()) + return fullDocumentLocation(fn->firstAssociatedProperty()); - else if (functionNode->overloadNumber() > 1) - anchorRef = QLatin1Char('#') + cleanRef(functionNode->name()) - + QLatin1Char('-') + QString::number(functionNode->overloadNumber()); + else if (fn->overloadNumber() > 0) + anchorRef = QLatin1Char('#') + cleanRef(fn->name()) + + QLatin1Char('-') + QString::number(fn->overloadNumber()); else - anchorRef = QLatin1Char('#') + cleanRef(functionNode->name()); + anchorRef = QLatin1Char('#') + cleanRef(fn->name()); break; } /* @@ -840,9 +835,8 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) } else if (!(*a).isEmpty() && !documentedParams.contains(*a)) { bool needWarning = (func->status() > Node::Obsolete); - if (func->overloadNumber() > 1) { - FunctionNode *primaryFunc = - func->parent()->findFunctionNode(func->name()); + if (func->overloadNumber() > 0) { + FunctionNode *primaryFunc = func->parent()->findFunctionNode(func->name()); if (primaryFunc) { foreach (const Parameter ¶m, primaryFunc->parameters()) { @@ -1806,15 +1800,24 @@ void Generator::initialize(const Config &config) project_ = config.getString(CONFIG_PROJECT); - QStringList prefixes = config.getStringList(CONFIG_OUTPUTPREFIXES); - if (!prefixes.isEmpty()) { - foreach (const QString &prefix, prefixes) + outputPrefixes.clear(); + QStringList items = config.getStringList(CONFIG_OUTPUTPREFIXES); + if (!items.isEmpty()) { + foreach (const QString &prefix, items) outputPrefixes[prefix] = config.getString(CONFIG_OUTPUTPREFIXES + Config::dot + prefix); } else { outputPrefixes[QLatin1String("QML")] = QLatin1String("qml-"); outputPrefixes[QLatin1String("JS")] = QLatin1String("js-"); } + + outputSuffixes.clear(); + items = config.getStringList(CONFIG_OUTPUTSUFFIXES); + if (!items.isEmpty()) { + foreach (const QString &suffix, items) + outputSuffixes[suffix] = config.getString(CONFIG_OUTPUTSUFFIXES + Config::dot + suffix); + } + noLinkErrors_ = config.getBool(CONFIG_NOLINKERRORS); autolinkErrors_ = config.getBool(CONFIG_AUTOLINKERRORS); } @@ -1864,9 +1867,25 @@ QString Generator::outFileName() return QFileInfo(static_cast<QFile*>(out().device())->fileName()).fileName(); } -QString Generator::outputPrefix(const QString &nodeType) +QString Generator::outputPrefix(const Node *node) +{ + // Prefix is applied to QML and JS types + if (node->isQmlType() || node->isQmlBasicType()) + return outputPrefixes[QLatin1String("QML")]; + if (node->isJsType() || node->isJsBasicType()) + return outputPrefixes[QLatin1String("JS")]; + return QString(); +} + +QString Generator::outputSuffix(const Node *node) { - return outputPrefixes[nodeType]; + // Suffix is applied to QML and JS types, as + // well as module pages. + if (node->isQmlModule() || node->isQmlType() || node->isQmlBasicType()) + return outputSuffixes[QLatin1String("QML")]; + if (node->isJsModule() || node->isJsType() || node->isJsBasicType()) + return outputSuffixes[QLatin1String("JS")]; + return QString(); } bool Generator::parseArg(const QString& src, @@ -2021,7 +2040,7 @@ void Generator::supplementAlsoList(const Node *node, QList<Text> &alsoList) { if (node->type() == Node::Function) { const FunctionNode *func = static_cast<const FunctionNode *>(node); - if (func->overloadNumber() == 1) { + if (func->overloadNumber() == 0) { QString alternateName; const FunctionNode *alternateFunc = 0; diff --git a/src/tools/qdoc/generator.h b/src/tools/qdoc/generator.h index e4bcd29e52b395087e61cf44c6d2d995e7b4a3e1..6c44cd189cb9329fd2dacc6ce683298ddcd7a358 100644 --- a/src/tools/qdoc/generator.h +++ b/src/tools/qdoc/generator.h @@ -135,7 +135,8 @@ protected: virtual QString typeString(const Node *node); static bool matchAhead(const Atom *atom, Atom::AtomType expectedAtomType); - static QString outputPrefix(const QString &nodeType); + static QString outputPrefix(const Node* node); + static QString outputSuffix(const Node* node); static void singularPlural(Text& text, const NodeList& nodes); static void supplementAlsoList(const Node *node, QList<Text> &alsoList); static QString trimmedTrailing(const QString &string); @@ -214,6 +215,7 @@ private: static QStringList outFileNames_; static QSet<QString> outputFormats; static QHash<QString, QString> outputPrefixes; + static QHash<QString, QString> outputSuffixes; static QStringList scriptDirs; static QStringList scriptFiles; static QStringList styleDirs; diff --git a/src/tools/qdoc/helpprojectwriter.cpp b/src/tools/qdoc/helpprojectwriter.cpp index e98b2f5cb16565bd7bb0517a98d599100103c74e..996cf03f3249fd44d7ceafac92d29eb405176108 100644 --- a/src/tools/qdoc/helpprojectwriter.cpp +++ b/src/tools/qdoc/helpprojectwriter.cpp @@ -125,7 +125,8 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList QHash<QString, Node::NodeType> typeHash; typeHash["namespace"] = Node::Namespace; typeHash["class"] = Node::Class; - typeHash["fake"] = Node::Document; + typeHash["doc"] = Node::Document; + typeHash["fake"] = Node::Document; // Legacy alias for 'doc' typeHash["enum"] = Node::Enum; typeHash["typedef"] = Node::Typedef; typeHash["function"] = Node::Function; @@ -139,7 +140,8 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList typeHash["qmlsignalhandler"] = Node::QmlSignalHandler; typeHash["qmlmethod"] = Node::QmlMethod; typeHash["qmlpropertygroup"] = Node::QmlPropertyGroup; - typeHash["qmlclass"] = Node::QmlType; + typeHash["qmlclass"] = Node::QmlType; // Legacy alias for 'qmltype' + typeHash["qmltype"] = Node::QmlType; typeHash["qmlbasictype"] = Node::QmlBasicType; QHash<QString, Node::DocSubtype> docSubtypeHash; @@ -158,16 +160,20 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList if (typeHash.contains(lower)) subproject.selectors[typeHash[lower]] = allSubTypes; } else if (pieces.size() >= 2) { - QString lower = pieces[0].toLower(); + QString docType = pieces[0].toLower(); pieces = pieces[1].split(QLatin1Char(',')); - if (typeHash.contains(lower)) { + if (typeHash.contains(docType)) { QSet<Node::DocSubtype> docSubtypes; for (int i = 0; i < pieces.size(); ++i) { - QString lower = pieces[i].toLower(); - if (docSubtypeHash.contains(lower)) - docSubtypes.insert(docSubtypeHash[lower]); + QString piece = pieces[i].toLower(); + if (typeHash[docType] == Node::Group) { + subproject.groups << piece; + continue; + } + if (docSubtypeHash.contains(piece)) + docSubtypes.insert(docSubtypeHash[piece]); } - subproject.selectors[typeHash[lower]] = docSubtypes; + subproject.selectors[typeHash[docType]] = docSubtypes; } } } @@ -249,14 +255,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project, if (!docPath.isEmpty() && project.excluded.contains(docPath)) return false; - QString objName; - if (node->isDocumentNode()) { - const DocumentNode *fake = static_cast<const DocumentNode *>(node); - objName = fake->fullTitle(); - } - else - objName = node->fullDocumentName(); - + QString objName = node->isDocumentNode() ? node->fullTitle() : node->fullDocumentName(); // Only add nodes to the set for each subproject if they match a selector. // Those that match will be listed in the table of contents. @@ -267,11 +266,22 @@ bool HelpProjectWriter::generateSection(HelpProject &project, project.subprojects[i].nodes[objName] = node; } else if (subproject.selectors.contains(node->type())) { + // Add all group members for 'group:name' selector + if (node->isGroup()) { + if (project.subprojects[i].groups.contains(node->name())) { + const CollectionNode* cn = static_cast<const CollectionNode*>(node); + foreach (const Node* m, cn->members()) { + QString memberName = m->isDocumentNode() + ? m->fullTitle() : m->fullDocumentName(); + project.subprojects[i].nodes[memberName] = m; + } + } + } // Accept only the node types in the selectors hash. - if (node->type() != Node::Document) + else if (node->type() != Node::Document) project.subprojects[i].nodes[objName] = node; else { - // Accept only fake nodes with subtypes contained in the selector's + // Accept only doc nodes with subtypes contained in the selector's // mask. const DocumentNode *docNode = static_cast<const DocumentNode *>(node); if (subproject.selectors[node->type()].contains(docNode->docSubtype()) && @@ -297,8 +307,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project, QStringList details; details << keyword->string() << keyword->string() - << gen_->fullDocumentLocation(node, false) + - QLatin1Char('#') + Doc::canonicalTitle(keyword->string()); + << gen_->fullDocumentLocation(node, false); project.keywords.append(details); } else @@ -347,8 +356,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project, QStringList details; details << keyword->string() << keyword->string() - << gen_->fullDocumentLocation(node, false) + - QLatin1Char('#') + Doc::canonicalTitle(keyword->string()); + << gen_->fullDocumentLocation(node, false); project.keywords.append(details); } else @@ -428,8 +436,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project, QStringList details; details << keyword->string() << keyword->string() - << gen_->fullDocumentLocation(node, false) + - QLatin1Char('#') + Doc::canonicalTitle(keyword->string()); + << gen_->fullDocumentLocation(node, false); project.keywords.append(details); } else docNode->doc().location().warning( diff --git a/src/tools/qdoc/helpprojectwriter.h b/src/tools/qdoc/helpprojectwriter.h index 7b3e8b1e75b83992750da243ed3e7415d8fc8a24..e4cd1404c7466020d30dc9786f692e89d164540e 100644 --- a/src/tools/qdoc/helpprojectwriter.h +++ b/src/tools/qdoc/helpprojectwriter.h @@ -54,6 +54,7 @@ struct SubProject bool sortPages; QString type; QHash<QString, const Node *> nodes; + QStringList groups; }; struct HelpProject diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index d7a17fce26557f564a723584b77978a48607b31d..ecccd48a6cc24302c176caededbf074eb20e09b8 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -49,6 +49,7 @@ #include <qiterator.h> #include <qtextcodec.h> #include <quuid.h> +#include <qmap.h> QT_BEGIN_NAMESPACE @@ -71,11 +72,11 @@ static void addLink(const QString &linkTarget, QString *res) { if (!linkTarget.isEmpty()) { - *res += "<a href=\""; + *res += QLatin1String("<a href=\""); *res += linkTarget; - *res += "\">"; + *res += QLatin1String("\">"); *res += nestedStuff; - *res += "</a>"; + *res += QLatin1String("</a>"); } else { *res += nestedStuff; @@ -139,8 +140,8 @@ void HtmlGenerator::initializeGenerator(const Config &config) */ int i = 0; while (defaults[i].key) { - formattingLeftMap().insert(defaults[i].key, defaults[i].left); - formattingRightMap().insert(defaults[i].key, defaults[i].right); + formattingLeftMap().insert(QLatin1String(defaults[i].key), QLatin1String(defaults[i].left)); + formattingRightMap().insert(QLatin1String(defaults[i].key), QLatin1String(defaults[i].right)); i++; } @@ -180,7 +181,7 @@ void HtmlGenerator::initializeGenerator(const Config &config) projectDescription = config.getString(CONFIG_DESCRIPTION); if (projectDescription.isEmpty() && !project.isEmpty()) - projectDescription = project + " Reference Documentation"; + projectDescription = project + QLatin1String(" Reference Documentation"); projectUrl = config.getString(CONFIG_URL); tagFile_ = config.getString(CONFIG_TAGFILE); @@ -236,8 +237,8 @@ void HtmlGenerator::initializeGenerator(const Config &config) headerStyles = config.getString(HtmlGenerator::format() + Config::dot + CONFIG_HEADERSTYLES); QString prefix = CONFIG_QHP + Config::dot + project + Config::dot; - manifestDir = "qthelp://" + config.getString(prefix + "namespace"); - manifestDir += QLatin1Char('/') + config.getString(prefix + "virtualFolder") + QLatin1Char('/'); + manifestDir = QLatin1String("qthelp://") + config.getString(prefix + QLatin1String("namespace")); + manifestDir += QLatin1Char('/') + config.getString(prefix + QLatin1String("virtualFolder")) + QLatin1Char('/'); readManifestMetaContent(config); examplesPath = config.getString(CONFIG_EXAMPLESINSTALLPATH); if (!examplesPath.isEmpty()) @@ -282,12 +283,17 @@ QString HtmlGenerator::format() */ void HtmlGenerator::generateKeywordAnchors(const Node* node) { + Q_UNUSED(node); + // Disabled: keywords always link to the top of the QDoc + // comment they appear in, and do not use a dedicated anchor. +#if 0 if (!node->doc().isEmpty()) { const QList<Atom*>& keywords = node->doc().keywords(); foreach (Atom* a, keywords) { - out() << "<a name=\"" << Doc::canonicalTitle(a->string()) << "\"></a>"; + out() << QLatin1String("<a name=\"") << Doc::canonicalTitle(a->string()) << QLatin1String("\"></a>"); } } +#endif } /*! @@ -470,7 +476,7 @@ QString HtmlGenerator::generateLinksToBrokenLinksPage(CodeMarker* marker, int& c */ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMarker *marker) { - int skipAhead = 0; + int idx, skipAhead = 0; static bool in_para = false; switch (atom->type()) { @@ -539,9 +545,9 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark else out() << "variable"; QStringList words = str.split(QLatin1Char(' ')); - if (!(words.first() == "contains" || words.first() == "specifies" - || words.first() == "describes" || words.first() == "defines" - || words.first() == "holds" || words.first() == "determines")) + if (!(words.first() == QLatin1String("contains") || words.first() == QLatin1String("specifies") + || words.first() == QLatin1String("describes") || words.first() == QLatin1String("defines") + || words.first() == QLatin1String("holds") || words.first() == QLatin1String("determines"))) out() << " holds "; else out() << ' '; @@ -660,74 +666,83 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark break; case Atom::AnnotatedList: { - CollectionNode* cn = qdb_->getCollection(atom->string(), Node::DOC); + const CollectionNode* cn = qdb_->getCollectionNode(atom->string(), Node::DOC); if (cn) generateList(cn, marker, atom->string()); } break; case Atom::GeneratedList: - if (atom->string() == "annotatedclasses") { + if (atom->string() == QLatin1String("annotatedclasses")) { generateAnnotatedList(relative, marker, qdb_->getCppClasses()); } - else if (atom->string() == "classes") { + else if (atom->string() == QLatin1String("classes")) { generateCompactList(Generic, relative, qdb_->getCppClasses(), true, QStringLiteral("")); } else if (atom->string().contains("classes ")) { QString rootName = atom->string().mid(atom->string().indexOf("classes") + 7).trimmed(); generateCompactList(Generic, relative, qdb_->getCppClasses(), true, rootName); } - else if (atom->string() == "qmlbasictypes") { + else if (atom->string() == QLatin1String("qmlbasictypes")) { generateCompactList(Generic, relative, qdb_->getQmlBasicTypes(), true, QStringLiteral("")); } - else if (atom->string() == "qmltypes") { + else if (atom->string() == QLatin1String("qmltypes")) { generateCompactList(Generic, relative, qdb_->getQmlTypes(), true, QStringLiteral("")); } - else if (atom->string().contains("classesbymodule")) { - QString physicalModuleName = atom->string().mid(atom->string().indexOf("classesbymodule") + 15).trimmed(); + else if ((idx = atom->string().indexOf(QStringLiteral("bymodule"))) != -1) { + QString moduleName = atom->string().mid(idx + 8).trimmed(); + Node::Genus genus = Node::CPP; + if (atom->string().startsWith(QStringLiteral("qml"))) + genus = Node::QML; + else if (atom->string().startsWith(QStringLiteral("js"))) + genus = Node::JS; QDocDatabase* qdb = QDocDatabase::qdocDB(); - CollectionNode* cn = qdb->findModule(physicalModuleName); + const CollectionNode* cn = qdb->getCollectionNode(moduleName, genus); if (cn) { - NodeMap m; - cn->getMemberClasses(m); - if (!m.isEmpty()) { - generateAnnotatedList(relative, marker, m); + if (genus == Node::CPP) { + NodeMap m; + cn->getMemberClasses(m); + if (!m.isEmpty()) { + generateAnnotatedList(relative, marker, m); + } } + else + generateAnnotatedList(relative, marker, cn->members()); } } - else if (atom->string() == "classhierarchy") { + else if (atom->string() == QLatin1String("classhierarchy")) { generateClassHierarchy(relative, qdb_->getCppClasses()); } - else if (atom->string() == "obsoleteclasses") { + else if (atom->string() == QLatin1String("obsoleteclasses")) { generateCompactList(Generic, relative, qdb_->getObsoleteClasses(), false, QStringLiteral("Q")); } - else if (atom->string() == "obsoleteqmltypes") { + else if (atom->string() == QLatin1String("obsoleteqmltypes")) { generateCompactList(Generic, relative, qdb_->getObsoleteQmlTypes(), false, QStringLiteral("")); } - else if (atom->string() == "obsoletecppmembers") { + else if (atom->string() == QLatin1String("obsoletecppmembers")) { generateCompactList(Obsolete, relative, qdb_->getClassesWithObsoleteMembers(), false, QStringLiteral("Q")); } - else if (atom->string() == "obsoleteqmlmembers") { + else if (atom->string() == QLatin1String("obsoleteqmlmembers")) { generateCompactList(Obsolete, relative, qdb_->getQmlTypesWithObsoleteMembers(), false, QStringLiteral("")); } - else if (atom->string() == "functionindex") { + else if (atom->string() == QLatin1String("functionindex")) { generateFunctionIndex(relative); } - else if (atom->string() == "legalese") { + else if (atom->string() == QLatin1String("legalese")) { generateLegaleseList(relative, marker); } - else if (atom->string() == "overviews") { + else if (atom->string() == QLatin1String("overviews")) { generateList(relative, marker, "overviews"); } - else if (atom->string() == "cpp-modules") { + else if (atom->string() == QLatin1String("cpp-modules")) { generateList(relative, marker, "cpp-modules"); } - else if (atom->string() == "qml-modules") { + else if (atom->string() == QLatin1String("qml-modules")) { generateList(relative, marker, "qml-modules"); } - else if (atom->string() == "namespaces") { + else if (atom->string() == QLatin1String("namespaces")) { generateAnnotatedList(relative, marker, qdb_->getNamespaces()); } - else if (atom->string() == "related") { + else if (atom->string() == QLatin1String("related")) { generateList(relative, marker, "related"); } #if 0 @@ -735,7 +750,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark This is not used in Qt5, as of 10/02/2014 Remove permanently if it is not missed. */ - else if (atom->string() == "relatedinline") { + else if (atom->string() == QLatin1String("relatedinline")) { const DocumentNode *dn = static_cast<const DocumentNode *>(relative); if (dn && !dn->members().isEmpty()) { // Reverse the list into the original scan order. @@ -1210,13 +1225,13 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark p2 = atom->string(1); } if (!p1.isEmpty()) { - if (p1 == "borderless") + if (p1 == QLatin1String("borderless")) attr = p1; else if (p1.contains("%")) width = p1; } if (!p2.isEmpty()) { - if (p2 == "borderless") + if (p2 == QLatin1String("borderless")) attr = p2; else if (p2.contains("%")) width = p2; @@ -1477,7 +1492,7 @@ void HtmlGenerator::generateClassLikeNode(Aggregate* inner, CodeMarker* marker) const FunctionNode *func = reinterpret_cast<const FunctionNode *>(*m); if (func->metaness() == FunctionNode::Ctor || func->metaness() == FunctionNode::Dtor || - func->overloadNumber() != 1) + func->overloadNumber() != 0) names.clear(); } else if ((*m)->type() == Node::Property) { @@ -1796,10 +1811,12 @@ void HtmlGenerator::generateCollectionNode(CollectionNode* cn, CodeMarker* marke generateAlsoList(cn, marker); generateExtractionMark(cn, EndMark); - if (cn->isGroup()) - generateAnnotatedList(cn, marker, cn->members()); - else if (cn->isQmlModule() || cn->isJsModule()) - generateAnnotatedList(cn, marker, cn->members()); + if (!cn->noAutoList()) { + if (cn->isGroup()) + generateAnnotatedList(cn, marker, cn->members()); + else if (cn->isQmlModule() || cn->isJsModule()) + generateAnnotatedList(cn, marker, cn->members()); + } sections = marker->sections(cn, CodeMarker::Detailed, CodeMarker::Okay); s = sections.constBegin(); @@ -1978,6 +1995,7 @@ void HtmlGenerator::generateHeader(const QString& title, out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, qdb_->version()); navigationLinks.clear(); + refMap.clear(); if (node && !node->links().empty()) { QPair<QString,QString> linkPair; @@ -2127,7 +2145,7 @@ void HtmlGenerator::generateRequisites(Aggregate *inner, CodeMarker *marker) if (inner->type() == Node::Class || inner->type() == Node::Namespace) { //add the QT variable to the map if (!inner->physicalModuleName().isEmpty()) { - CollectionNode* cn = qdb_->findModule(inner->physicalModuleName()); + const CollectionNode* cn = qdb_->getCollectionNode(inner->physicalModuleName(), Node::CPP); if (cn && !cn->qtVariable().isEmpty()) { text.clear(); text << "QT += " + cn->qtVariable(); @@ -2237,11 +2255,7 @@ void HtmlGenerator::generateQmlRequisites(QmlTypeNode *qcn, CodeMarker *marker) //add the module name and version to the map QString logicalModuleVersion; - CollectionNode* collection = 0; - if (qcn->isJsNode()) - collection = qdb_->findJsModule(qcn->logicalModuleName()); - else - collection = qdb_->findQmlModule(qcn->logicalModuleName()); + const CollectionNode* collection = qdb_->getCollectionNode(qcn->logicalModuleName(), qcn->genus()); if (collection) logicalModuleVersion = collection->logicalModuleVersion(); else @@ -3155,13 +3169,13 @@ void HtmlGenerator::generateList(const Node* relative, CodeMarker* marker, const { CNMap cnm; Node::Genus genus = Node::DontCare; - if (selector == "overviews") + if (selector == QLatin1String("overviews")) genus = Node::DOC; - else if (selector == "cpp-modules") + else if (selector == QLatin1String("cpp-modules")) genus = Node::CPP; - else if (selector == "qml-modules") + else if (selector == QLatin1String("qml-modules")) genus = Node::QML; - else if (selector == "js-modules") + else if (selector == QLatin1String("js-modules")) genus = Node::JS; if (genus != Node::DontCare) { NodeList nl; @@ -3406,6 +3420,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, { QString src = markedCode; QString html; + html.reserve(src.size()); QStringRef arg; QStringRef par1; @@ -3418,62 +3433,30 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, static const QString linkTag("link"); // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)" + // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)" + // replace all "(<@(type|headerfile)(?: +[^>]*)?>)(.*)(</@\\2>)" tags bool done = false; for (int i = 0, srcSize = src.size(); i < srcSize;) { if (src.at(i) == charLangle && src.at(i + 1) == charAt) { if (alignNames && !done) { - html += "</td><td class=\"memItemRight bottomAlign\">"; + html += QLatin1String("</td><td class=\"memItemRight bottomAlign\">"); done = true; } i += 2; if (parseArg(src, linkTag, &i, srcSize, &arg, &par1)) { - html += "<b>"; + html += QLatin1String("<b>"); const Node* n = CodeMarker::nodeForString(par1.toString()); QString link = linkForNode(n, relative); addLink(link, arg, &html); - html += "</b>"; + html += QLatin1String("</b>"); } - else { - html += charLangle; - html += charAt; - } - } - else { - html += src.at(i++); - } - } - - // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)" - src = html; - html = QString(); - for (int i = 0, srcSize = src.size(); i < srcSize;) { - if (src.at(i) == charLangle && src.at(i + 1) == charAt) { - i += 2; - if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { + else if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { const Node* n = qdb_->findFunctionNode(par1.toString(), relative, Node::DontCare); QString link = linkForNode(n, relative); addLink(link, arg, &html); par1 = QStringRef(); } - else { - html += charLangle; - html += charAt; - } - } - else { - html += src.at(i++); - } - } - - // replace all "(<@(type|headerfile)(?: +[^>]*)?>)(.*)(</@\\2>)" tags - src = html; - html = QString(); - - for (int i=0, srcSize=src.size(); i<srcSize;) { - if (src.at(i) == charLangle && src.at(i+1) == charAt) { - i += 2; - bool handled = false; - if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) { + else if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) { par1 = QStringRef(); const Node* n = qdb_->findTypeNode(arg.toString(), relative); html += QLatin1String("<span class=\"type\">"); @@ -3486,7 +3469,6 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, else addLink(linkForNode(n,relative), arg, &html); html += QLatin1String("</span>"); - handled = true; } else if (parseArg(src, headerTag, &i, srcSize, &arg, &par1)) { par1 = QStringRef(); @@ -3499,9 +3481,8 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, else html += arg; } - handled = true; } - if (!handled) { + else { html += charLangle; html += charAt; } @@ -3524,60 +3505,68 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, // "</@(?:comment|preprocessor|string|char|number|op|type|name|keyword)>" -> "</span>" src = html; html = QString(); - static const QString spanTags[] = { - "<@comment>", "<span class=\"comment\">", - "<@preprocessor>", "<span class=\"preprocessor\">", - "<@string>", "<span class=\"string\">", - "<@char>", "<span class=\"char\">", - "<@number>", "<span class=\"number\">", - "<@op>", "<span class=\"operator\">", - "<@type>", "<span class=\"type\">", - "<@name>", "<span class=\"name\">", - "<@keyword>", "<span class=\"keyword\">", - "</@comment>", "</span>", - "</@preprocessor>", "</span>", - "</@string>", "</span>", - "</@char>", "</span>", - "</@number>", "</span>", - "</@op>", "</span>", - "</@type>", "</span>", - "</@name>", "</span>", - "</@keyword>", "</span>", + html.reserve(src.size()); + static const QLatin1String spanTags[] = { + QLatin1String("comment>"), QLatin1String("<span class=\"comment\">"), + QLatin1String("preprocessor>"), QLatin1String("<span class=\"preprocessor\">"), + QLatin1String("string>"), QLatin1String("<span class=\"string\">"), + QLatin1String("char>"), QLatin1String("<span class=\"char\">"), + QLatin1String("number>"), QLatin1String("<span class=\"number\">"), + QLatin1String("op>"), QLatin1String("<span class=\"operator\">"), + QLatin1String("type>"), QLatin1String("<span class=\"type\">"), + QLatin1String("name>"), QLatin1String("<span class=\"name\">"), + QLatin1String("keyword>"), QLatin1String("<span class=\"keyword\">") }; + int nTags = 9; // Update the upper bound of k in the following code to match the length // of the above array. for (int i = 0, n = src.size(); i < n;) { - if (src.at(i) == charLangle) { - bool handled = false; - for (int k = 0; k != 18; ++k) { - const QString & tag = spanTags[2 * k]; - if (i + tag.length() <= src.length() && - tag == QStringRef(&src, i, tag.length())) { - html += spanTags[2 * k + 1]; - i += tag.length(); - handled = true; - break; + if (src.at(i) == QLatin1Char('<')) { + if (src.at(i + 1) == QLatin1Char('@')) { + i += 2; + bool handled = false; + for (int k = 0; k != nTags; ++k) { + const QLatin1String& tag = spanTags[2 * k]; + if (i + tag.size() <= src.length() && + tag == QStringRef(&src, i, tag.size())) { + html += spanTags[2 * k + 1]; + i += tag.size(); + handled = true; + break; + } } - } - if (!handled) { - ++i; - if (src.at(i) == charAt || - (src.at(i) == QLatin1Char('/') && src.at(i + 1) == charAt)) { + if (!handled) { // drop 'our' unknown tags (the ones still containing '@') while (i < n && src.at(i) != QLatin1Char('>')) ++i; ++i; } - else { - // retain all others - html += charLangle; + continue; + } + else if (src.at(i + 1) == QLatin1Char('/') && src.at(i + 2) == QLatin1Char('@')) { + i += 3; + bool handled = false; + for (int k = 0; k != nTags; ++k) { + const QLatin1String& tag = spanTags[2 * k]; + if (i + tag.size() <= src.length() && + tag == QStringRef(&src, i, tag.size())) { + html += QLatin1String("</span>"); + i += tag.size(); + handled = true; + break; + } + } + if (!handled) { + // drop 'our' unknown tags (the ones still containing '@') + while (i < n && src.at(i) != QLatin1Char('>')) + ++i; + ++i; } + continue; } } - else { - html += src.at(i); - ++i; - } + html += src.at(i); + ++i; } return html; } @@ -3652,7 +3641,7 @@ QString HtmlGenerator::protect(const QString &string, const QString &outputEncod APPEND(">"); } else if (ch == QLatin1Char('"')) { APPEND("""); - } else if ((outputEncoding == "ISO-8859-1" && ch.unicode() > 0x007F) + } else if ((outputEncoding == QLatin1String("ISO-8859-1") && ch.unicode() > 0x007F) || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/')) || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) { // we escape '*/' and the last dot in 'e.g.' and 'i.e.' for the Javadoc generator @@ -3681,10 +3670,10 @@ QString HtmlGenerator::fileBase(const Node *node) const if (!node->isAggregate()) { switch (node->status()) { case Node::Compat: - result += "-compat"; + result += QLatin1String("-compat"); break; case Node::Obsolete: - result += "-obsolete"; + result += QLatin1String("-obsolete"); break; default: ; @@ -3729,12 +3718,12 @@ QString HtmlGenerator::refForNode(const Node *node) break; case Node::Function: func = static_cast<const FunctionNode *>(node); - if (func->associatedProperty()) { - return refForNode(func->associatedProperty()); + if (func->hasOneAssociatedProperty() && func->doc().isEmpty()) { + return refForNode(func->firstAssociatedProperty()); } else { ref = func->name(); - if (func->overloadNumber() != 1) + if (func->overloadNumber() != 0) ref += QLatin1Char('-') + QString::number(func->overloadNumber()); } break; @@ -3759,7 +3748,7 @@ QString HtmlGenerator::refForNode(const Node *node) case Node::QmlMethod: func = static_cast<const FunctionNode *>(node); ref = func->name() + "-method"; - if (func->overloadNumber() != 1) + if (func->overloadNumber() != 0) ref += QLatin1Char('-') + QString::number(func->overloadNumber()); break; case Node::Variable: @@ -3825,10 +3814,8 @@ QString HtmlGenerator::getAutoLink(const Atom *atom, const Node *relative, const link = linkForNode(*node, relative); if ((*node)->docSubtype() == Node::Image) link = "images/used-in-examples/" + link; - if (!ref.isEmpty()) - link += QLatin1Char('#') + ref; } - else if (!ref.isEmpty()) { + if (!ref.isEmpty()) { int hashtag = link.lastIndexOf(QChar('#')); if (hashtag != -1) link.truncate(hashtag); @@ -3918,24 +3905,22 @@ void HtmlGenerator::generateDetailedMember(const Node *node, const Aggregate *relative, CodeMarker *marker) { - const EnumNode *enume; - + const EnumNode *etn; #ifdef GENERATE_MAC_REFS generateMacRef(node, marker); #endif generateExtractionMark(node, MemberMark); generateKeywordAnchors(node); QString nodeRef = refForNode(node); - if (node->type() == Node::Enum - && (enume = static_cast<const EnumNode *>(node))->flagsType()) { + if (node->isEnumType() && (etn = static_cast<const EnumNode *>(node))->flagsType()) { #ifdef GENERATE_MAC_REFS - generateMacRef(enume->flagsType(), marker); + generateMacRef(etn->flagsType(), marker); #endif out() << "<h3 class=\"flags\" id=\"" << nodeRef << "\">"; out() << "<a name=\"" + nodeRef + "\"></a>"; - generateSynopsis(enume, relative, marker, CodeMarker::Detailed); + generateSynopsis(etn, relative, marker, CodeMarker::Detailed); out() << "<br/>"; - generateSynopsis(enume->flagsType(), + generateSynopsis(etn->flagsType(), relative, marker, CodeMarker::Detailed); @@ -3954,7 +3939,7 @@ void HtmlGenerator::generateDetailedMember(const Node *node, generateThreadSafeness(node, marker); generateSince(node, marker); - if (node->type() == Node::Property) { + if (node->isProperty()) { const PropertyNode *property = static_cast<const PropertyNode *>(node); Section section; @@ -3980,16 +3965,17 @@ void HtmlGenerator::generateDetailedMember(const Node *node, const FunctionNode* fn = static_cast<const FunctionNode*>(node); if (fn->isPrivateSignal()) generatePrivateSignalNote(node, marker); + generateAssociatedPropertyNotes(fn); } - else if (node->type() == Node::Enum) { - const EnumNode *enume = static_cast<const EnumNode *>(node); - if (enume->flagsType()) { - out() << "<p>The " << protectEnc(enume->flagsType()->name()) + else if (node->isEnumType()) { + const EnumNode *etn = static_cast<const EnumNode *>(node); + if (etn->flagsType()) { + out() << "<p>The " << protectEnc(etn->flagsType()->name()) << " type is a typedef for " << "<a href=\"" << qflagsHref_ << "\">QFlags</a><" - << protectEnc(enume->name()) + << protectEnc(etn->name()) << ">. It stores an OR combination of " - << protectEnc(enume->name()) + << protectEnc(etn->name()) << " values.</p>\n"; } } @@ -4364,8 +4350,8 @@ void HtmlGenerator::generateExtractionMark(const Node *node, ExtractionMarkType if (markType == MemberMark) { if (node->type() == Node::Function) { const FunctionNode *func = static_cast<const FunctionNode *>(node); - if (!func->associatedProperty()) { - if (func->overloadNumber() == 1) + if (!func->hasAssociatedProperties()) { + if (func->overloadNumber() == 0) out() << "[overload1]"; out() << "$$$" + func->name() + func->rawParameters().remove(' '); } @@ -4421,7 +4407,7 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString QString fileName = manifest +"-manifest.xml"; QFile file(outputDir() + QLatin1Char('/') + fileName); bool demos = false; - if (manifest == "demos") + if (manifest == QLatin1String("demos")) demos = true; bool proceed = false; @@ -4450,6 +4436,7 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString writer.writeAttribute("module", project); writer.writeStartElement(manifest); + QStringList usedAttributes; i = exampleNodeMap.begin(); while (i != exampleNodeMap.end()) { const ExampleNode* en = i.value(); @@ -4463,6 +4450,10 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString ++i; continue; } + // attributes that are always written for the element + usedAttributes.clear(); + usedAttributes << "name" << "docUrl" << "projectPath"; + writer.writeStartElement(element); writer.writeAttribute("name", en->title()); QString docUrl = manifestDir + fileBase(en) + ".html"; @@ -4496,8 +4487,10 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString writer.writeAttribute("projectPath", examplesPath + proFiles[0]); } } - if (!en->imageFileName().isEmpty()) + if (!en->imageFileName().isEmpty()) { writer.writeAttribute("imageUrl", manifestDir + en->imageFileName()); + usedAttributes << "imageUrl"; + } QString fullName = project + QLatin1Char('/') + en->title(); QSet<QString> tags; @@ -4523,7 +4516,10 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString if (attrList.count() == 1) attrList.append(QStringLiteral("true")); QString attrName = attrList.takeFirst(); - writer.writeAttribute(attrName, attrList.join(div)); + if (!usedAttributes.contains(attrName)) { + writer.writeAttribute(attrName, attrList.join(div)); + usedAttributes << attrName; + } } } } @@ -4579,7 +4575,7 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString if (!tags.isEmpty()) { writer.writeStartElement("tags"); bool wrote_one = false; - foreach (QString tag, tags) { + foreach (const QString &tag, tags) { if (wrote_one) writer.writeCharacters(","); writer.writeCharacters(tag); @@ -4874,4 +4870,37 @@ void HtmlGenerator::writeDitaRefs(const DitaRefList& ditarefs) } } +/*! + Generates bold Note lines that explain how function \a fn + is associated with each of its associated properties. + */ +void HtmlGenerator::generateAssociatedPropertyNotes(const FunctionNode* fn) +{ + if (fn->hasAssociatedProperties()) { + out() << "<p><b>Note:</b> "; + foreach (const PropertyNode* pn, fn->associatedProperties()) { + QString msg; + switch (pn->role(fn)) { + case PropertyNode::Getter: + msg = QStringLiteral("Getter function "); + break; + case PropertyNode::Setter: + msg = QStringLiteral("Setter function "); + break; + case PropertyNode::Resetter: + msg = QStringLiteral("Resetter function "); + break; + case PropertyNode::Notifier: + msg = QStringLiteral("Notifier signal "); + break; + default: + break; + } + QString link = linkForNode(pn, 0); + out() << msg << "for property <a href=\"" << link << "\">" << pn->name() << "</a>. "; + } + out() << "</p>"; + } +} + QT_END_NAMESPACE diff --git a/src/tools/qdoc/htmlgenerator.h b/src/tools/qdoc/htmlgenerator.h index 615de8e8a32ed3be0c6474fe660a02ad97c40203..d46fc9ebee52797353c803e55b4e771a991547e6 100644 --- a/src/tools/qdoc/htmlgenerator.h +++ b/src/tools/qdoc/htmlgenerator.h @@ -38,7 +38,7 @@ #ifndef HTMLGENERATOR_H #define HTMLGENERATOR_H -#include <qmap.h> +#include <qhash.h> #include <qregexp.h> #include <qxmlstream.h> #include "codemarker.h" @@ -106,6 +106,7 @@ protected: void generateManifestFile(const QString &manifest, const QString &element); void readManifestMetaContent(const Config &config); void generateKeywordAnchors(const Node* node); + void generateAssociatedPropertyNotes(const FunctionNode* fn); private: enum SubTitleSize { SmallSubTitle, LargeSubTitle }; @@ -186,7 +187,6 @@ private: void generateQmlInstantiates(QmlTypeNode* qcn, CodeMarker* marker); void generateInstantiatedBy(ClassNode* cn, CodeMarker* marker); - void generateRequisitesTable(const QStringList& requisitesOrder, QMap<QString, Text>& requisites); void generateSection(const NodeList& nl, const Node *relative, CodeMarker *marker, @@ -231,7 +231,7 @@ private: void writeDitaRefs(const DitaRefList& ditarefs); QXmlStreamWriter& xmlWriter(); - QMap<QString, QString> refMap; + QHash<QString, QString> refMap; int codeIndent; HelpProjectWriter *helpProjectWriter; bool inObsoleteLink; diff --git a/src/tools/qdoc/jscodemarker.cpp b/src/tools/qdoc/jscodemarker.cpp index 537328357240fb6724c8203ebbd0bbce93640a0f..f6a2c9917978ba3a8e8c67ba0c48b898e6775af5 100644 --- a/src/tools/qdoc/jscodemarker.cpp +++ b/src/tools/qdoc/jscodemarker.cpp @@ -68,7 +68,7 @@ bool JsCodeMarker::recognizeCode(const QString &code) QQmlJS::Parser parser(&engine); QString newCode = code; - QList<QQmlJS::AST::SourceLocation> pragmas = extractPragmas(newCode); + QVector<QQmlJS::AST::SourceLocation> pragmas = extractPragmas(newCode); lexer.setCode(newCode, 1); return parser.parseProgram(); @@ -115,7 +115,7 @@ QString JsCodeMarker::addMarkUp(const QString &code, QQmlJS::Lexer lexer(&engine); QString newCode = code; - QList<QQmlJS::AST::SourceLocation> pragmas = extractPragmas(newCode); + QVector<QQmlJS::AST::SourceLocation> pragmas = extractPragmas(newCode); lexer.setCode(newCode, 1); QQmlJS::Parser parser(&engine); diff --git a/src/tools/qdoc/location.h b/src/tools/qdoc/location.h index ade7a1518af72140262866b85cfbe0bc2cc975e5..1cb8e3aec1964c84085fa1238eb639c8c0ed5c8b 100644 --- a/src/tools/qdoc/location.h +++ b/src/tools/qdoc/location.h @@ -105,6 +105,7 @@ private: int lineNo; int columnNo; }; + friend class QTypeInfo<StackEntry>; void emitMessage(MessageType type, const QString& message, @@ -124,6 +125,8 @@ private: static QRegExp *spuriousRegExp; static bool logProgress_; }; +Q_DECLARE_TYPEINFO(Location::StackEntry, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(Location, Q_COMPLEX_TYPE); // stkTop = &stkBottom QT_END_NAMESPACE diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp index a521daadbb730216f111a8b5cd1595e7393ac9fa..3833cbb5dd582b9f7c13bb660861553ad004ae37 100644 --- a/src/tools/qdoc/main.cpp +++ b/src/tools/qdoc/main.cpp @@ -342,9 +342,11 @@ static void processQdocconfFile(const QString &fileName) qdb->clearSearchOrder(); if (!Generator::singleExec()) { - Generator::debug(" loading index files"); - loadIndexFiles(config); - Generator::debug(" done loading index files"); + if (!Generator::preparing()) { + Generator::debug(" loading index files"); + loadIndexFiles(config); + Generator::debug(" done loading index files"); + } qdb->newPrimaryTree(project); } else if (Generator::preparing()) @@ -480,6 +482,9 @@ static void processQdocconfFile(const QString &fileName) } Generator::debug(QString("Parsing done.")); + /* + Currently these doneParsingSourceFiles() calls do nothing. + */ foreach (CodeParser *codeParser, usedParsers) codeParser->doneParsingSourceFiles(); diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp index e58e65a633c525c7eae59b9e95113521b0bc9fd2..8646e699a9baded9063c561131debe3bbfa438a3 100644 --- a/src/tools/qdoc/node.cpp +++ b/src/tools/qdoc/node.cpp @@ -606,7 +606,6 @@ QString Node::fileBase() const base.replace(QLatin1Char(' '), QLatin1Char('-')); return base.toLower(); } -#endif /*! Returns this node's Universally Unique IDentifier as a QString. Creates the UUID first, if it has not been created. @@ -617,6 +616,7 @@ QString Node::guid() const uuid_ = idForNode(); return uuid_; } +#endif /*! If this node is a QML or JS type node, return a pointer to @@ -727,7 +727,7 @@ Aggregate::~Aggregate() Node *Aggregate::findChildNode(const QString& name, Node::Genus genus) const { if (genus == Node::DontCare) { - Node *node = childMap.value(name); + Node *node = childMap_.value(name); if (node && !node->isQmlPropertyGroup()) // mws asks: Why not property group? return node; if (isQmlType() || isJsType()) { @@ -742,7 +742,7 @@ Node *Aggregate::findChildNode(const QString& name, Node::Genus genus) const } } else { - NodeList nodes = childMap.values(name); + NodeList nodes = childMap_.values(name); if (!nodes.isEmpty()) { for (int i=0; i<nodes.size(); ++i) { Node* node = nodes.at(i); @@ -751,7 +751,7 @@ Node *Aggregate::findChildNode(const QString& name, Node::Genus genus) const } } } - return primaryFunctionMap.value(name); + return primaryFunctionMap_.value(name); } /*! @@ -760,11 +760,11 @@ Node *Aggregate::findChildNode(const QString& name, Node::Genus genus) const */ void Aggregate::findChildren(const QString& name, NodeList& nodes) const { - nodes = childMap.values(name); - Node* n = primaryFunctionMap.value(name); + nodes = childMap_.values(name); + Node* n = primaryFunctionMap_.value(name); if (n) { nodes.append(n); - NodeList t = secondaryFunctionMap.value(name); + NodeList t = secondaryFunctionMap_.value(name); if (!t.isEmpty()) nodes.append(t); } @@ -774,7 +774,7 @@ void Aggregate::findChildren(const QString& name, NodeList& nodes) const if (i < 0) return; QString qmlPropGroup = name.left(i); - NodeList t = childMap.values(qmlPropGroup); + NodeList t = childMap_.values(qmlPropGroup); if (t.isEmpty()) return; foreach (Node* n, t) { @@ -794,9 +794,9 @@ void Aggregate::findChildren(const QString& name, NodeList& nodes) const Node* Aggregate::findChildNode(const QString& name, NodeType type) { if (type == Function) - return primaryFunctionMap.value(name); + return primaryFunctionMap_.value(name); else { - NodeList nodes = childMap.values(name); + NodeList nodes = childMap_.values(name); for (int i=0; i<nodes.size(); ++i) { Node* node = nodes.at(i); if (node->type() == type) @@ -812,7 +812,7 @@ Node* Aggregate::findChildNode(const QString& name, NodeType type) */ FunctionNode *Aggregate::findFunctionNode(const QString& name) const { - return static_cast<FunctionNode *>(primaryFunctionMap.value(name)); + return static_cast<FunctionNode *>(primaryFunctionMap_.value(name)); } /*! @@ -822,13 +822,13 @@ FunctionNode *Aggregate::findFunctionNode(const QString& name) const */ FunctionNode *Aggregate::findFunctionNode(const FunctionNode *clone) const { - QMap<QString,Node*>::ConstIterator c = primaryFunctionMap.constFind(clone->name()); - if (c != primaryFunctionMap.constEnd()) { + QMap<QString,Node*>::ConstIterator c = primaryFunctionMap_.constFind(clone->name()); + if (c != primaryFunctionMap_.constEnd()) { if (isSameSignature(clone, (FunctionNode *) *c)) { return (FunctionNode *) *c; } - else if (secondaryFunctionMap.contains(clone->name())) { - const NodeList& secs = secondaryFunctionMap[clone->name()]; + else if (secondaryFunctionMap_.contains(clone->name())) { + const NodeList& secs = secondaryFunctionMap_[clone->name()]; NodeList::ConstIterator s = secs.constBegin(); while (s != secs.constEnd()) { if (isSameSignature(clone, (FunctionNode *) *s)) @@ -846,8 +846,8 @@ FunctionNode *Aggregate::findFunctionNode(const FunctionNode *clone) const QStringList Aggregate::primaryKeys() { QStringList t; - QMap<QString, Node*>::iterator i = primaryFunctionMap.begin(); - while (i != primaryFunctionMap.end()) { + QMap<QString, Node*>::iterator i = primaryFunctionMap_.begin(); + while (i != primaryFunctionMap_.end()) { t.append(i.key()); ++i; } @@ -860,44 +860,14 @@ QStringList Aggregate::primaryKeys() QStringList Aggregate::secondaryKeys() { QStringList t; - QMap<QString, NodeList>::iterator i = secondaryFunctionMap.begin(); - while (i != secondaryFunctionMap.end()) { + QMap<QString, NodeList>::iterator i = secondaryFunctionMap_.begin(); + while (i != secondaryFunctionMap_.end()) { t.append(i.key()); ++i; } return t; } -/*! - */ -void Aggregate::setOverload(FunctionNode *func, bool b) -{ - Node *node = (Node *) func; - Node *&primary = primaryFunctionMap[func->name()]; - - if (secondaryFunctionMap.contains(func->name())) { - NodeList& secs = secondaryFunctionMap[func->name()]; - if (b) { - if (primary == node) { - primary = secs.first(); - secs.erase(secs.begin()); - secs.append(node); - } - else { - secs.removeAll(node); - secs.append(node); - } - } - else { - if (primary != node) { - secs.removeAll(node); - secs.prepend(primary); - primary = node; - } - } - } -} - /*! Mark all child nodes that have no documentation as having private access and internal status. qdoc will then ignore @@ -916,55 +886,98 @@ void Aggregate::makeUndocumentedChildrenInternal() } /*! + This is where we should set the overload numbers, including + the related non-members. */ void Aggregate::normalizeOverloads() { - QMap<QString, Node *>::Iterator p1 = primaryFunctionMap.begin(); - while (p1 != primaryFunctionMap.end()) { + QMap<QString, Node *>::Iterator p1 = primaryFunctionMap_.begin(); + while (p1 != primaryFunctionMap_.end()) { FunctionNode *primaryFunc = (FunctionNode *) *p1; - if (secondaryFunctionMap.contains(primaryFunc->name()) && - (primaryFunc->status() != Active || primaryFunc->access() == Private)) { - - NodeList& secs = secondaryFunctionMap[primaryFunc->name()]; - NodeList::ConstIterator s = secs.constBegin(); - while (s != secs.constEnd()) { - FunctionNode *secondaryFunc = (FunctionNode *) *s; - - // Any non-obsolete, non-compatibility, non-private functions - // (i.e, visible functions) are preferable to the primary - // function. - - if (secondaryFunc->status() == Active && secondaryFunc->access() != Private) { - - *p1 = secondaryFunc; - int index = secondaryFunctionMap[primaryFunc->name()].indexOf(secondaryFunc); - secondaryFunctionMap[primaryFunc->name()].replace(index, primaryFunc); - break; + if (primaryFunc->status() != Active || primaryFunc->access() == Private) { + if (secondaryFunctionMap_.contains(primaryFunc->name())) { + /* + Either the primary function is not active or it is private. + It therefore can't be the primary function. Search the list + of overloads to find one that can be the primary function. + */ + NodeList& overloads = secondaryFunctionMap_[primaryFunc->name()]; + NodeList::ConstIterator s = overloads.constBegin(); + while (s != overloads.constEnd()) { + FunctionNode *overloadFunc = (FunctionNode *) *s; + /* + Any non-obsolete, non-private function (i.e., visible function) + is preferable to the current primary function. Swap the primary + and overload functions. + */ + if (overloadFunc->status() == Active && overloadFunc->access() != Private) { + primaryFunc->setOverloadNumber(overloadFunc->overloadNumber()); + overloads.replace(overloads.indexOf(overloadFunc), primaryFunc); + *p1 = overloadFunc; + overloadFunc->setOverloadFlag(false); + overloadFunc->setOverloadNumber(0); + break; + } + ++s; } - ++s; } } ++p1; } - - QMap<QString, Node *>::ConstIterator p = primaryFunctionMap.constBegin(); - while (p != primaryFunctionMap.constEnd()) { + /* + Ensure that none of the primary functions is marked with \overload. + */ + QMap<QString, Node *>::Iterator p = primaryFunctionMap_.begin(); + while (p != primaryFunctionMap_.end()) { FunctionNode *primaryFunc = (FunctionNode *) *p; - if (primaryFunc->isOverload()) - primaryFunc->overload_ = false; - if (secondaryFunctionMap.contains(primaryFunc->name())) { - NodeList& secs = secondaryFunctionMap[primaryFunc->name()]; - NodeList::ConstIterator s = secs.constBegin(); - while (s != secs.constEnd()) { - FunctionNode *secondaryFunc = (FunctionNode *) *s; - if (!secondaryFunc->isOverload()) - secondaryFunc->overload_ = true; - ++s; + if (primaryFunc->isOverload()) { + if (secondaryFunctionMap_.contains(primaryFunc->name())) { + /* + The primary function is marked with \overload. Find an + overload in the secondary function map that is not marked + with \overload but that is active and not private. Then + swap it with the primary function. + */ + NodeList& overloads = secondaryFunctionMap_[primaryFunc->name()]; + NodeList::ConstIterator s = overloads.constBegin(); + while (s != overloads.constEnd()) { + FunctionNode *overloadFunc = (FunctionNode *) *s; + if (!overloadFunc->isOverload()) { + if (overloadFunc->status() == Active && overloadFunc->access() != Private) { + primaryFunc->setOverloadNumber(overloadFunc->overloadNumber()); + overloads.replace(overloads.indexOf(overloadFunc), primaryFunc); + *p = overloadFunc; + overloadFunc->setOverloadFlag(false); + overloadFunc->setOverloadNumber(0); + break; + } + } + ++s; + } } } ++p; } - + /* + Add the related non-members here. + */ + if (!related_.isEmpty()) { + foreach (Node* n, related_) { + if (n->isFunction()) { + FunctionNode* fn = static_cast<FunctionNode*>(n); + QMap<QString, Node *>::Iterator p = primaryFunctionMap_.find(fn->name()); + if (p != primaryFunctionMap_.end()) { + secondaryFunctionMap_[fn->name()].append(fn); + fn->setOverloadNumber(secondaryFunctionMap_[fn->name()].size()); + } + else + fn->setOverloadNumber(0); + } + } + } + /* + Recursive part. + */ NodeList::ConstIterator c = childNodes().constBegin(); while (c != childNodes().constEnd()) { if ((*c)->isAggregate()) @@ -1023,22 +1036,6 @@ const EnumNode *Aggregate::findEnumNodeForValue(const QString &enumValue) const return 0; } -/*! - Returnds the sequence number of the function node \a func - in the list of overloaded functions for a class, such that - all the functions have the same name as the \a func. - */ -int Aggregate::overloadNumber(const FunctionNode *func) const -{ - Node *node = const_cast<FunctionNode *>(func); - if (primaryFunctionMap[func->name()] == node) { - return 1; - } - else { - return secondaryFunctionMap[func->name()].indexOf(node) + 2; - } -} - /*! Returns a node list containing all the member functions of some class such that the functions overload the name \a funcName. @@ -1046,10 +1043,10 @@ int Aggregate::overloadNumber(const FunctionNode *func) const NodeList Aggregate::overloads(const QString &funcName) const { NodeList result; - Node *primary = primaryFunctionMap.value(funcName); + Node *primary = primaryFunctionMap_.value(funcName); if (primary) { result << primary; - result += secondaryFunctionMap[funcName]; + result += secondaryFunctionMap_[funcName]; } return result; } @@ -1133,19 +1130,22 @@ void Aggregate::addChild(Node *child) { children_.append(child); if ((child->type() == Function) || (child->type() == QmlMethod)) { - FunctionNode *func = (FunctionNode *) child; - if (!primaryFunctionMap.contains(func->name())) { - primaryFunctionMap.insert(func->name(), func); + FunctionNode *func = static_cast<FunctionNode*>(child); + QString name = func->name(); + if (!primaryFunctionMap_.contains(name)) { + primaryFunctionMap_.insert(name, func); + func->setOverloadNumber(0); } else { - NodeList &secs = secondaryFunctionMap[func->name()]; - secs.append(func); + NodeList &overloads = secondaryFunctionMap_[name]; + overloads.append(func); + func->setOverloadNumber(overloads.size()); } } else { if (child->type() == Enum) enumChildren_.append(child); - childMap.insertMulti(child->name(), child); + childMap_.insertMulti(child->name(), child); } if (child->parent() == 0) { child->setParent(this); @@ -1161,7 +1161,7 @@ void Aggregate::addChild(Node *child) */ void Aggregate::addChild(Node* child, const QString& title) { - childMap.insertMulti(title, child); + childMap_.insertMulti(title, child); } /*! @@ -1175,35 +1175,33 @@ void Aggregate::removeChild(Node *child) children_.removeAll(child); enumChildren_.removeAll(child); if (child->type() == Function) { - QMap<QString, Node *>::Iterator prim = - primaryFunctionMap.find(child->name()); - NodeList& secs = secondaryFunctionMap[child->name()]; - if (prim != primaryFunctionMap.end() && *prim == child) { - if (secs.isEmpty()) { - primaryFunctionMap.remove(child->name()); + QMap<QString, Node *>::Iterator primary = primaryFunctionMap_.find(child->name()); + NodeList& overloads = secondaryFunctionMap_[child->name()]; + if (primary != primaryFunctionMap_.end() && *primary == child) { + primaryFunctionMap_.erase(primary); + if (!overloads.isEmpty()) { + FunctionNode* fn = static_cast<FunctionNode*>(overloads.takeFirst()); + fn->setOverloadNumber(0); + primaryFunctionMap_.insert(child->name(), fn); } - else { - primaryFunctionMap.insert(child->name(), secs.takeFirst()); - } - } - else { - secs.removeAll(child); } + else + overloads.removeAll(child); } - QMap<QString, Node *>::Iterator ent = childMap.find(child->name()); - while (ent != childMap.end() && ent.key() == child->name()) { + QMap<QString, Node *>::Iterator ent = childMap_.find(child->name()); + while (ent != childMap_.end() && ent.key() == child->name()) { if (*ent == child) { - childMap.erase(ent); + childMap_.erase(ent); break; } ++ent; } if (child->title().isEmpty()) return; - ent = childMap.find(child->title()); - while (ent != childMap.end() && ent.key() == child->title()) { + ent = childMap_.find(child->title()); + while (ent != childMap_.end() && ent.key() == child->title()) { if (*ent == child) { - childMap.erase(ent); + childMap_.erase(ent); break; } ++ent; @@ -1810,6 +1808,9 @@ QString Parameter::reconstruct(bool value) const /*! Construct a function node for a C++ function. It's parent is \a parent, and it's name is \a name. + + Do not set overloadNumber_ in the initializer list because it + is set by addChild() in the Node base class. */ FunctionNode::FunctionNode(Aggregate *parent, const QString& name) : LeafNode(Function, parent, name), @@ -1817,12 +1818,11 @@ FunctionNode::FunctionNode(Aggregate *parent, const QString& name) virtualness_(NonVirtual), const_(false), static_(false), - overload_(false), reimplemented_(false), attached_(false), privateSignal_(false), - reimplementedFrom_(0), - associatedProperty_(0) + overload_(false), + reimplementedFrom_(0) { setGenus(Node::CPP); } @@ -1831,6 +1831,9 @@ FunctionNode::FunctionNode(Aggregate *parent, const QString& name) Construct a function node for a QML method or signal, specified by \a type. It's parent is \a parent, and it's name is \a name. If \a attached is true, it is an attached method or signal. + + Do not set overloadNumber_ in the initializer list because it + is set by addChild() in the Node base class. */ FunctionNode::FunctionNode(NodeType type, Aggregate *parent, const QString& name, bool attached) : LeafNode(type, parent, name), @@ -1838,12 +1841,11 @@ FunctionNode::FunctionNode(NodeType type, Aggregate *parent, const QString& name virtualness_(NonVirtual), const_(false), static_(false), - overload_(false), reimplemented_(false), attached_(attached), privateSignal_(false), - reimplementedFrom_(0), - associatedProperty_(0) + overload_(false), + reimplementedFrom_(0) { setGenus(Node::QML); if (type == QmlMethod || type == QmlSignal) { @@ -1866,13 +1868,15 @@ void FunctionNode::setVirtualness(Virtualness v) parent()->setAbstract(true); } -/*! +/*! \fn void FunctionNode::setOverloadFlag(bool b) + Sets this function node's overload flag to \a b. + It does not set the overload number. + */ + +/*! \fn void FunctionNode::setOverloadNumber(unsigned char n) + Sets this function node's overload number to \a n. + It does not set the overload flag. */ -void FunctionNode::setOverload(bool b) -{ - parent()->setOverload(this, b); - overload_ = b; -} /*! Sets the function node's reimplementation flag to \a b. @@ -1919,23 +1923,35 @@ void FunctionNode::setReimplementedFrom(FunctionNode *f) } /*! - Sets the "associated" property to \a property. The function - might be the setter or getter for a property, for example. + Adds the "associated" property \a p to this function node. + The function might be the setter or getter for a property, + for example. */ -void FunctionNode::setAssociatedProperty(PropertyNode *p) +void FunctionNode::addAssociatedProperty(PropertyNode *p) { - associatedProperty_ = p; + associatedProperties_.append(p); } /*! - Returns the overload number for this function obtained - from the parent. + Returns true if this function has at least one property + that is active, i.e. at least one property that is not + obsolete. */ -int FunctionNode::overloadNumber() const +bool FunctionNode::hasActiveAssociatedProperty() const { - return parent()->overloadNumber(this); + if (associatedProperties_.isEmpty()) + return false; + foreach (const PropertyNode* p, associatedProperties_) { + if (!p->isObsolete()) + return true; + } + return false; } +/*! \fn unsigned char FunctionNode::overloadNumber() const + Returns the overload number for this function. + */ + /*! Returns the list of parameter names. */ @@ -2007,6 +2023,19 @@ QString FunctionNode::signature(bool values) const return s; } +/*! + Returns true if function \a fn has role \a r for this + property. + */ +PropertyNode::FunctionRole PropertyNode::role(const FunctionNode* fn) const +{ + for (int i=0; i<4; i++) { + if (functions_[i].contains((Node*)fn)) + return (FunctionRole) i; + } + return Notifier; +} + /*! Print some debugging stuff. */ @@ -2492,6 +2521,7 @@ QString Node::cleanId(const QString &str) return clean; } +#if 0 /*! Creates a string that can be used as a UUID for the node, depending on the type and subtype of the node. Uniquenss @@ -2596,7 +2626,7 @@ QString Node::idForNode() const << parent_->type() << func->name(); } - if (func->overloadNumber() != 1) + if (func->overloadNumber() != 0) str += QLatin1Char('-') + QString::number(func->overloadNumber()); } break; @@ -2697,7 +2727,7 @@ QString Node::idForNode() const else str = "js-method-"; str += parent_->name().toLower() + "-" + func->name(); - if (func->overloadNumber() != 1) + if (func->overloadNumber() != 0) str += QLatin1Char('-') + QString::number(func->overloadNumber()); break; case Node::Variable: @@ -2719,6 +2749,7 @@ QString Node::idForNode() const } return str; } +#endif /*! Prints the inner node's list of children. @@ -2807,7 +2838,7 @@ void CollectionNode::getMemberNamespaces(NodeMap& out) Loads \a out with all this collection node's members that are class nodes. */ -void CollectionNode::getMemberClasses(NodeMap& out) +void CollectionNode::getMemberClasses(NodeMap& out) const { out.clear(); NodeList::const_iterator i = members_.cbegin(); diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h index 8a666b1161f29323eed4881d5f6c41ba534d7612..e9816dad191e1fb3ac31f27b2a0eb22f1e26fdeb 100644 --- a/src/tools/qdoc/node.h +++ b/src/tools/qdoc/node.h @@ -59,6 +59,7 @@ class CollectionNode; class QmlPropertyNode; typedef QList<Node*> NodeList; +typedef QList<PropertyNode*> PropNodeList; typedef QMap<QString, Node*> NodeMap; typedef QMultiMap<QString, Node*> NodeMultiMap; typedef QPair<int, int> NodeTypePair; @@ -202,6 +203,7 @@ public: virtual bool isJsType() const { return false; } virtual bool isQmlBasicType() const { return false; } virtual bool isJsBasicType() const { return false; } + virtual bool isEnumType() const { return false; } virtual bool isExample() const { return false; } virtual bool isExampleFile() const { return false; } virtual bool isHeaderFile() const { return false; } @@ -243,7 +245,7 @@ public: virtual QmlPropertyNode* hasQmlProperty(const QString& ) const { return 0; } virtual QmlPropertyNode* hasQmlProperty(const QString&, bool ) const { return 0; } virtual void getMemberNamespaces(NodeMap& ) { } - virtual void getMemberClasses(NodeMap& ) { } + virtual void getMemberClasses(NodeMap& ) const { } virtual bool isInternal() const; virtual void setDataType(const QString& ) { } virtual void setReadOnly(bool ) { } @@ -253,6 +255,7 @@ public: virtual QString element() const { return QString(); } virtual Tree* tree() const; virtual void findChildren(const QString& , NodeList& nodes) const { nodes.clear(); } + virtual void setNoAutoList(bool ) { } bool isIndexNode() const { return indexNodeFlag_; } NodeType type() const { return (NodeType) nodeType_; } virtual DocSubtype docSubtype() const { return NoSubtype; } @@ -297,7 +300,7 @@ public: void clearRelated() { relatesTo_ = 0; } - QString guid() const; + //QString guid() const; QString extractClassName(const QString &string) const; virtual QString qmlTypeName() const { return name_; } virtual QString qmlFullBaseName() const { return QString(); } @@ -318,7 +321,7 @@ public: virtual void setOutputSubdirectory(const QString& t) { outSubDir_ = t; } QString fullDocumentName() const; static QString cleanId(const QString &str); - QString idForNode() const; + //QString idForNode() const; static FlagValue toFlagValue(bool b); static bool fromFlagValue(FlagValue fv, bool defaultValue); @@ -357,12 +360,13 @@ private: QString since_; QString templateStuff_; QString reconstitutedBrief_; - mutable QString uuid_; + //mutable QString uuid_; QString outSubDir_; static QStringMap operators_; static int propertyGroupCount_; static QMap<QString,Node::NodeType> goals_; }; +Q_DECLARE_TYPEINFO(Node::DocSubtype, Q_PRIMITIVE_TYPE); class Aggregate : public Node { @@ -376,7 +380,6 @@ public: FunctionNode* findFunctionNode(const FunctionNode* clone) const; void addInclude(const QString &include); void setIncludes(const QStringList &includes); - void setOverload(FunctionNode* func, bool overlode); void normalizeOverloads(); void makeUndocumentedChildrenInternal(); void deleteChildren(); @@ -389,7 +392,6 @@ public: const NodeList & relatedNodes() const { return related_; } int count() const { return children_.size(); } - int overloadNumber(const FunctionNode* func) const; NodeList overloads(const QString &funcName) const; const QStringList& includes() const { return includes_; } @@ -408,6 +410,8 @@ public: void addChild(Node* child); void removeChild(Node* child); void setOutputSubdirectory(const QString& t) Q_DECL_OVERRIDE; + const NodeMap& primaryFunctionMap() { return primaryFunctionMap_; } + const QMap<QString, NodeList>& secondaryFunctionMap() { return secondaryFunctionMap_; } protected: Aggregate(NodeType type, Aggregate* parent, const QString& name); @@ -425,9 +429,9 @@ private: NodeList children_; NodeList enumChildren_; NodeList related_; - QMap<QString, Node*> childMap; - QMap<QString, Node*> primaryFunctionMap; - QMap<QString, NodeList> secondaryFunctionMap; + NodeMap childMap_; + NodeMap primaryFunctionMap_; + QMap<QString, NodeList> secondaryFunctionMap_; }; class LeafNode : public Node @@ -776,6 +780,7 @@ public: void addItem(const EnumItem& item); void setFlagsType(TypedefNode* typedeff); bool hasItem(const QString &name) const { return names_.contains(name); } + virtual bool isEnumType() const Q_DECL_OVERRIDE { return true; } const QList<EnumItem>& items() const { return items_; } Access itemAccess(const QString& name) const; @@ -864,7 +869,9 @@ public: void setVirtualness(Virtualness v); void setConst(bool b) { const_ = b; } void setStatic(bool b) { static_ = b; } - void setOverload(bool b); + unsigned char overloadNumber() const { return overloadNumber_; } + void setOverloadFlag(bool b) { overload_ = b; } + void setOverloadNumber(unsigned char n) { overloadNumber_ = n; } void setReimplemented(bool b); void addParameter(const Parameter& parameter); inline void setParameters(const QList<Parameter>& parameters); @@ -900,15 +907,18 @@ public: virtual bool isJsMethod() const Q_DECL_OVERRIDE { return (type() == Node::QmlMethod) && (genus() == Node::JS); } - int overloadNumber() const; const QList<Parameter>& parameters() const { return parameters_; } void clearParams() { parameters_.clear(); } QStringList parameterNames() const; QString rawParameters(bool names = false, bool values = false) const; const FunctionNode* reimplementedFrom() const { return reimplementedFrom_; } const QList<FunctionNode*> &reimplementedBy() const { return reimplementedBy_; } - const PropertyNode* associatedProperty() const { return associatedProperty_; } + const PropNodeList& associatedProperties() const { return associatedProperties_; } const QStringList& parentPath() const { return parentPath_; } + bool hasAssociatedProperties() const { return !associatedProperties_.isEmpty(); } + bool hasOneAssociatedProperty() const { return (associatedProperties_.size() == 1); } + PropertyNode* firstAssociatedProperty() const { return associatedProperties_[0]; } + bool hasActiveAssociatedProperty() const; QStringList reconstructParameters(bool values = false) const; QString signature(bool values = false) const; @@ -931,7 +941,7 @@ public: void debug() const; private: - void setAssociatedProperty(PropertyNode* property); + void addAssociatedProperty(PropertyNode* property); friend class Aggregate; friend class PropertyNode; @@ -942,13 +952,14 @@ private: Virtualness virtualness_; bool const_ : 1; bool static_ : 1; - bool overload_ : 1; bool reimplemented_: 1; bool attached_: 1; bool privateSignal_: 1; + bool overload_ : 1; + unsigned char overloadNumber_; QList<Parameter> parameters_; const FunctionNode* reimplementedFrom_; - const PropertyNode* associatedProperty_; + PropNodeList associatedProperties_; QList<FunctionNode*> reimplementedBy_; }; @@ -985,6 +996,7 @@ public: NodeList setters() const { return functions(Setter); } NodeList resetters() const { return functions(Resetter); } NodeList notifiers() const { return functions(Notifier); } + FunctionRole role(const FunctionNode* fn) const; bool isStored() const { return fromFlagValue(stored_, storedDefault()); } bool isDesignable() const { return fromFlagValue(designable_, designableDefault()); } bool isScriptable() const { return fromFlagValue(scriptable_, scriptableDefault()); } @@ -1026,13 +1038,13 @@ inline void FunctionNode::setParameters(const QList<Parameter> &p) inline void PropertyNode::addFunction(FunctionNode* function, FunctionRole role) { functions_[(int)role].append(function); - function->setAssociatedProperty(this); + function->addAssociatedProperty(this); } inline void PropertyNode::addSignal(FunctionNode* function, FunctionRole role) { functions_[(int)role].append(function); - function->setAssociatedProperty(this); + function->addAssociatedProperty(this); } inline NodeList PropertyNode::functions() const @@ -1086,7 +1098,8 @@ class CollectionNode : public Aggregate CollectionNode(NodeType type, Aggregate* parent, const QString& name, - Genus genus) : Aggregate(type, parent, name), seen_(false) + Genus genus) + : Aggregate(type, parent, name), seen_(false), noAutoList_(false) { setPageType(Node::OverviewPage); setGenus(genus); @@ -1105,7 +1118,7 @@ class CollectionNode : public Aggregate virtual bool hasNamespaces() const Q_DECL_OVERRIDE; virtual bool hasClasses() const Q_DECL_OVERRIDE; virtual void getMemberNamespaces(NodeMap& out) Q_DECL_OVERRIDE; - virtual void getMemberClasses(NodeMap& out) Q_DECL_OVERRIDE; + virtual void getMemberClasses(NodeMap& out) const Q_DECL_OVERRIDE; virtual bool wasSeen() const Q_DECL_OVERRIDE { return seen_; } virtual QString title() const Q_DECL_OVERRIDE { return title_; } virtual QString subTitle() const Q_DECL_OVERRIDE { return subtitle_; } @@ -1129,9 +1142,12 @@ class CollectionNode : public Aggregate void markSeen() { seen_ = true; } void markNotSeen() { seen_ = false; } + bool noAutoList() const { return noAutoList_; } + virtual void setNoAutoList(bool b) Q_DECL_OVERRIDE { noAutoList_ = b; } private: bool seen_; + bool noAutoList_; QString title_; QString subtitle_; NodeList members_; diff --git a/src/tools/qdoc/openedlist.h b/src/tools/qdoc/openedlist.h index ee45714cfdf7cc1e1ca0b8d41b56519c563c422b..3a564b018da539dab804e588f95d9786fd8d2908 100644 --- a/src/tools/qdoc/openedlist.h +++ b/src/tools/qdoc/openedlist.h @@ -79,6 +79,7 @@ private: QString pref; QString suff; }; +Q_DECLARE_TYPEINFO(OpenedList, Q_MOVABLE_TYPE); QT_END_NAMESPACE diff --git a/src/tools/qdoc/puredocparser.cpp b/src/tools/qdoc/puredocparser.cpp index bfd39253534af1e6db1fd9351fba80e25edeb78a..80a7ec4bf59a1724de7ff4e7a54cb06401fdfec7 100644 --- a/src/tools/qdoc/puredocparser.cpp +++ b/src/tools/qdoc/puredocparser.cpp @@ -149,12 +149,6 @@ bool PureDocParser::processQdocComments() isJsPropertyTopic = true; } } - if ((isQmlPropertyTopic || isJsPropertyTopic) && topics.size() > 1) { - qDebug() << "MULTIPLE TOPICS:" << doc.location().fileName() << doc.location().lineNo(); - for (int i=0; i<topics.size(); ++i) { - qDebug() << " " << topics[i].topic << topics[i].args; - } - } NodeList nodes; DocList docs; diff --git a/src/tools/qdoc/qdoc.pro b/src/tools/qdoc/qdoc.pro index f0df113af8384601c3eb4db5ece5745f8e9dddc8..634d30a9a37feec0cff3e9a26b3494a2ae1b5fdf 100644 --- a/src/tools/qdoc/qdoc.pro +++ b/src/tools/qdoc/qdoc.pro @@ -1,11 +1,10 @@ !force_bootstrap { load(qfeatures) requires(!contains(QT_DISABLED_FEATURES, xmlstreamwriter)) - requires(!contains(QT_DISABLED_FEATURES, dom)) } option(host_build) -QT = core xml +QT = core DEFINES += \ QT_QMLDEVTOOLS_LIB \ # force static exports even if not bootstrapping diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp index f10072a94307a9a83f7b984daae175ea3590b1cd..5f2a61bb7656361c28f5dae831433fc2a8e51001 100644 --- a/src/tools/qdoc/qdocdatabase.cpp +++ b/src/tools/qdoc/qdocdatabase.cpp @@ -167,7 +167,7 @@ void QDocForest::setSearchOrder(QStringList& t) forest_.remove(primaryName); QMap<QString, Tree*>::iterator i; - foreach (QString m, t) { + foreach (const QString &m, t) { if (primaryName != m) { i = forest_.find(m); if (i != forest_.end()) { @@ -1264,6 +1264,10 @@ const NodeMap& QDocDatabase::getSinceMap(const QString& key) to generating documentation. */ void QDocDatabase::resolveIssues() { + primaryTreeRoot()->normalizeOverloads(); + fixInheritance(); + resolveProperties(); + primaryTreeRoot()->makeUndocumentedChildrenInternal(); resolveQmlInheritance(primaryTreeRoot()); primaryTree()->resolveTargets(primaryTreeRoot()); primaryTree()->resolveCppToQmlLinks(); @@ -1277,6 +1281,7 @@ void QDocDatabase::resolveStuff() primaryTree()->resolveCppToQmlLinks(); primaryTree()->resolveUsingClauses(); resolveNamespaces(); + primaryTreeRoot()->normalizeOverloads(); } /*! @@ -1291,7 +1296,7 @@ void QDocDatabase::resolveNamespaces() t = forest_.nextTree(); } QList<QString> keys = nmm_.uniqueKeys(); - foreach (QString s, keys) { + foreach (const QString &s, keys) { NamespaceNode* ns = 0; QList<Node*> nodes = nmm_.values(s); int count = nmm_.remove(s); @@ -1574,6 +1579,13 @@ void QDocDatabase::mergeCollections(Node::Genus genus, CNMap& cnm, const Node* r if (values.size() > 1) { foreach (CollectionNode* v, values) { if (v != n) { + // Allow multiple (major) versions of QML/JS modules + if (n->type() == Node::QmlModule + && n->logicalModuleIdentifier() != v->logicalModuleIdentifier()) { + if (v->wasSeen() && v != relative && !v->members().isEmpty()) + cnm.insert(v->fullTitle().toLower(), v); + continue; + } foreach (Node* t, v->members()) n->addMember(t); } @@ -1594,12 +1606,19 @@ void QDocDatabase::mergeCollections(Node::Genus genus, CNMap& cnm, const Node* r Finds all the collection nodes with the same name and genus as \a c and merges their members into the members list of \a c. + + For QML and JS modules, the merge is done only if + the module identifier matches between the nodes, to avoid + merging modules with different (major) versions. */ void QDocDatabase::mergeCollections(CollectionNode* c) { foreach (Tree* t, searchOrder()) { CollectionNode* cn = t->getCollection(c->name(), c->genus()); if (cn && cn != c) { + if (cn->type() == Node::QmlModule + && cn->logicalModuleIdentifier() != c->logicalModuleIdentifier()) + continue; foreach (Node* n, cn->members()) c->addMember(n); } diff --git a/src/tools/qdoc/qdocdatabase.h b/src/tools/qdoc/qdocdatabase.h index 6154ec762b178bcb530278c7d287ac3fc9c7c057..5d55ea48e13ac332ecca3a36b7d895ee67426d69 100644 --- a/src/tools/qdoc/qdocdatabase.h +++ b/src/tools/qdoc/qdocdatabase.h @@ -177,6 +177,16 @@ class QDocForest return 0; } + const CollectionNode* getCollectionNode(const QString& name, Node::Genus genus) + { + foreach (Tree* t, searchOrder()) { + const CollectionNode* cn = t->getCollection(name, genus); + if (cn) + return cn; + } + return 0; + } + QmlTypeNode* lookupQmlType(const QString& name) { foreach (Tree* t, searchOrder()) { @@ -221,19 +231,11 @@ class QDocDatabase Tree* findTree(const QString& t) { return forest_.findTree(t); } - CollectionNode* getCollection(const QString& name, Node::Genus genus) { - return primaryTree()->getCollection(name, genus); - } const CNMap& groups() { return primaryTree()->groups(); } const CNMap& modules() { return primaryTree()->modules(); } const CNMap& qmlModules() { return primaryTree()->qmlModules(); } const CNMap& jsModules() { return primaryTree()->jsModules(); } - CollectionNode* findGroup(const QString& name) { return primaryTree()->findGroup(name); } - CollectionNode* findModule(const QString& name) { return primaryTree()->findModule(name); } - CollectionNode* findQmlModule(const QString& name) { return primaryTree()->findQmlModule(name); } - CollectionNode* findJsModule(const QString& name) { return primaryTree()->findJsModule(name); } - CollectionNode* addGroup(const QString& name) { return primaryTree()->addGroup(name); } CollectionNode* addModule(const QString& name) { return primaryTree()->addModule(name); } CollectionNode* addQmlModule(const QString& name) { return primaryTree()->addQmlModule(name); } @@ -339,6 +341,9 @@ class QDocDatabase Node* findNodeByNameAndType(const QStringList& path, Node::NodeType type) { return forest_.findNodeByNameAndType(path, type); } + const CollectionNode* getCollectionNode(const QString& name, Node::Genus genus) { + return forest_.getCollectionNode(name, genus); + } private: const Node* findNodeForTarget(QStringList& targetPath, diff --git a/src/tools/qdoc/qdocindexfiles.cpp b/src/tools/qdoc/qdocindexfiles.cpp index 2e49c1c5945232ba3a1d32fa75eb70192c94036e..37194b911c179b22cd88adbbafbeb12bc6648a13 100644 --- a/src/tools/qdoc/qdocindexfiles.cpp +++ b/src/tools/qdoc/qdocindexfiles.cpp @@ -31,7 +31,6 @@ ** ****************************************************************************/ -#include "qdom.h" #include "qxmlstream.h" #include "qdocindexfiles.h" #include "qdoctagfiles.h" @@ -117,72 +116,83 @@ static bool readingRoot = true; void QDocIndexFiles::readIndexFile(const QString& path) { QFile file(path); - if (file.open(QFile::ReadOnly)) { - QDomDocument document; - document.setContent(&file); - file.close(); - - QDomElement indexElement = document.documentElement(); - - // Generate a relative URL between the install dir and the index file - // when the -installdir command line option is set. - QString indexUrl; - if (Config::installDir.isEmpty()) { - indexUrl = indexElement.attribute("url", QString()); - } - else { - // Use a fake directory, since we will copy the output to a sub directory of - // installDir when using "make install". This is just for a proper relative path. - //QDir installDir(path.section('/', 0, -3) + "/outputdir"); - QDir installDir(path.section('/', 0, -3) + '/' + Generator::outputSubdir()); - indexUrl = installDir.relativeFilePath(path).section('/', 0, -2); - } - project_ = indexElement.attribute("project", QString()); + if (!file.open(QFile::ReadOnly)) { + qWarning() << "Could not read index file" << path; + return; + } - basesList_.clear(); - relatedList_.clear(); + QXmlStreamReader reader(&file); + reader.setNamespaceProcessing(false); - readingRoot = true; - NamespaceNode* root = qdb_->newIndexTree(project_); - - // Scan all elements in the XML file, constructing a map that contains - // base classes for each class found. - QDomElement child = indexElement.firstChildElement(); - while (!child.isNull()) { - readIndexSection(child, root, indexUrl); - child = child.nextSiblingElement(); - readingRoot = true; - } + if (!reader.readNextStartElement()) + return; + + if (reader.name() != QLatin1String("INDEX")) + return; + + QXmlStreamAttributes attrs = reader.attributes(); + + // Generate a relative URL between the install dir and the index file + // when the -installdir command line option is set. + QString indexUrl; + if (Config::installDir.isEmpty()) { + indexUrl = attrs.value(QLatin1String("url")).toString(); + } + else { + // Use a fake directory, since we will copy the output to a sub directory of + // installDir when using "make install". This is just for a proper relative path. + //QDir installDir(path.section('/', 0, -3) + "/outputdir"); + QDir installDir(path.section('/', 0, -3) + '/' + Generator::outputSubdir()); + indexUrl = installDir.relativeFilePath(path).section('/', 0, -2); + } + project_ = attrs.value(QLatin1String("project")).toString(); + + basesList_.clear(); + relatedList_.clear(); - // Now that all the base classes have been found for this index, - // arrange them into an inheritance hierarchy. - resolveIndex(); + NamespaceNode* root = qdb_->newIndexTree(project_); + + // Scan all elements in the XML file, constructing a map that contains + // base classes for each class found. + while (reader.readNextStartElement()) { + readingRoot = true; + readIndexSection(reader, root, indexUrl); } + + // Now that all the base classes have been found for this index, + // arrange them into an inheritance hierarchy. + resolveIndex(); } /*! Read a <section> element from the index file and create the appropriate node(s). */ -void QDocIndexFiles::readIndexSection(const QDomElement& element, +void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader, Node* current, const QString& indexUrl) { - QString name = element.attribute("name"); - QString href = element.attribute("href"); + QXmlStreamAttributes attributes = reader.attributes(); + QStringRef elementName = reader.name(); + + QString name = attributes.value(QLatin1String("name")).toString(); + QString href = attributes.value(QLatin1String("href")).toString(); Node* node; Location location; Aggregate* parent = 0; + + bool hasReadChildren = false; + if (current->isAggregate()) parent = static_cast<Aggregate*>(current); QString filePath; int lineNo = 0; - if (element.hasAttribute("filepath")) { - filePath = element.attribute("filepath", QString()); - lineNo = element.attribute("lineno", QString()).toInt(); + if (attributes.hasAttribute(QLatin1String("filepath"))) { + filePath = attributes.value(QLatin1String("filepath")).toString(); + lineNo = attributes.value("lineno").toInt(); } - if (element.nodeName() == "namespace") { + if (elementName == QLatin1String("namespace")) { node = new NamespaceNode(parent, name); if (!indexUrl.isEmpty()) @@ -191,10 +201,10 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element, location = Location(name.toLower() + ".html"); } - else if (element.nodeName() == "class") { + else if (elementName == QLatin1String("class")) { node = new ClassNode(parent, name); - if (element.hasAttribute("bases")) { - QString bases = element.attribute("bases"); + if (attributes.hasAttribute(QLatin1String("bases"))) { + QString bases = attributes.value(QLatin1String("bases")).toString(); if (!bases.isEmpty()) basesList_.append(QPair<ClassNode*,QString>(static_cast<ClassNode*>(node), bases)); } @@ -203,108 +213,108 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element, else if (!indexUrl.isNull()) location = Location(name.toLower() + ".html"); bool abstract = false; - if (element.attribute("abstract") == "true") + if (attributes.value(QLatin1String("abstract")) == QLatin1String("true")) abstract = true; node->setAbstract(abstract); } - else if (element.nodeName() == "qmlclass") { + else if (elementName == QLatin1String("qmlclass")) { QmlTypeNode* qcn = new QmlTypeNode(parent, name); - qcn->setTitle(element.attribute("title")); - QString logicalModuleName = element.attribute("qml-module-name"); + qcn->setTitle(attributes.value(QLatin1String("title")).toString()); + QString logicalModuleName = attributes.value(QLatin1String("qml-module-name")).toString(); if (!logicalModuleName.isEmpty()) qdb_->addToQmlModule(logicalModuleName, qcn); bool abstract = false; - if (element.attribute("abstract") == "true") + if (attributes.value(QLatin1String("abstract")) == QLatin1String("true")) abstract = true; qcn->setAbstract(abstract); - QString qmlFullBaseName = element.attribute("qml-base-type"); + QString qmlFullBaseName = attributes.value(QLatin1String("qml-base-type")).toString(); if (!qmlFullBaseName.isEmpty()) { qcn->setQmlBaseName(qmlFullBaseName); } - if (element.hasAttribute("location")) - name = element.attribute("location", QString()); + if (attributes.hasAttribute(QLatin1String("location"))) + name = attributes.value("location").toString(); if (!indexUrl.isEmpty()) location = Location(indexUrl + QLatin1Char('/') + name); else if (!indexUrl.isNull()) location = Location(name); node = qcn; } - else if (element.nodeName() == "jstype") { + else if (elementName == QLatin1String("jstype")) { QmlTypeNode* qcn = new QmlTypeNode(parent, name); qcn->setGenus(Node::JS); - qcn->setTitle(element.attribute("title")); - QString logicalModuleName = element.attribute("js-module-name"); + qcn->setTitle(attributes.value(QLatin1String("title")).toString()); + QString logicalModuleName = attributes.value(QLatin1String("js-module-name")).toString(); if (!logicalModuleName.isEmpty()) qdb_->addToQmlModule(logicalModuleName, qcn); bool abstract = false; - if (element.attribute("abstract") == "true") + if (attributes.value(QLatin1String("abstract")) == QLatin1String("true")) abstract = true; qcn->setAbstract(abstract); - QString qmlFullBaseName = element.attribute("js-base-type"); + QString qmlFullBaseName = attributes.value(QLatin1String("js-base-type")).toString(); if (!qmlFullBaseName.isEmpty()) { qcn->setQmlBaseName(qmlFullBaseName); } - if (element.hasAttribute("location")) - name = element.attribute("location", QString()); + if (attributes.hasAttribute(QLatin1String("location"))) + name = attributes.value("location").toString(); if (!indexUrl.isEmpty()) location = Location(indexUrl + QLatin1Char('/') + name); else if (!indexUrl.isNull()) location = Location(name); node = qcn; } - else if (element.nodeName() == "qmlbasictype") { + else if (elementName == QLatin1String("qmlbasictype")) { QmlBasicTypeNode* qbtn = new QmlBasicTypeNode(parent, name); - qbtn->setTitle(element.attribute("title")); - if (element.hasAttribute("location")) - name = element.attribute("location", QString()); + qbtn->setTitle(attributes.value(QLatin1String("title")).toString()); + if (attributes.hasAttribute(QLatin1String("location"))) + name = attributes.value("location").toString(); if (!indexUrl.isEmpty()) location = Location(indexUrl + QLatin1Char('/') + name); else if (!indexUrl.isNull()) location = Location(name); node = qbtn; } - else if (element.nodeName() == "jsbasictype") { + else if (elementName == QLatin1String("jsbasictype")) { QmlBasicTypeNode* qbtn = new QmlBasicTypeNode(parent, name); qbtn->setGenus(Node::JS); - qbtn->setTitle(element.attribute("title")); - if (element.hasAttribute("location")) - name = element.attribute("location", QString()); + qbtn->setTitle(attributes.value(QLatin1String("title")).toString()); + if (attributes.hasAttribute(QLatin1String("location"))) + name = attributes.value("location").toString(); if (!indexUrl.isEmpty()) location = Location(indexUrl + QLatin1Char('/') + name); else if (!indexUrl.isNull()) location = Location(name); node = qbtn; } - else if (element.nodeName() == "qmlpropertygroup") { + else if (elementName == QLatin1String("qmlpropertygroup")) { QmlTypeNode* qcn = static_cast<QmlTypeNode*>(parent); QmlPropertyGroupNode* qpgn = new QmlPropertyGroupNode(qcn, name); - if (element.hasAttribute("location")) - name = element.attribute("location", QString()); + if (attributes.hasAttribute(QLatin1String("location"))) + name = attributes.value("location").toString(); if (!indexUrl.isEmpty()) location = Location(indexUrl + QLatin1Char('/') + name); else if (!indexUrl.isNull()) location = Location(name); node = qpgn; } - else if (element.nodeName() == "jspropertygroup") { + else if (elementName == QLatin1String("jspropertygroup")) { QmlTypeNode* qcn = static_cast<QmlTypeNode*>(parent); QmlPropertyGroupNode* qpgn = new QmlPropertyGroupNode(qcn, name); qpgn->setGenus(Node::JS); - if (element.hasAttribute("location")) - name = element.attribute("location", QString()); + if (attributes.hasAttribute(QLatin1String("location"))) + name = attributes.value("location").toString(); if (!indexUrl.isEmpty()) location = Location(indexUrl + QLatin1Char('/') + name); else if (!indexUrl.isNull()) location = Location(name); node = qpgn; } - else if (element.nodeName() == "qmlproperty") { - QString type = element.attribute("type"); + else if (elementName == QLatin1String("qmlproperty")) { + QString type = attributes.value(QLatin1String("type")).toString(); bool attached = false; - if (element.attribute("attached") == "true") + if (attributes.value(QLatin1String("attached")) == QLatin1String("true")) attached = true; bool readonly = false; - if (element.attribute("writable") == "false") + if (attributes.value(QLatin1String("writable")) == QLatin1String("false")) readonly = true; QmlPropertyNode* qpn = 0; if (parent->isQmlType()) { @@ -318,13 +328,13 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element, qpn->setReadOnly(readonly); node = qpn; } - else if (element.nodeName() == "jsproperty") { - QString type = element.attribute("type"); + else if (elementName == QLatin1String("jsproperty")) { + QString type = attributes.value(QLatin1String("type")).toString(); bool attached = false; - if (element.attribute("attached") == "true") + if (attributes.value(QLatin1String("attached")) == QLatin1String("true")) attached = true; bool readonly = false; - if (element.attribute("writable") == "false") + if (attributes.value(QLatin1String("writable")) == QLatin1String("false")) readonly = true; QmlPropertyNode* qpn = 0; if (parent->isJsType()) { @@ -339,103 +349,103 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element, qpn->setReadOnly(readonly); node = qpn; } - else if ((element.nodeName() == "qmlmethod") || - (element.nodeName() == "qmlsignal") || - (element.nodeName() == "qmlsignalhandler")) { + else if ((elementName == QLatin1String("qmlmethod")) || + (elementName == QLatin1String("qmlsignal")) || + (elementName == QLatin1String("qmlsignalhandler"))) { Node::NodeType t = Node::QmlMethod; - if (element.nodeName() == "qmlsignal") + if (elementName == QLatin1String("qmlsignal")) t = Node::QmlSignal; - else if (element.nodeName() == "qmlsignalhandler") + else if (elementName == QLatin1String("qmlsignalhandler")) t = Node::QmlSignalHandler; bool attached = false; FunctionNode* fn = new FunctionNode(t, parent, name, attached); node = fn; } - else if ((element.nodeName() == "jsmethod") || - (element.nodeName() == "jssignal") || - (element.nodeName() == "jssignalhandler")) { + else if ((elementName == QLatin1String("jsmethod")) || + (elementName == QLatin1String("jssignal")) || + (elementName == QLatin1String("jssignalhandler"))) { Node::NodeType t = Node::QmlMethod; - if (element.nodeName() == "jssignal") + if (elementName == QLatin1String("jssignal")) t = Node::QmlSignal; - else if (element.nodeName() == "jssignalhandler") + else if (elementName == QLatin1String("jssignalhandler")) t = Node::QmlSignalHandler; bool attached = false; FunctionNode* fn = new FunctionNode(t, parent, name, attached); fn->setGenus(Node::JS); node = fn; } - else if (element.nodeName() == "group") { + else if (elementName == QLatin1String("group")) { CollectionNode* cn = qdb_->addGroup(name); - cn->setTitle(element.attribute("title")); - cn->setSubTitle(element.attribute("subtitle")); - if (element.attribute("seen") == "true") + cn->setTitle(attributes.value(QLatin1String("title")).toString()); + cn->setSubTitle(attributes.value(QLatin1String("subtitle")).toString()); + if (attributes.value(QLatin1String("seen")) == QLatin1String("true")) cn->markSeen(); node = cn; } - else if (element.nodeName() == "module") { + else if (elementName == QLatin1String("module")) { CollectionNode* cn = qdb_->addModule(name); - cn->setTitle(element.attribute("title")); - cn->setSubTitle(element.attribute("subtitle")); - if (element.attribute("seen") == "true") + cn->setTitle(attributes.value(QLatin1String("title")).toString()); + cn->setSubTitle(attributes.value(QLatin1String("subtitle")).toString()); + if (attributes.value(QLatin1String("seen")) == QLatin1String("true")) cn->markSeen(); node = cn; } - else if (element.nodeName() == "qmlmodule") { - QString t = element.attribute("qml-module-name"); + else if (elementName == QLatin1String("qmlmodule")) { + QString t = attributes.value(QLatin1String("qml-module-name")).toString(); CollectionNode* cn = qdb_->addQmlModule(t); QStringList info; - info << t << element.attribute("qml-module-version"); + info << t << attributes.value(QLatin1String("qml-module-version")).toString(); cn->setLogicalModuleInfo(info); - cn->setTitle(element.attribute("title")); - cn->setSubTitle(element.attribute("subtitle")); - if (element.attribute("seen") == "true") + cn->setTitle(attributes.value(QLatin1String("title")).toString()); + cn->setSubTitle(attributes.value(QLatin1String("subtitle")).toString()); + if (attributes.value(QLatin1String("seen")) == QLatin1String("true")) cn->markSeen(); node = cn; } - else if (element.nodeName() == "jsmodule") { - QString t = element.attribute("js-module-name"); + else if (elementName == QLatin1String("jsmodule")) { + QString t = attributes.value(QLatin1String("js-module-name")).toString(); CollectionNode* cn = qdb_->addJsModule(t); QStringList info; - info << t << element.attribute("js-module-version"); + info << t << attributes.value(QLatin1String("js-module-version")).toString(); cn->setLogicalModuleInfo(info); - cn->setTitle(element.attribute("title")); - cn->setSubTitle(element.attribute("subtitle")); - if (element.attribute("seen") == "true") + cn->setTitle(attributes.value(QLatin1String("title")).toString()); + cn->setSubTitle(attributes.value(QLatin1String("subtitle")).toString()); + if (attributes.value(QLatin1String("seen")) == QLatin1String("true")) cn->markSeen(); node = cn; } - else if (element.nodeName() == "page") { + else if (elementName == QLatin1String("page")) { Node::DocSubtype subtype; Node::PageType ptype = Node::NoPageType; - QString attr = element.attribute("subtype"); - if (attr == "example") { + QString attr = attributes.value(QLatin1String("subtype")).toString(); + if (attr == QLatin1String("example")) { subtype = Node::Example; ptype = Node::ExamplePage; } - else if (attr == "header") { + else if (attr == QLatin1String("header")) { subtype = Node::HeaderFile; ptype = Node::ApiPage; } - else if (attr == "file") { + else if (attr == QLatin1String("file")) { subtype = Node::File; ptype = Node::NoPageType; } - else if (attr == "page") { + else if (attr == QLatin1String("page")) { subtype = Node::Page; ptype = Node::ArticlePage; } - else if (attr == "externalpage") { + else if (attr == QLatin1String("externalpage")) { subtype = Node::ExternalPage; ptype = Node::ArticlePage; } else - return; + goto done; DocumentNode* docNode = new DocumentNode(parent, name, subtype, ptype); - docNode->setTitle(element.attribute("title")); + docNode->setTitle(attributes.value(QLatin1String("title")).toString()); - if (element.hasAttribute("location")) - name = element.attribute("location", QString()); + if (attributes.hasAttribute(QLatin1String("location"))) + name = attributes.value(QLatin1String("location")).toString(); if (!indexUrl.isEmpty()) location = Location(indexUrl + QLatin1Char('/') + name); @@ -445,7 +455,7 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element, node = docNode; } - else if (element.nodeName() == "enum") { + else if (elementName == QLatin1String("enum")) { EnumNode* enumNode = new EnumNode(parent, name); if (!indexUrl.isEmpty()) @@ -453,17 +463,20 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element, else if (!indexUrl.isNull()) location = Location(parent->name().toLower() + ".html"); - QDomElement child = element.firstChildElement("value"); - while (!child.isNull()) { - EnumItem item(child.attribute("name"), child.attribute("value")); - enumNode->addItem(item); - child = child.nextSiblingElement("value"); + while (reader.readNextStartElement()) { + if (reader.name() == QLatin1String("value")) { + QXmlStreamAttributes childAttributes = reader.attributes(); + EnumItem item(childAttributes.value(QLatin1String("name")).toString(), childAttributes.value(QLatin1String("value")).toString()); + enumNode->addItem(item); + } + reader.skipCurrentElement(); } node = enumNode; + hasReadChildren = true; } - else if (element.nodeName() == "typedef") { + else if (elementName == QLatin1String("typedef")) { node = new TypedefNode(parent, name); if (!indexUrl.isEmpty()) @@ -472,7 +485,7 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element, location = Location(parent->name().toLower() + ".html"); } - else if (element.nodeName() == "property") { + else if (elementName == QLatin1String("property")) { node = new PropertyNode(parent, name); if (!indexUrl.isEmpty()) @@ -481,68 +494,76 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element, location = Location(parent->name().toLower() + ".html"); } - else if (element.nodeName() == "function") { + else if (elementName == QLatin1String("function")) { FunctionNode::Virtualness virt; - QString t = element.attribute("virtual"); - if (t == "non") + QString t = attributes.value(QLatin1String("virtual")).toString(); + if (t == QLatin1String("non")) virt = FunctionNode::NonVirtual; - else if (t == "virtual") + else if (t == QLatin1String("virtual")) virt = FunctionNode::NormalVirtual; - else if (t == "pure") + else if (t == QLatin1String("pure")) virt = FunctionNode::PureVirtual; else - return; + goto done; - t = element.attribute("meta"); + t = attributes.value(QLatin1String("meta")).toString(); FunctionNode::Metaness meta; - if (t == "plain") + if (t == QLatin1String("plain")) meta = FunctionNode::Plain; - else if (t == "signal") + else if (t == QLatin1String("signal")) meta = FunctionNode::Signal; - else if (t == "slot") + else if (t == QLatin1String("slot")) meta = FunctionNode::Slot; - else if (t == "constructor") + else if (t == QLatin1String("constructor")) meta = FunctionNode::Ctor; - else if (t == "destructor") + else if (t == QLatin1String("destructor")) meta = FunctionNode::Dtor; - else if (t == "macro") + else if (t == QLatin1String("macro")) meta = FunctionNode::MacroWithParams; - else if (t == "macrowithparams") + else if (t == QLatin1String("macrowithparams")) meta = FunctionNode::MacroWithParams; - else if (t == "macrowithoutparams") + else if (t == QLatin1String("macrowithoutparams")) meta = FunctionNode::MacroWithoutParams; else - return; + goto done; FunctionNode* functionNode = new FunctionNode(parent, name); - functionNode->setReturnType(element.attribute("return")); + functionNode->setReturnType(attributes.value(QLatin1String("return")).toString()); functionNode->setVirtualness(virt); functionNode->setMetaness(meta); - functionNode->setConst(element.attribute("const") == "true"); - functionNode->setStatic(element.attribute("static") == "true"); - functionNode->setOverload(element.attribute("overload") == "true"); - - if (element.hasAttribute("relates") - && element.attribute("relates") != parent->name()) { + functionNode->setConst(attributes.value(QLatin1String("const")) == QLatin1String("true")); + functionNode->setStatic(attributes.value(QLatin1String("static")) == QLatin1String("true")); + if (attributes.value(QLatin1String("overload")) == QLatin1String("true")) { + functionNode->setOverloadFlag(true); + functionNode->setOverloadNumber(attributes.value(QLatin1String("overload-number")).toUInt()); + } + else { + functionNode->setOverloadFlag(false); + functionNode->setOverloadNumber(0); + } + if (attributes.hasAttribute(QLatin1String("relates")) + && attributes.value(QLatin1String("relates")) != parent->name()) { relatedList_.append( QPair<FunctionNode*,QString>(functionNode, - element.attribute("relates"))); + attributes.value(QLatin1String("relates")).toString())); } /* Note: The "signature" attribute was written to the index file, but it is not read back in. Is that ok? */ - QDomElement child = element.firstChildElement("parameter"); - while (!child.isNull()) { - // Do not use the default value for the parameter; it is not - // required, and has been known to cause problems. - Parameter parameter(child.attribute("left"), - child.attribute("right"), - child.attribute("name"), - QString()); // child.attribute("default") - functionNode->addParameter(parameter); - child = child.nextSiblingElement("parameter"); + while (reader.readNextStartElement()) { + if (reader.name() == QLatin1String("parameter")) { + QXmlStreamAttributes childAttributes = reader.attributes(); + // Do not use the default value for the parameter; it is not + // required, and has been known to cause problems. + Parameter parameter(childAttributes.value(QLatin1String("left")).toString(), + childAttributes.value(QLatin1String("right")).toString(), + childAttributes.value(QLatin1String("name")).toString(), + QString()); // childAttributes.value(QLatin1String("default")) + functionNode->addParameter(parameter); + } + reader.skipCurrentElement(); } node = functionNode; @@ -550,125 +571,134 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element, location = Location(indexUrl + QLatin1Char('/') + parent->name().toLower() + ".html"); else if (!indexUrl.isNull()) location = Location(parent->name().toLower() + ".html"); + + hasReadChildren = true; } - else if (element.nodeName() == "variable") { + else if (elementName == QLatin1String("variable")) { node = new VariableNode(parent, name); if (!indexUrl.isEmpty()) location = Location(indexUrl + QLatin1Char('/') + parent->name().toLower() + ".html"); else if (!indexUrl.isNull()) location = Location(parent->name().toLower() + ".html"); } - else if (element.nodeName() == "keyword") { - QString title = element.attribute("title"); + else if (elementName == QLatin1String("keyword")) { + QString title = attributes.value(QLatin1String("title")).toString(); qdb_->insertTarget(name, title, TargetRec::Keyword, current, 1); - return; + goto done; } - else if (element.nodeName() == "target") { - QString title = element.attribute("title"); + else if (elementName == QLatin1String("target")) { + QString title = attributes.value(QLatin1String("title")).toString(); qdb_->insertTarget(name, title, TargetRec::Target, current, 2); - return; + goto done; } - else if (element.nodeName() == "contents") { - QString title = element.attribute("title"); + else if (elementName == QLatin1String("contents")) { + QString title = attributes.value(QLatin1String("title")).toString(); qdb_->insertTarget(name, title, TargetRec::Contents, current, 3); - return; + goto done; } else - return; - - QString access = element.attribute("access"); - if (access == "public") - node->setAccess(Node::Public); - else if (access == "protected") - node->setAccess(Node::Protected); - else if ((access == "private") || (access == "internal")) - node->setAccess(Node::Private); - else - node->setAccess(Node::Public); - - if ((element.nodeName() != "page") && - (element.nodeName() != "qmlclass") && - (element.nodeName() != "qmlbasictype") && - (element.nodeName() != "jstype") && - (element.nodeName() != "jsbasictype")) { - QString threadSafety = element.attribute("threadsafety"); - if (threadSafety == "non-reentrant") - node->setThreadSafeness(Node::NonReentrant); - else if (threadSafety == "reentrant") - node->setThreadSafeness(Node::Reentrant); - else if (threadSafety == "thread safe") - node->setThreadSafeness(Node::ThreadSafe); + goto done; + + { + QString access = attributes.value(QLatin1String("access")).toString(); + if (access == "public") + node->setAccess(Node::Public); + else if (access == "protected") + node->setAccess(Node::Protected); + else if ((access == "private") || (access == "internal")) + node->setAccess(Node::Private); + else + node->setAccess(Node::Public); + + if ((elementName != QLatin1String("page")) && + (elementName != QLatin1String("qmlclass")) && + (elementName != QLatin1String("qmlbasictype")) && + (elementName != QLatin1String("jstype")) && + (elementName != QLatin1String("jsbasictype"))) { + QString threadSafety = attributes.value(QLatin1String("threadsafety")).toString(); + if (threadSafety == QLatin1String("non-reentrant")) + node->setThreadSafeness(Node::NonReentrant); + else if (threadSafety == QLatin1String("reentrant")) + node->setThreadSafeness(Node::Reentrant); + else if (threadSafety == QLatin1String("thread safe")) + node->setThreadSafeness(Node::ThreadSafe); + else + node->setThreadSafeness(Node::UnspecifiedSafeness); + } else node->setThreadSafeness(Node::UnspecifiedSafeness); - } - else - node->setThreadSafeness(Node::UnspecifiedSafeness); - - QString status = element.attribute("status"); - if (status == "compat") - node->setStatus(Node::Compat); - else if (status == "obsolete") - node->setStatus(Node::Obsolete); - else if (status == "deprecated") - node->setStatus(Node::Obsolete); - else if (status == "preliminary") - node->setStatus(Node::Preliminary); - else if (status == "active") - node->setStatus(Node::Active); - else if (status == "internal") - node->setStatus(Node::Internal); - else - node->setStatus(Node::Active); - - QString physicalModuleName = element.attribute("module"); - if (!physicalModuleName.isEmpty()) - qdb_->addToModule(physicalModuleName, node); - if (!href.isEmpty()) { - if (node->isExternalPage()) - node->setUrl(href); - else if (!indexUrl.isEmpty()) - node->setUrl(indexUrl + QLatin1Char('/') + href); - } - QString since = element.attribute("since"); - if (!since.isEmpty()) { - node->setSince(since); - } + QString status = attributes.value(QLatin1String("status")).toString(); + if (status == QLatin1String("compat")) + node->setStatus(Node::Compat); + else if (status == QLatin1String("obsolete")) + node->setStatus(Node::Obsolete); + else if (status == QLatin1String("deprecated")) + node->setStatus(Node::Obsolete); + else if (status == QLatin1String("preliminary")) + node->setStatus(Node::Preliminary); + else if (status == QLatin1String("active")) + node->setStatus(Node::Active); + else if (status == QLatin1String("internal")) + node->setStatus(Node::Internal); + else + node->setStatus(Node::Active); + + QString physicalModuleName = attributes.value(QLatin1String("module")).toString(); + if (!physicalModuleName.isEmpty()) + qdb_->addToModule(physicalModuleName, node); + if (!href.isEmpty()) { + if (node->isExternalPage()) + node->setUrl(href); + else if (!indexUrl.isEmpty()) + node->setUrl(indexUrl + QLatin1Char('/') + href); + } - QString groupsAttr = element.attribute("groups"); - if (!groupsAttr.isEmpty()) { - QStringList groupNames = groupsAttr.split(","); - foreach (const QString &name, groupNames) { - qdb_->addToGroup(name, node); + QString since = attributes.value(QLatin1String("since")).toString(); + if (!since.isEmpty()) { + node->setSince(since); } - } - // Create some content for the node. - QSet<QString> emptySet; - Location t(filePath); - if (!filePath.isEmpty()) { - t.setLineNo(lineNo); - node->setLocation(t); - location = t; - } - Doc doc(location, location, " ", emptySet, emptySet); // placeholder - node->setDoc(doc); - node->setIndexNodeFlag(); - node->setOutputSubdirectory(project_.toLower()); - QString briefAttr = element.attribute("brief"); - if (!briefAttr.isEmpty()) { - node->setReconstitutedBrief(briefAttr); + QString groupsAttr = attributes.value(QLatin1String("groups")).toString(); + if (!groupsAttr.isEmpty()) { + QStringList groupNames = groupsAttr.split(","); + foreach (const QString &name, groupNames) { + qdb_->addToGroup(name, node); + } + } + + // Create some content for the node. + QSet<QString> emptySet; + Location t(filePath); + if (!filePath.isEmpty()) { + t.setLineNo(lineNo); + node->setLocation(t); + location = t; + } + Doc doc(location, location, " ", emptySet, emptySet); // placeholder + node->setDoc(doc); + node->setIndexNodeFlag(); + node->setOutputSubdirectory(project_.toLower()); + QString briefAttr = attributes.value(QLatin1String("brief")).toString(); + if (!briefAttr.isEmpty()) { + node->setReconstitutedBrief(briefAttr); + } + + if (!hasReadChildren) { + bool useParent = (elementName == QLatin1String("namespace") && name.isEmpty()); + while (reader.readNextStartElement()) { + if (useParent) + readIndexSection(reader, parent, indexUrl); + else + readIndexSection(reader, node, indexUrl); + } + } } - bool useParent = (element.nodeName() == "namespace" && name.isEmpty()); - if (element.hasChildNodes()) { - QDomElement child = element.firstChildElement(); - while (!child.isNull()) { - if (useParent) - readIndexSection(child, parent, indexUrl); - else - readIndexSection(child, node, indexUrl); - child = child.nextSiblingElement(); + done: + while (!reader.isEndElement()) { + if (reader.readNext() == QXmlStreamReader::Invalid) { + break; } } } @@ -1183,9 +1213,15 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer, if (functionNode->relates()) { writer.writeAttribute("relates", functionNode->relates()->name()); } - const PropertyNode* propertyNode = functionNode->associatedProperty(); - if (propertyNode) - writer.writeAttribute("associated-property", propertyNode->name()); + if (functionNode->hasAssociatedProperties()) { + QString associatedProperties; + foreach (PropertyNode* pn, functionNode->associatedProperties()) { + if (!associatedProperties.isEmpty()) + associatedProperties += QLatin1String(", "); + associatedProperties += pn->name(); + } + writer.writeAttribute("associated-property", associatedProperties); + } writer.writeAttribute("type", functionNode->returnType()); if (!brief.isEmpty()) writer.writeAttribute("brief", brief); diff --git a/src/tools/qdoc/qdocindexfiles.h b/src/tools/qdoc/qdocindexfiles.h index 9a18639251b2157c0c43334fc72985991f6ac8dd..1b9b6afc40a0fc81de116191ee88735d5b9edac6 100644 --- a/src/tools/qdoc/qdocindexfiles.h +++ b/src/tools/qdoc/qdocindexfiles.h @@ -42,7 +42,6 @@ class Atom; class Generator; class QStringList; class QDocDatabase; -class QDomElement; class QXmlStreamWriter; class QDocIndexFiles @@ -64,7 +63,7 @@ class QDocIndexFiles bool generateInternalNodes = false); void readIndexFile(const QString& path); - void readIndexSection(const QDomElement& element, Node* current, const QString& indexUrl); + void readIndexSection(QXmlStreamReader &reader, Node* current, const QString& indexUrl); void resolveIndex(); bool generateIndexSection(QXmlStreamWriter& writer, Node* node, bool generateInternalNodes = false); void generateIndexSections(QXmlStreamWriter& writer, Node* node, bool generateInternalNodes = false); @@ -74,8 +73,8 @@ class QDocIndexFiles QDocDatabase* qdb_; Generator* gen_; QString project_; - QList<QPair<ClassNode*,QString> > basesList_; - QList<QPair<FunctionNode*,QString> > relatedList_; + QVector<QPair<ClassNode*,QString> > basesList_; + QVector<QPair<FunctionNode*,QString> > relatedList_; }; QT_END_NAMESPACE diff --git a/src/tools/qdoc/qdoctagfiles.cpp b/src/tools/qdoc/qdoctagfiles.cpp index 7a1902bbca1ae11dc79afa03f45314f5608ea661..1210ac7c36bfeacd69a326d0e26f2abfa11c23af 100644 --- a/src/tools/qdoc/qdoctagfiles.cpp +++ b/src/tools/qdoc/qdoctagfiles.cpp @@ -35,7 +35,6 @@ #include "qdoctagfiles.h" #include "qdocdatabase.h" -#include "qdom.h" #include "atom.h" #include "doc.h" #include "htmlgenerator.h" diff --git a/src/tools/qdoc/qmlcodemarker.cpp b/src/tools/qdoc/qmlcodemarker.cpp index 17067bebe6a02ec8bce9476b4504d4e01596b4fd..cfb5e16b442e645ef904bf2e28b4018695edb268 100644 --- a/src/tools/qdoc/qmlcodemarker.cpp +++ b/src/tools/qdoc/qmlcodemarker.cpp @@ -166,7 +166,7 @@ QString QmlCodeMarker::addMarkUp(const QString &code, QQmlJS::Lexer lexer(&engine); QString newCode = code; - QList<QQmlJS::AST::SourceLocation> pragmas = extractPragmas(newCode); + QVector<QQmlJS::AST::SourceLocation> pragmas = extractPragmas(newCode); lexer.setCode(newCode, 1); QQmlJS::Parser parser(&engine); @@ -209,11 +209,11 @@ static void replaceWithSpace(QString &str, int idx, int n) Searches for ".pragma <value>" or ".import <stuff>" declarations in \a script. Currently supported pragmas are: library */ -QList<QQmlJS::AST::SourceLocation> QmlCodeMarker::extractPragmas(QString &script) +QVector<QQmlJS::AST::SourceLocation> QmlCodeMarker::extractPragmas(QString &script) { const QString pragma(QLatin1String("pragma")); const QString library(QLatin1String("library")); - QList<QQmlJS::AST::SourceLocation> removed; + QVector<QQmlJS::AST::SourceLocation> removed; QQmlJS::Lexer l(0); l.setCode(script, 0); diff --git a/src/tools/qdoc/qmlcodemarker.h b/src/tools/qdoc/qmlcodemarker.h index dabb0d8233526fe54183dc570c29bd8d4d9b12e0..b3ec03965f18dc142ba41c56d94d6fccdd933389 100644 --- a/src/tools/qdoc/qmlcodemarker.h +++ b/src/tools/qdoc/qmlcodemarker.h @@ -66,7 +66,7 @@ public: virtual QString functionEndRegExp(const QString &funcName) Q_DECL_OVERRIDE; /* Copied from src/declarative/qml/qdeclarativescriptparser.cpp */ - QList<QQmlJS::AST::SourceLocation> extractPragmas(QString &script); + QVector<QQmlJS::AST::SourceLocation> extractPragmas(QString &script); private: QString addMarkUp(const QString &code, const Node *relative, diff --git a/src/tools/qdoc/qmlcodeparser.cpp b/src/tools/qdoc/qmlcodeparser.cpp index f485255b8eae8c747a14f6e4842c94239e8c9129..bcc0fedc9aafbe0ce607c5c4a27412a54171a7fc 100644 --- a/src/tools/qdoc/qmlcodeparser.cpp +++ b/src/tools/qdoc/qmlcodeparser.cpp @@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE #define COMMAND_PRELIMINARY Doc::alias("preliminary") #define COMMAND_SINCE Doc::alias("since") #define COMMAND_WRAPPER Doc::alias("wrapper") +#define COMMAND_NOAUTOLIST Doc::alias("noautolist") #define COMMAND_ABSTRACT Doc::alias("abstract") #define COMMAND_QMLABSTRACT Doc::alias("qmlabstract") @@ -256,7 +257,8 @@ const QSet<QString>& QmlCodeParser::otherMetaCommands() << COMMAND_QMLABSTRACT << COMMAND_INQMLMODULE << COMMAND_INJSMODULE - << COMMAND_WRAPPER; + << COMMAND_WRAPPER + << COMMAND_NOAUTOLIST; } return otherMetaCommands_; } diff --git a/src/tools/qdoc/qmlmarkupvisitor.cpp b/src/tools/qdoc/qmlmarkupvisitor.cpp index ee86b6de3209542e7a646442f015db659dad295a..3a7635778e3c10359831927c71beaaeebed57ac1 100644 --- a/src/tools/qdoc/qmlmarkupvisitor.cpp +++ b/src/tools/qdoc/qmlmarkupvisitor.cpp @@ -42,7 +42,7 @@ QT_BEGIN_NAMESPACE QmlMarkupVisitor::QmlMarkupVisitor(const QString &source, - const QList<QQmlJS::AST::SourceLocation> &pragmas, + const QVector<QQmlJS::AST::SourceLocation> &pragmas, QQmlJS::Engine *engine) { this->source = source; @@ -54,21 +54,22 @@ QmlMarkupVisitor::QmlMarkupVisitor(const QString &source, // Merge the lists of locations of pragmas and comments in the source code. int i = 0; int j = 0; - while (i < engine->comments().length() && j < pragmas.length()) { - if (engine->comments()[i].offset < pragmas[j].offset) { + const QVector<QQmlJS::AST::SourceLocation> comments = engine->comments(); + while (i < comments.size() && j < pragmas.length()) { + if (comments[i].offset < pragmas[j].offset) { extraTypes.append(Comment); - extraLocations.append(engine->comments()[i]); + extraLocations.append(comments[i]); ++i; } else { extraTypes.append(Pragma); - extraLocations.append(engine->comments()[j]); + extraLocations.append(comments[j]); ++j; } } - while (i < engine->comments().length()) { + while (i < comments.size()) { extraTypes.append(Comment); - extraLocations.append(engine->comments()[i]); + extraLocations.append(comments[i]); ++i; } diff --git a/src/tools/qdoc/qmlmarkupvisitor.h b/src/tools/qdoc/qmlmarkupvisitor.h index 04d6a57564ef772da18269adf08173ae757994e9..ddd16209ab37ab8242637ea90d1d880430ff8164 100644 --- a/src/tools/qdoc/qmlmarkupvisitor.h +++ b/src/tools/qdoc/qmlmarkupvisitor.h @@ -50,7 +50,7 @@ public: }; QmlMarkupVisitor(const QString &code, - const QList<QQmlJS::AST::SourceLocation> &pragmas, + const QVector<QQmlJS::AST::SourceLocation> &pragmas, QQmlJS::Engine *engine); virtual ~QmlMarkupVisitor(); @@ -157,13 +157,14 @@ private: QString sourceText(QQmlJS::AST::SourceLocation &location); QQmlJS::Engine *engine; - QList<ExtraType> extraTypes; - QList<QQmlJS::AST::SourceLocation> extraLocations; + QVector<ExtraType> extraTypes; + QVector<QQmlJS::AST::SourceLocation> extraLocations; QString source; QString output; quint32 cursor; int extraIndex; }; +Q_DECLARE_TYPEINFO(QmlMarkupVisitor::ExtraType, Q_PRIMITIVE_TYPE); QT_END_NAMESPACE diff --git a/src/tools/qdoc/qmlparser/qqmljsastfwd_p.h b/src/tools/qdoc/qmlparser/qqmljsastfwd_p.h index eae4125ab250d4db601e1fa84f567cb33c27546d..bfaa4401d23f3d2e7d7daf5ba2301b58de1f3fd6 100644 --- a/src/tools/qdoc/qmlparser/qqmljsastfwd_p.h +++ b/src/tools/qdoc/qmlparser/qqmljsastfwd_p.h @@ -37,6 +37,7 @@ #include "qqmljsglobal_p.h" #include <QtCore/qglobal.h> +#include <QtCore/qtypeinfo.h> // // W A R N I N G @@ -53,27 +54,6 @@ QT_QML_BEGIN_NAMESPACE namespace QQmlJS { namespace AST { -class SourceLocation -{ -public: - explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0) - : offset(offset), length(length), - startLine(line), startColumn(column) - { } - - bool isValid() const { return length != 0; } - - quint32 begin() const { return offset; } - quint32 end() const { return offset + length; } - -// attributes - // ### encode - quint32 offset; - quint32 length; - quint32 startLine; - quint32 startColumn; -}; - class Visitor; class Node; class ExpressionNode; @@ -176,8 +156,31 @@ class UiQualifiedId; class UiQualifiedPragmaId; class UiHeaderItemList; +class SourceLocation +{ +public: + explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0) + : offset(offset), length(length), + startLine(line), startColumn(column) + { } + + bool isValid() const { return length != 0; } + + quint32 begin() const { return offset; } + quint32 end() const { return offset + length; } + +// attributes + // ### encode + quint32 offset; + quint32 length; + quint32 startLine; + quint32 startColumn; +}; + } } // namespace AST +Q_DECLARE_TYPEINFO(QQmlJS::AST::SourceLocation, Q_PRIMITIVE_TYPE); + QT_QML_END_NAMESPACE #endif diff --git a/src/tools/qdoc/qmlparser/qqmljsengine_p.cpp b/src/tools/qdoc/qmlparser/qqmljsengine_p.cpp index 4e1305173045791726ad60d9bd20eb4536048e67..2a949b630c673e11311396c6e590ef07849cfe3f 100644 --- a/src/tools/qdoc/qmlparser/qqmljsengine_p.cpp +++ b/src/tools/qdoc/qmlparser/qqmljsengine_p.cpp @@ -125,7 +125,7 @@ void Engine::setCode(const QString &code) void Engine::addComment(int pos, int len, int line, int col) { if (len > 0) _comments.append(QQmlJS::AST::SourceLocation(pos, len, line, col)); } -QList<QQmlJS::AST::SourceLocation> Engine::comments() const +QVector<QQmlJS::AST::SourceLocation> Engine::comments() const { return _comments; } Lexer *Engine::lexer() const diff --git a/src/tools/qdoc/qmlparser/qqmljsengine_p.h b/src/tools/qdoc/qmlparser/qqmljsengine_p.h index fb65d7f028b47c72bc7edee78e56f0266be936c1..9ab26f0d0f1961e2438c87eb772ab6825a5864a3 100644 --- a/src/tools/qdoc/qmlparser/qqmljsengine_p.h +++ b/src/tools/qdoc/qmlparser/qqmljsengine_p.h @@ -50,7 +50,7 @@ #include "qqmljsmemorypool_p.h" #include <QtCore/qstring.h> -#include <QtCore/qset.h> +#include <QtCore/qvector.h> QT_QML_BEGIN_NAMESPACE @@ -87,7 +87,7 @@ class QML_PARSER_EXPORT Engine Lexer *_lexer; Directives *_directives; MemoryPool _pool; - QList<AST::SourceLocation> _comments; + QVector<AST::SourceLocation> _comments; QString _extraCode; QString _code; @@ -99,7 +99,7 @@ public: const QString &code() const { return _code; } void addComment(int pos, int len, int line, int col); - QList<AST::SourceLocation> comments() const; + QVector<AST::SourceLocation> comments() const; Lexer *lexer() const; void setLexer(Lexer *lexer); diff --git a/src/tools/qdoc/qmlvisitor.cpp b/src/tools/qdoc/qmlvisitor.cpp index 360af5adf6b5928169e960eda68b4f7d59db28e4..6f63624bf03ae14f0b9764b8100b441787cd2207 100644 --- a/src/tools/qdoc/qmlvisitor.cpp +++ b/src/tools/qdoc/qmlvisitor.cpp @@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE #define COMMAND_PRELIMINARY Doc::alias(QLatin1String("preliminary")) #define COMMAND_SINCE Doc::alias(QLatin1String("since")) #define COMMAND_WRAPPER Doc::alias(QLatin1String("wrapper")) +#define COMMAND_NOAUTOLIST Doc::alias(QLatin1String("noautolist")) #define COMMAND_ABSTRACT Doc::alias(QLatin1String("abstract")) #define COMMAND_QMLABSTRACT Doc::alias(QLatin1String("qmlabstract")) @@ -119,7 +120,7 @@ QmlDocVisitor::~QmlDocVisitor() */ QQmlJS::AST::SourceLocation QmlDocVisitor::precedingComment(quint32 offset) const { - QListIterator<QQmlJS::AST::SourceLocation> it(engine->comments()); + QVectorIterator<QQmlJS::AST::SourceLocation> it(engine->comments()); it.toBack(); while (it.hasPrevious()) { @@ -201,13 +202,6 @@ bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Nod node->setDoc(doc); nodes.append(node); if (topicsUsed.size() > 0) { - for (int i=0; i<topicsUsed.size(); ++i) { - if ((topicsUsed.at(i).topic == COMMAND_QMLPROPERTYGROUP) || - (topicsUsed.at(i).topic == COMMAND_JSPROPERTYGROUP)) { - qDebug() << "PROPERTY GROUP COMMAND SEEN:" << topicsUsed.at(i).args << filePath_; - break; - } - } for (int i=0; i<topicsUsed.size(); ++i) { QString topic = topicsUsed.at(i).topic; QString args = topicsUsed.at(i).args; @@ -752,14 +746,14 @@ bool QmlDocVisitor::visit(QQmlJS::AST::FunctionDeclaration* fd) if (current->isJsType()) qmlMethod->setGenus(Node::JS); int overloads = 0; - NodeList::ConstIterator overloadIterator = current->childNodes().constBegin(); - while (overloadIterator != current->childNodes().constEnd()) { - if ((*overloadIterator)->name() == name) + NodeList::ConstIterator i = current->childNodes().constBegin(); + while (i != current->childNodes().constEnd()) { + if ((*i)->name() == name) overloads++; - overloadIterator++; + i++; } if (overloads > 1) - qmlMethod->setOverload(true); + qmlMethod->setOverloadFlag(true); QList<Parameter> parameters; QQmlJS::AST::FormalParameterList* formals = fd->formals; if (formals) { diff --git a/src/tools/qdoc/quoter.cpp b/src/tools/qdoc/quoter.cpp index d8a4df33f3a6da4d94970db759e665b4baa68d61..25cf27f7310e57c42e2a898c03dc2ea73b15608b 100644 --- a/src/tools/qdoc/quoter.cpp +++ b/src/tools/qdoc/quoter.cpp @@ -39,6 +39,8 @@ QT_BEGIN_NAMESPACE +QHash<QString,QString> Quoter::commentHash; + static void replaceMultipleNewlines(QString &s) { const int n = s.size(); @@ -120,14 +122,16 @@ Quoter::Quoter() * .html, .qrc, .ui, .xq, .xml .dita files: <!-- [<id>] --> */ - commentHash["pro"] = "#!"; - commentHash["py"] = "#!"; - commentHash["html"] = "<!--"; - commentHash["qrc"] = "<!--"; - commentHash["ui"] = "<!--"; - commentHash["xml"] = "<!--"; - commentHash["dita"] = "<!--"; - commentHash["xq"] = "<!--"; + if (!commentHash.size()) { + commentHash["pro"] = "#!"; + commentHash["py"] = "#!"; + commentHash["html"] = "<!--"; + commentHash["qrc"] = "<!--"; + commentHash["ui"] = "<!--"; + commentHash["xml"] = "<!--"; + commentHash["dita"] = "<!--"; + commentHash["xq"] = "<!--"; + } } void Quoter::reset() diff --git a/src/tools/qdoc/quoter.h b/src/tools/qdoc/quoter.h index 2c3fa3980d3b6cdd5faa5d888b728ef953aa70c0..7877eda696e3585c16f5f8c174d39d450983ec85 100644 --- a/src/tools/qdoc/quoter.h +++ b/src/tools/qdoc/quoter.h @@ -78,7 +78,7 @@ private: QStringList plainLines; QStringList markedLines; Location codeLocation; - QHash<QString,QString> commentHash; + static QHash<QString,QString> commentHash; }; QT_END_NAMESPACE diff --git a/src/tools/qdoc/tokenizer.cpp b/src/tools/qdoc/tokenizer.cpp index 68c6fb7831a5c97ffb77aa13e9710519c54c6387..a85c3b00d83cec38e718f085b6536ae857c74c4b 100644 --- a/src/tools/qdoc/tokenizer.cpp +++ b/src/tools/qdoc/tokenizer.cpp @@ -186,7 +186,7 @@ int Tokenizer::getToken() } else if (strcmp(yyLex, kwords[i - 1]) == 0) { int ret = (int) Tok_FirstKeyword + i - 1; - if (ret != Tok_explicit && ret != Tok_inline && ret != Tok_typename) + if (ret != Tok_typename) return ret; break; } diff --git a/src/tools/qdoc/tokenizer.h b/src/tools/qdoc/tokenizer.h index 2b79320567d69ecfc6284a6b6b75880109a28081..41a3ffd93136eeb08b93d413416bac01c3f29a3e 100644 --- a/src/tools/qdoc/tokenizer.h +++ b/src/tools/qdoc/tokenizer.h @@ -107,6 +107,7 @@ public: int braceDepth() const { return yyBraceDepth; } int parenDepth() const { return yyParenDepth; } int bracketDepth() const { return yyBracketDepth; } + Location& tokenLocation() { return yyTokLoc; } static void initialize(const Config &config); static void terminate(); diff --git a/src/tools/qdoc/tree.cpp b/src/tools/qdoc/tree.cpp index 629514e7d1e3dae511a38121780a7fc7afcee52f..e0fd68d2e70f8bd4f1b10ec35dab5efd3ae185aa 100644 --- a/src/tools/qdoc/tree.cpp +++ b/src/tools/qdoc/tree.cpp @@ -327,6 +327,8 @@ Aggregate* Tree::findRelatesNode(const QStringList& path) } /*! + Inserts function name \a funcName and function role \a funcRole into + the property function map for the specified \a property. */ void Tree::addPropertyFunction(PropertyNode* property, const QString& funcName, @@ -993,7 +995,6 @@ void Tree::insertTarget(const QString& name, */ void Tree::resolveTargets(Aggregate* root) { - // need recursion foreach (Node* child, root->childNodes()) { if (child->type() == Node::Document) { DocumentNode* node = static_cast<DocumentNode*>(child); @@ -1037,9 +1038,8 @@ void Tree::resolveTargets(Aggregate* root) QString ref = refForAtom(keywords.at(i)); QString title = keywords.at(i)->string(); if (!ref.isEmpty() && !title.isEmpty()) { - QString key = Doc::canonicalTitle(title); TargetRec* target = new TargetRec(ref, title, TargetRec::Keyword, child, 1); - nodesByTargetRef_.insert(key, target); + nodesByTargetRef_.insert(Doc::canonicalTitle(title), target); nodesByTargetTitle_.insert(title, target); } } @@ -1057,6 +1057,8 @@ void Tree::resolveTargets(Aggregate* root) } } } + if (child->isAggregate()) + resolveTargets(static_cast<Aggregate*>(child)); } } @@ -1140,18 +1142,15 @@ const DocumentNode* Tree::findDocumentNodeByTitle(const QString& title) const DocumentNodeMultiMap::const_iterator j = i; ++j; if (j != docNodesByTitle_.constEnd() && j.key() == i.key()) { - QList<Location> internalLocations; while (j != docNodesByTitle_.constEnd()) { if (j.key() == i.key() && j.value()->url().isEmpty()) { - internalLocations.append(j.value()->location()); break; // Just report one duplicate for now. } ++j; } - if (internalLocations.size() > 0) { + if (j != docNodesByTitle_.cend()) { i.value()->location().warning("This page title exists in more than one file: " + title); - foreach (const Location &location, internalLocations) - location.warning("[It also exists here]"); + j.value()->location().warning("[It also exists here]"); } } return i.value(); diff --git a/src/tools/qdoc/tree.h b/src/tools/qdoc/tree.h index 0f41c221b61b836db079a364cd07c07f9cb8ca80..9e195c90ae27bd7808d854a95aa79997eff618c4 100644 --- a/src/tools/qdoc/tree.h +++ b/src/tools/qdoc/tree.h @@ -56,7 +56,12 @@ struct TargetRec TargetRec::TargetType type, Node* node, int priority) - : node_(node), ref_(name), title_(title), priority_(priority), type_(type) { } + : node_(node), ref_(name), title_(title), priority_(priority), type_(type) { + // Discard the dedicated ref for keywords - they always + // link to the top of the QDoc comment they appear in + if (type == Keyword) + ref_.clear(); + } bool isEmpty() const { return ref_.isEmpty(); } diff --git a/src/tools/qlalr/compress.cpp b/src/tools/qlalr/compress.cpp index 247b284421e60ea4caadfc4d9660031e97bbead2..fa67504a088622691dfcd0334295e4b29616ecd5 100644 --- a/src/tools/qlalr/compress.cpp +++ b/src/tools/qlalr/compress.cpp @@ -183,7 +183,7 @@ void Compress::operator () (int *table, int row_count, int column_count) index.fill (-999999, row_count); - foreach (UncompressedRow row, sortedTable) + foreach (const UncompressedRow &row, sortedTable) { int first_token = std::distance (row.begin (), row.beginNonZeros ()); QVector<int>::iterator pos = info.begin (); diff --git a/src/tools/qlalr/cppgenerator.cpp b/src/tools/qlalr/cppgenerator.cpp index 80f7a4ed2b2c09ec3fdd7f455a53290df37f2e45..3005690e6e71bd3ad05a509271c4c718343c6065 100644 --- a/src/tools/qlalr/cppgenerator.cpp +++ b/src/tools/qlalr/cppgenerator.cpp @@ -163,7 +163,7 @@ void CppGenerator::operator () () if (item->rule == grammar.goal) accept_state = q; - foreach (Name s, lookaheads) + foreach (const Name &s, lookaheads) { int &u = ACTION (q, aut.id (s)); @@ -616,7 +616,7 @@ void CppGenerator::generateImpl (QTextStream &out) out << name_ids.value(rule->lhs); - foreach (Name n, rule->rhs) + foreach (const Name &n, rule->rhs) out << ", " << name_ids.value (n); } out << "};" << endl << endl; diff --git a/src/tools/qlalr/lalr.cpp b/src/tools/qlalr/lalr.cpp index 3d780cd61819e12e761c8ea97dcb74faec0762a1..537051956e99e8d231934d8581b84126ed0eb470 100644 --- a/src/tools/qlalr/lalr.cpp +++ b/src/tools/qlalr/lalr.cpp @@ -367,7 +367,7 @@ void Automaton::closure (StatePointer state) if (_M_grammar->isNonTerminal (*item->dot)) { - foreach (RulePointer rule, _M_grammar->rule_map.values (*item->dot)) + foreach (const RulePointer &rule, _M_grammar->rule_map.values (*item->dot)) { Item ii; ii.rule = rule; @@ -413,7 +413,7 @@ void Automaton::buildLookbackSets () if (! _M_grammar->isNonTerminal (A)) continue; - foreach (RulePointer rule, _M_grammar->rule_map.values (A)) + foreach (const RulePointer &rule, _M_grammar->rule_map.values (A)) { StatePointer q = p; @@ -606,7 +606,7 @@ void Automaton::buildIncludesDigraph () if (! _M_grammar->isNonTerminal (name)) continue; - foreach (RulePointer rule, _M_grammar->rule_map.values (name)) + foreach (const RulePointer &rule, _M_grammar->rule_map.values (name)) { StatePointer p = pp; @@ -706,7 +706,7 @@ void Automaton::buildLookaheads () { for (ItemPointer item = p->closure.begin (); item != p->closure.end (); ++item) { - foreach (Lookback lookback, lookbacks.values (item)) + foreach (const Lookback &lookback, lookbacks.values (item)) { StatePointer q = lookback.state; diff --git a/src/tools/qlalr/lalr.h b/src/tools/qlalr/lalr.h index 138b1bb876d0d04a288bb516c1275eada9f16ade..bdd6609ba6242c1e5105139e645346245653e568 100644 --- a/src/tools/qlalr/lalr.h +++ b/src/tools/qlalr/lalr.h @@ -396,6 +396,9 @@ public: StatePointer state; Name nt; }; +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(OrderedSet<Node<Read> >::const_iterator, Q_PRIMITIVE_TYPE); +QT_END_NAMESPACE class Include { @@ -417,6 +420,9 @@ public: StatePointer state; Name nt; }; +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(OrderedSet<Node<Include> >::const_iterator, Q_PRIMITIVE_TYPE); +QT_END_NAMESPACE class Automaton { diff --git a/src/tools/qlalr/parsetable.cpp b/src/tools/qlalr/parsetable.cpp index 8b62e597ef0040ef42203c64cb27a00b46def607..77e22199878e42477de587a904d380bb325fece5 100644 --- a/src/tools/qlalr/parsetable.cpp +++ b/src/tools/qlalr/parsetable.cpp @@ -91,7 +91,7 @@ void ParseTable::operator () (Automaton *aut) first = false; - foreach (Name la, aut->lookaheads.value (item)) + foreach (const Name &la, aut->lookaheads.value (item)) out << " " << *la << " reduce using rule " << aut->id (item->rule) << " (" << *item->rule->lhs << ")" << endl; } diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index 71438726f731bb4f02a7d30800f1f8f6233acd3a..40e77c9876c64001f4fcbcbe2c65678c2f4b5114 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -366,6 +366,7 @@ enum RCCXmlTag { ResourceTag, FileTag }; +Q_DECLARE_TYPEINFO(RCCXmlTag, Q_PRIMITIVE_TYPE); bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice, const QString &fname, QString currentPath, bool ignoreErrors) @@ -693,7 +694,8 @@ QStringList RCCResourceLibrary::dataFiles() const RCCFileInfo *child = it.value(); if (child->m_flags & RCCFileInfo::Directory) pending.push(child); - ret.append(child->m_fileInfo.filePath()); + else + ret.append(child->m_fileInfo.filePath()); } } return ret; @@ -937,10 +939,14 @@ bool RCCResourceLibrary::writeDataNames() return true; } -static bool qt_rcc_compare_hash(const RCCFileInfo *left, const RCCFileInfo *right) +struct qt_rcc_compare_hash { - return qt_hash(left->m_name) < qt_hash(right->m_name); -} + typedef bool result_type; + result_type operator()(const RCCFileInfo *left, const RCCFileInfo *right) const + { + return qt_hash(left->m_name) < qt_hash(right->m_name); + } +}; bool RCCResourceLibrary::writeDataStructure() { @@ -962,7 +968,7 @@ bool RCCResourceLibrary::writeDataStructure() //sort by hash value for binary lookup QList<RCCFileInfo*> m_children = file->m_children.values(); - std::sort(m_children.begin(), m_children.end(), qt_rcc_compare_hash); + std::sort(m_children.begin(), m_children.end(), qt_rcc_compare_hash()); //write out the actual data now for (int i = 0; i < m_children.size(); ++i) { @@ -981,7 +987,7 @@ bool RCCResourceLibrary::writeDataStructure() //sort by hash value for binary lookup QList<RCCFileInfo*> m_children = file->m_children.values(); - std::sort(m_children.begin(), m_children.end(), qt_rcc_compare_hash); + std::sort(m_children.begin(), m_children.end(), qt_rcc_compare_hash()); //write out the actual data now for (int i = 0; i < m_children.size(); ++i) { diff --git a/src/widgets/accessible/complexwidgets.cpp b/src/widgets/accessible/complexwidgets.cpp index 60a1329d5e2a3d32eb2f7d33489274c85fa232aa..649a7f436335c97456dc6e5ac06323ca31fdbfbc 100644 --- a/src/widgets/accessible/complexwidgets.cpp +++ b/src/widgets/accessible/complexwidgets.cpp @@ -172,7 +172,7 @@ QAccessibleTabBar::QAccessibleTabBar(QWidget *w) QAccessibleTabBar::~QAccessibleTabBar() { - foreach (QAccessible::Id id, m_childInterfaces.values()) + foreach (QAccessible::Id id, m_childInterfaces) QAccessible::deleteAccessibleInterface(id); } diff --git a/src/widgets/accessible/itemviews.cpp b/src/widgets/accessible/itemviews.cpp index c7625c282765da3ac3c306cd79c32a492ccd7002..23a459c7e69653bbde7d83b447a43726fca3b5dd 100644 --- a/src/widgets/accessible/itemviews.cpp +++ b/src/widgets/accessible/itemviews.cpp @@ -94,7 +94,7 @@ bool QAccessibleTable::isValid() const QAccessibleTable::~QAccessibleTable() { - Q_FOREACH (QAccessible::Id id, childToId.values()) + Q_FOREACH (QAccessible::Id id, childToId) QAccessible::deleteAccessibleInterface(id); } @@ -198,7 +198,9 @@ QList<QAccessibleInterface *> QAccessibleTable::selectedCells() const QList<QAccessibleInterface*> cells; if (!view()->selectionModel()) return cells; - Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedIndexes()) + const QModelIndexList selectedIndexes = view()->selectionModel()->selectedIndexes(); + cells.reserve(selectedIndexes.size()); + Q_FOREACH (const QModelIndex &index, selectedIndexes) cells.append(child(logicalIndex(index))); return cells; } @@ -208,9 +210,11 @@ QList<int> QAccessibleTable::selectedColumns() const if (!view()->selectionModel()) return QList<int>(); QList<int> columns; - Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedColumns()) { + const QModelIndexList selectedColumns = view()->selectionModel()->selectedColumns(); + columns.reserve(selectedColumns.size()); + Q_FOREACH (const QModelIndex &index, selectedColumns) columns.append(index.column()); - } + return columns; } @@ -219,9 +223,11 @@ QList<int> QAccessibleTable::selectedRows() const if (!view()->selectionModel()) return QList<int>(); QList<int> rows; - Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedRows()) { + const QModelIndexList selectedRows = view()->selectionModel()->selectedRows(); + rows.reserve(selectedRows.size()); + Q_FOREACH (const QModelIndex &index, selectedRows) rows.append(index.row()); - } + return rows; } @@ -526,7 +532,7 @@ void QAccessibleTable::modelChange(QAccessibleTableModelChangeEvent *event) switch (event->modelChangeType()) { case QAccessibleTableModelChangeEvent::ModelReset: - Q_FOREACH (QAccessible::Id id, childToId.values()) + Q_FOREACH (QAccessible::Id id, childToId) QAccessible::deleteAccessibleInterface(id); childToId.clear(); break; diff --git a/src/widgets/accessible/itemviews.h b/src/widgets/accessible/itemviews.h index c1bd70a390509ed061dffbccb97ada18084fdcc4..33757f168a252bbd45d964bb8f2f69f9b34dcfba 100644 --- a/src/widgets/accessible/itemviews.h +++ b/src/widgets/accessible/itemviews.h @@ -161,13 +161,13 @@ public: QAccessibleTableCell(QAbstractItemView *view, const QModelIndex &m_index, QAccessible::Role role); void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - QObject *object() const Q_DECL_OVERRIDE { return 0; } + QObject *object() const Q_DECL_OVERRIDE { return Q_NULLPTR; } QAccessible::Role role() const Q_DECL_OVERRIDE; QAccessible::State state() const Q_DECL_OVERRIDE; QRect rect() const Q_DECL_OVERRIDE; bool isValid() const Q_DECL_OVERRIDE; - QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } + QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return Q_NULLPTR; } int childCount() const Q_DECL_OVERRIDE { return 0; } int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } @@ -213,13 +213,13 @@ public: // For header cells, pass the header view in addition QAccessibleTableHeaderCell(QAbstractItemView *view, int index, Qt::Orientation orientation); - QObject *object() const Q_DECL_OVERRIDE { return 0; } + QObject *object() const Q_DECL_OVERRIDE { return Q_NULLPTR; } QAccessible::Role role() const Q_DECL_OVERRIDE; QAccessible::State state() const Q_DECL_OVERRIDE; QRect rect() const Q_DECL_OVERRIDE; bool isValid() const Q_DECL_OVERRIDE; - QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } + QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return Q_NULLPTR; } int childCount() const Q_DECL_OVERRIDE { return 0; } int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } @@ -250,13 +250,13 @@ public: :view(view_) {} - QObject *object() const Q_DECL_OVERRIDE { return 0; } + QObject *object() const Q_DECL_OVERRIDE { return Q_NULLPTR; } QAccessible::Role role() const Q_DECL_OVERRIDE { return QAccessible::Pane; } QAccessible::State state() const Q_DECL_OVERRIDE { return QAccessible::State(); } QRect rect() const Q_DECL_OVERRIDE { return QRect(); } bool isValid() const Q_DECL_OVERRIDE { return true; } - QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } + QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return Q_NULLPTR; } int childCount() const Q_DECL_OVERRIDE { return 0; } int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } @@ -267,7 +267,7 @@ public: return QAccessible::queryAccessibleInterface(view); } QAccessibleInterface *child(int) const Q_DECL_OVERRIDE { - return 0; + return Q_NULLPTR; } private: diff --git a/src/widgets/dialogs/dialogs.pri b/src/widgets/dialogs/dialogs.pri index 206b394ed6d6ae1f29fb5ea7ef11f3ba24c6b1b9..4f4a9b1517afd7fc4d399d6ffa1d027c69afea34 100644 --- a/src/widgets/dialogs/dialogs.pri +++ b/src/widgets/dialogs/dialogs.pri @@ -24,7 +24,7 @@ win32 { SOURCES += dialogs/qwizard_win.cpp } -wince*: FORMS += dialogs/qfiledialog_embedded.ui +wince: FORMS += dialogs/qfiledialog_embedded.ui else: FORMS += dialogs/qfiledialog.ui INCLUDEPATH += $$PWD diff --git a/src/widgets/dialogs/qcolordialog.h b/src/widgets/dialogs/qcolordialog.h index 43c7716ef6b9b408a9b9a8de3b78508dc9683954..de18e6f9ed9c716554dad4ef49c4267b896e8c75 100644 --- a/src/widgets/dialogs/qcolordialog.h +++ b/src/widgets/dialogs/qcolordialog.h @@ -61,8 +61,8 @@ public: Q_DECLARE_FLAGS(ColorDialogOptions, ColorDialogOption) - explicit QColorDialog(QWidget *parent = 0); - explicit QColorDialog(const QColor &initial, QWidget *parent = 0); + explicit QColorDialog(QWidget *parent = Q_NULLPTR); + explicit QColorDialog(const QColor &initial, QWidget *parent = Q_NULLPTR); ~QColorDialog(); void setCurrentColor(const QColor &color); @@ -81,12 +81,12 @@ public: void setVisible(bool visible) Q_DECL_OVERRIDE; static QColor getColor(const QColor &initial = Qt::white, - QWidget *parent = 0, + QWidget *parent = Q_NULLPTR, const QString &title = QString(), - ColorDialogOptions options = 0); + ColorDialogOptions options = ColorDialogOptions()); // obsolete - static QRgb getRgba(QRgb rgba = 0xffffffff, bool *ok = 0, QWidget *parent = 0); + static QRgb getRgba(QRgb rgba = 0xffffffff, bool *ok = Q_NULLPTR, QWidget *parent = Q_NULLPTR); static int customCount(); static QColor customColor(int index); diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index 6676a3ccba683a65524ca437400b8f5e3ab4ea3d..054c220b84f2bdd9dc25b64deb30eb252f9b86f9 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -534,10 +534,7 @@ int QDialog::exec() QPointer<QDialog> guard = this; if (d->nativeDialogInUse) { - if (windowModality() == Qt::WindowModal) - d->platformHelper()->execModalForWindow(d->parentWindow()); - else - d->platformHelper()->exec(); + d->platformHelper()->exec(); } else { QEventLoop eventLoop; d->eventLoop = &eventLoop; @@ -720,13 +717,6 @@ void QDialog::setVisible(bool visible) if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden)) return; - if (!testAttribute(Qt::WA_Moved)) { - Qt::WindowStates state = windowState(); - adjustPosition(parentWidget()); - setAttribute(Qt::WA_Moved, false); // not really an explicit position - if (state != windowState()) - setWindowState(state); - } QWidget::setVisible(visible); showExtension(d->doShowExtension); QWidget *fw = window()->focusWidget(); diff --git a/src/widgets/dialogs/qdialog.h b/src/widgets/dialogs/qdialog.h index cd53378f9abce3bfb9340e9a47967be329e35a87..5ea537538758754609ddcad352ed0d360752b04c 100644 --- a/src/widgets/dialogs/qdialog.h +++ b/src/widgets/dialogs/qdialog.h @@ -51,7 +51,7 @@ class Q_WIDGETS_EXPORT QDialog : public QWidget Q_PROPERTY(bool modal READ isModal WRITE setModal) public: - explicit QDialog(QWidget *parent = 0, Qt::WindowFlags f = 0); + explicit QDialog(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); ~QDialog(); enum DialogCode { Rejected, Accepted }; @@ -90,7 +90,7 @@ public Q_SLOTS: void showExtension(bool); protected: - QDialog(QDialogPrivate &, QWidget *parent, Qt::WindowFlags f = 0); + QDialog(QDialogPrivate &, QWidget *parent, Qt::WindowFlags f = Qt::WindowFlags()); #if defined(Q_OS_WINCE) bool event(QEvent *e); diff --git a/src/widgets/dialogs/qerrormessage.h b/src/widgets/dialogs/qerrormessage.h index 55d0b389b1743c2199507584a31c7dc138ba2e9c..1d69515dfb7e77c17a973d3f1336d0f62820e2be 100644 --- a/src/widgets/dialogs/qerrormessage.h +++ b/src/widgets/dialogs/qerrormessage.h @@ -48,7 +48,7 @@ class Q_WIDGETS_EXPORT QErrorMessage: public QDialog Q_OBJECT Q_DECLARE_PRIVATE(QErrorMessage) public: - explicit QErrorMessage(QWidget* parent = 0); + explicit QErrorMessage(QWidget* parent = Q_NULLPTR); ~QErrorMessage(); static QErrorMessage * qtHandler(); diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 41522bfa19057f55f1bfe973471a310d20f7ab04..335c70eeb6f01d580db095490cbae23ed26438a1 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -328,14 +328,8 @@ Q_GLOBAL_STATIC(QUrl, lastVisitedDir) */ QT_BEGIN_INCLUDE_NAMESPACE -#ifdef Q_DEAD_CODE_FROM_QT4_WIN -#include <qwindowsstyle_p.h> -#endif #include <QMetaEnum> #include <qshortcut.h> -#ifdef Q_DEAD_CODE_FROM_QT4_MAC -#include <qmacstyle_mac_p.h> -#endif QT_END_INCLUDE_NAMESPACE /*! @@ -1189,12 +1183,17 @@ QList<QUrl> QFileDialogPrivate::userSelectedFiles() const if (!usingWidgets()) return addDefaultSuffixToUrls(selectedFiles_sys()); - foreach (const QModelIndex &index, qFileDialogUi->listView->selectionModel()->selectedRows()) + const QModelIndexList selectedRows = qFileDialogUi->listView->selectionModel()->selectedRows(); + files.reserve(selectedRows.size()); + foreach (const QModelIndex &index, selectedRows) files.append(QUrl::fromLocalFile(index.data(QFileSystemModel::FilePathRole).toString())); - if (files.isEmpty() && !lineEdit()->text().isEmpty()) - foreach (const QString &path, typedFiles()) + if (files.isEmpty() && !lineEdit()->text().isEmpty()) { + const QStringList typedFilesList = typedFiles(); + files.reserve(typedFilesList.size()); + foreach (const QString &path, typedFilesList) files.append(QUrl::fromLocalFile(path)); + } return files; } @@ -1228,7 +1227,9 @@ QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList &files QList<QUrl> QFileDialogPrivate::addDefaultSuffixToUrls(const QList<QUrl> &urlsToFix) const { QList<QUrl> urls; - for (int i=0; i<urlsToFix.size(); ++i) { + const int numUrlsToFix = urlsToFix.size(); + urls.reserve(numUrlsToFix); + for (int i = 0; i < numUrlsToFix; ++i) { QUrl url = urlsToFix.at(i); // if the filename has no suffix, add the default suffix const QString defaultSuffix = options->defaultSuffix(); @@ -1252,7 +1253,9 @@ QStringList QFileDialog::selectedFiles() const Q_D(const QFileDialog); QStringList files; - foreach (const QUrl &file, d->userSelectedFiles()) + const QList<QUrl> userSelectedFiles = d->userSelectedFiles(); + files.reserve(userSelectedFiles.size()); + foreach (const QUrl &file, userSelectedFiles) files.append(file.toLocalFile()); if (files.isEmpty() && d->usingWidgets()) { const FileMode fm = fileMode(); @@ -1277,7 +1280,9 @@ QList<QUrl> QFileDialog::selectedUrls() const return d->userSelectedFiles(); } else { QList<QUrl> urls; - foreach (const QString &file, selectedFiles()) + const QStringList selectedFileList = selectedFiles(); + urls.reserve(selectedFileList.size()); + foreach (const QString &file, selectedFileList) urls.append(QUrl::fromLocalFile(file)); return urls; } @@ -1356,7 +1361,9 @@ QStringList qt_strip_filters(const QStringList &filters) { QStringList strippedFilters; QRegExp r(QString::fromLatin1(QPlatformFileDialogHelper::filterRegExp)); - for (int i = 0; i < filters.count(); ++i) { + const int numFilters = filters.count(); + strippedFilters.reserve(numFilters); + for (int i = 0; i < numFilters; ++i) { QString filterName; int index = r.indexIn(filters[i]); if (index >= 0) @@ -1391,7 +1398,9 @@ void QFileDialog::setNameFilters(const QStringList &filters) Q_D(QFileDialog); d->defaultFileTypes = (filters == QStringList(QFileDialog::tr("All Files (*)"))); QStringList cleanedFilters; - for (int i = 0; i < filters.count(); ++i) { + const int numFilters = filters.count(); + cleanedFilters.reserve(numFilters); + for (int i = 0; i < numFilters; ++i) { cleanedFilters << filters[i].simplified(); } d->options->setNameFilters(cleanedFilters); @@ -1691,6 +1700,30 @@ void QFileDialog::setAcceptMode(QFileDialog::AcceptMode mode) d->retranslateWindowTitle(); } +/*! + \property QFileDialog::supportedSchemes + \brief the URL schemes that the file dialog should allow navigating to. + \since 5.6 + + Setting this property allows to restrict the type of URLs the + user will be able to select. It is a way for the application to declare + the protocols it will support to fetch the file content. An empty list + means that no restriction is applied (the default). + Supported for local files ("file" scheme) is implicit and always enabled; + it is not necessary to include it in the restriction. +*/ + +void QFileDialog::setSupportedSchemes(const QStringList &schemes) +{ + Q_D(QFileDialog); + d->options->setSupportedSchemes(schemes); +} + +QStringList QFileDialog::supportedSchemes() const +{ + return d_func()->options->supportedSchemes(); +} + /* Returns the file system model index that is the root index in the views @@ -2039,7 +2072,7 @@ QString QFileDialog::labelText(DialogLabel label) const The dialog's caption is set to \a caption. If \a caption is not specified then a default caption will be used. - On Windows, and Mac OS X, this static function will use the + On Windows, and OS X, this static function will use the native file dialog and not a QFileDialog. On Windows the dialog will spin a blocking modal event loop that will not @@ -2087,8 +2120,8 @@ QString QFileDialog::getOpenFileName(QWidget *parent, user will be able to select. It is a way for the application to declare the protocols it will support to fetch the file content. An empty list means that no restriction is applied (the default). - Supported for local files ("file" scheme) is implicit and always enabled. - it is not necessary to include in the restriction. + Supported for local files ("file" scheme) is implicit and always enabled; + it is not necessary to include it in the restriction. When possible, this static function will use the native file dialog and not a QFileDialog. On platforms which don't support selecting remote @@ -2105,8 +2138,6 @@ QUrl QFileDialog::getOpenFileUrl(QWidget *parent, Options options, const QStringList &supportedSchemes) { - Q_UNUSED(supportedSchemes); // TODO - QFileDialogArgs args; args.parent = parent; args.caption = caption; @@ -2117,6 +2148,7 @@ QUrl QFileDialog::getOpenFileUrl(QWidget *parent, args.options = options; QFileDialog dialog(args); + dialog.setSupportedSchemes(supportedSchemes); if (selectedFilter && !selectedFilter->isEmpty()) dialog.selectNameFilter(*selectedFilter); if (dialog.exec() == QDialog::Accepted) { @@ -2151,7 +2183,7 @@ QUrl QFileDialog::getOpenFileUrl(QWidget *parent, The dialog's caption is set to \a caption. If \a caption is not specified then a default caption will be used. - On Windows, and Mac OS X, this static function will use the + On Windows, and OS X, this static function will use the native file dialog and not a QFileDialog. On Windows the dialog will spin a blocking modal event loop that will not @@ -2165,11 +2197,6 @@ QUrl QFileDialog::getOpenFileUrl(QWidget *parent, see the QFileDialog::Option enum for more information on the flags you can pass. - \note If you want to iterate over the list of files, you should iterate - over a copy. For example: - - \snippet code/src_gui_dialogs_qfiledialog.cpp 10 - \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog yourself using one of the QFileDialog constructors. @@ -2186,6 +2213,7 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent, const QStringList schemes = QStringList(QStringLiteral("file")); const QList<QUrl> selectedUrls = getOpenFileUrls(parent, caption, QUrl::fromLocalFile(dir), filter, selectedFilter, options, schemes); QStringList fileNames; + fileNames.reserve(selectedUrls.size()); foreach (const QUrl &url, selectedUrls) fileNames << url.toLocalFile(); return fileNames; @@ -2209,8 +2237,8 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent, user will be able to select. It is a way for the application to declare the protocols it will support to fetch the file content. An empty list means that no restriction is applied (the default). - Supported for local files ("file" scheme) is implicit and always enabled. - it is not necessary to include in the restriction. + Supported for local files ("file" scheme) is implicit and always enabled; + it is not necessary to include it in the restriction. When possible, this static function will use the native file dialog and not a QFileDialog. On platforms which don't support selecting remote @@ -2227,8 +2255,6 @@ QList<QUrl> QFileDialog::getOpenFileUrls(QWidget *parent, Options options, const QStringList &supportedSchemes) { - Q_UNUSED(supportedSchemes); - QFileDialogArgs args; args.parent = parent; args.caption = caption; @@ -2239,6 +2265,7 @@ QList<QUrl> QFileDialog::getOpenFileUrls(QWidget *parent, args.options = options; QFileDialog dialog(args); + dialog.setSupportedSchemes(supportedSchemes); if (selectedFilter && !selectedFilter->isEmpty()) dialog.selectNameFilter(*selectedFilter); if (dialog.exec() == QDialog::Accepted) { @@ -2279,12 +2306,12 @@ QList<QUrl> QFileDialog::getOpenFileUrls(QWidget *parent, The dialog's caption is set to \a caption. If \a caption is not specified, a default caption will be used. - On Windows, and Mac OS X, this static function will use the + On Windows, and OS X, this static function will use the native file dialog and not a QFileDialog. On Windows the dialog will spin a blocking modal event loop that will not dispatch any QTimers, and if \a parent is not 0 then it will position the - dialog just below the parent's title bar. On Mac OS X, with its native file + dialog just below the parent's title bar. On OS X, with its native file dialog, the filter argument is ignored. On Unix/X11, the normal behavior of the file dialog is to resolve and @@ -2328,8 +2355,8 @@ QString QFileDialog::getSaveFileName(QWidget *parent, user will be able to select. It is a way for the application to declare the protocols it will support to save the file content. An empty list means that no restriction is applied (the default). - Supported for local files ("file" scheme) is implicit and always enabled. - it is not necessary to include in the restriction. + Supported for local files ("file" scheme) is implicit and always enabled; + it is not necessary to include it in the restriction. When possible, this static function will use the native file dialog and not a QFileDialog. On platforms which don't support selecting remote @@ -2346,8 +2373,6 @@ QUrl QFileDialog::getSaveFileUrl(QWidget *parent, Options options, const QStringList &supportedSchemes) { - Q_UNUSED(supportedSchemes); - QFileDialogArgs args; args.parent = parent; args.caption = caption; @@ -2358,6 +2383,7 @@ QUrl QFileDialog::getSaveFileUrl(QWidget *parent, args.options = options; QFileDialog dialog(args); + dialog.setSupportedSchemes(supportedSchemes); dialog.setAcceptMode(AcceptSave); if (selectedFilter && !selectedFilter->isEmpty()) dialog.selectNameFilter(*selectedFilter); @@ -2388,7 +2414,7 @@ QUrl QFileDialog::getSaveFileUrl(QWidget *parent, pass. To ensure a native file dialog, \l{QFileDialog::}{ShowDirsOnly} must be set. - On Windows, and Mac OS X, this static function will use the + On Windows, and OS X, this static function will use the native file dialog and not a QFileDialog. On Windows CE, if the device has no native file dialog, a QFileDialog will be used. @@ -2435,8 +2461,8 @@ QString QFileDialog::getExistingDirectory(QWidget *parent, user will be able to select. It is a way for the application to declare the protocols it will support to fetch the file content. An empty list means that no restriction is applied (the default). - Supported for local files ("file" scheme) is implicit and always enabled. - it is not necessary to include in the restriction. + Supported for local files ("file" scheme) is implicit and always enabled; + it is not necessary to include it in the restriction. When possible, this static function will use the native file dialog and not a QFileDialog. On platforms which don't support selecting remote @@ -2451,8 +2477,6 @@ QUrl QFileDialog::getExistingDirectoryUrl(QWidget *parent, Options options, const QStringList &supportedSchemes) { - Q_UNUSED(supportedSchemes); - QFileDialogArgs args; args.parent = parent; args.caption = caption; @@ -2461,6 +2485,7 @@ QUrl QFileDialog::getExistingDirectoryUrl(QWidget *parent, args.options = options; QFileDialog dialog(args); + dialog.setSupportedSchemes(supportedSchemes); if (dialog.exec() == QDialog::Accepted) return dialog.selectedUrls().value(0); return QUrl(); @@ -2662,7 +2687,9 @@ void QFileDialogPrivate::saveSettings() settings.setValue(QLatin1String("treeViewHeader"), qFileDialogUi->treeView->header()->saveState()); } QStringList historyUrls; - foreach (const QString &path, q->history()) + const QStringList history = q->history(); + historyUrls.reserve(history.size()); + foreach (const QString &path, history) historyUrls << QUrl::fromLocalFile(path).toString(); settings.setValue(QLatin1String("history"), historyUrls); settings.setValue(QLatin1String("lastVisited"), lastVisitedDir()->toString()); @@ -2954,7 +2981,7 @@ void QFileDialogPrivate::createWidgets() q->setHistory(options->history()); if (options->initiallySelectedFiles().count() == 1) q->selectFile(options->initiallySelectedFiles().first().fileName()); - foreach (QUrl url, options->initiallySelectedFiles()) + foreach (const QUrl &url, options->initiallySelectedFiles()) q->selectUrl(url); lineEdit()->selectAll(); _q_updateOkButton(); diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h index 95209bceb5f7c635584c8ed065720b1caba4738a..ffe49a2dd225b0fd3db41a72f23a4146814a4946 100644 --- a/src/widgets/dialogs/qfiledialog.h +++ b/src/widgets/dialogs/qfiledialog.h @@ -66,6 +66,7 @@ class Q_WIDGETS_EXPORT QFileDialog : public QDialog Q_PROPERTY(bool nameFilterDetailsVisible READ isNameFilterDetailsVisible WRITE setNameFilterDetailsVisible DESIGNABLE false) Q_PROPERTY(Options options READ options WRITE setOptions) + Q_PROPERTY(QStringList supportedSchemes READ supportedSchemes WRITE setSupportedSchemes) public: enum ViewMode { Detail, List }; @@ -91,7 +92,7 @@ public: Q_DECLARE_FLAGS(Options, Option) QFileDialog(QWidget *parent, Qt::WindowFlags f); - explicit QFileDialog(QWidget *parent = 0, + explicit QFileDialog(QWidget *parent = Q_NULLPTR, const QString &caption = QString(), const QString &directory = QString(), const QString &filter = QString()); @@ -167,6 +168,9 @@ public: void setLabelText(DialogLabel label, const QString &text); QString labelText(DialogLabel label) const; + void setSupportedSchemes(const QStringList &schemes); + QStringList supportedSchemes() const; + #ifndef QT_NO_PROXYMODEL void setProxyModel(QAbstractProxyModel *model); QAbstractProxyModel *proxyModel() const; @@ -196,60 +200,60 @@ Q_SIGNALS: public: - static QString getOpenFileName(QWidget *parent = 0, + static QString getOpenFileName(QWidget *parent = Q_NULLPTR, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), - QString *selectedFilter = 0, - Options options = 0); + QString *selectedFilter = Q_NULLPTR, + Options options = Options()); - static QUrl getOpenFileUrl(QWidget *parent = 0, + static QUrl getOpenFileUrl(QWidget *parent = Q_NULLPTR, const QString &caption = QString(), const QUrl &dir = QUrl(), const QString &filter = QString(), - QString *selectedFilter = 0, - Options options = 0, + QString *selectedFilter = Q_NULLPTR, + Options options = Options(), const QStringList &supportedSchemes = QStringList()); - static QString getSaveFileName(QWidget *parent = 0, + static QString getSaveFileName(QWidget *parent = Q_NULLPTR, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), - QString *selectedFilter = 0, - Options options = 0); + QString *selectedFilter = Q_NULLPTR, + Options options = Options()); - static QUrl getSaveFileUrl(QWidget *parent = 0, + static QUrl getSaveFileUrl(QWidget *parent = Q_NULLPTR, const QString &caption = QString(), const QUrl &dir = QUrl(), const QString &filter = QString(), - QString *selectedFilter = 0, - Options options = 0, + QString *selectedFilter = Q_NULLPTR, + Options options = Options(), const QStringList &supportedSchemes = QStringList()); - static QString getExistingDirectory(QWidget *parent = 0, + static QString getExistingDirectory(QWidget *parent = Q_NULLPTR, const QString &caption = QString(), const QString &dir = QString(), Options options = ShowDirsOnly); - static QUrl getExistingDirectoryUrl(QWidget *parent = 0, + static QUrl getExistingDirectoryUrl(QWidget *parent = Q_NULLPTR, const QString &caption = QString(), const QUrl &dir = QUrl(), Options options = ShowDirsOnly, const QStringList &supportedSchemes = QStringList()); - static QStringList getOpenFileNames(QWidget *parent = 0, + static QStringList getOpenFileNames(QWidget *parent = Q_NULLPTR, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), - QString *selectedFilter = 0, - Options options = 0); + QString *selectedFilter = Q_NULLPTR, + Options options = Options()); - static QList<QUrl> getOpenFileUrls(QWidget *parent = 0, + static QList<QUrl> getOpenFileUrls(QWidget *parent = Q_NULLPTR, const QString &caption = QString(), const QUrl &dir = QUrl(), const QString &filter = QString(), - QString *selectedFilter = 0, - Options options = 0, + QString *selectedFilter = Q_NULLPTR, + Options options = Options(), const QStringList &supportedSchemes = QStringList()); diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 4859231d956fd802016cdf8ab4de796b6e976a0f..fd49246e9f584b534b1286d537fa3b85ac2dad1f 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -259,10 +259,7 @@ QModelIndex QFileSystemModel::index(const QString &path, int column) const { Q_D(const QFileSystemModel); QFileSystemModelPrivate::QFileSystemNode *node = d->node(path, false); - QModelIndex idx = d->index(node); - if (idx.column() != column) - idx = idx.sibling(idx.row(), column); - return idx; + return d->index(node, column); } /*! @@ -562,7 +559,7 @@ QModelIndex QFileSystemModel::parent(const QModelIndex &index) const return the index for node */ -QModelIndex QFileSystemModelPrivate::index(const QFileSystemModelPrivate::QFileSystemNode *node) const +QModelIndex QFileSystemModelPrivate::index(const QFileSystemModelPrivate::QFileSystemNode *node, int column) const { Q_Q(const QFileSystemModel); QFileSystemModelPrivate::QFileSystemNode *parentNode = (node ? node->parent : 0); @@ -575,7 +572,7 @@ QModelIndex QFileSystemModelPrivate::index(const QFileSystemModelPrivate::QFileS return QModelIndex(); int visualRow = translateVisibleLocation(parentNode, parentNode->visibleLocation(node->fileName)); - return q->createIndex(visualRow, 0, const_cast<QFileSystemNode*>(node)); + return q->createIndex(visualRow, column, const_cast<QFileSystemNode*>(node)); } /*! @@ -643,7 +640,7 @@ int QFileSystemModel::rowCount(const QModelIndex &parent) const */ int QFileSystemModel::columnCount(const QModelIndex &parent) const { - return (parent.column() > 0) ? 0 : 4; + return (parent.column() > 0) ? 0 : QFileSystemModelPrivate::NumColumns; } /*! @@ -1183,8 +1180,11 @@ void QFileSystemModel::sort(int column, Qt::SortOrder order) emit layoutAboutToBeChanged(); QModelIndexList oldList = persistentIndexList(); QList<QPair<QFileSystemModelPrivate::QFileSystemNode*, int> > oldNodes; - for (int i = 0; i < oldList.count(); ++i) { - QPair<QFileSystemModelPrivate::QFileSystemNode*, int> pair(d->node(oldList.at(i)), oldList.at(i).column()); + const int nodeCount = oldList.count(); + oldNodes.reserve(nodeCount); + for (int i = 0; i < nodeCount; ++i) { + const QModelIndex &oldNode = oldList.at(i); + QPair<QFileSystemModelPrivate::QFileSystemNode*, int> pair(d->node(oldNode), oldNode.column()); oldNodes.append(pair); } @@ -1197,10 +1197,11 @@ void QFileSystemModel::sort(int column, Qt::SortOrder order) d->sortOrder = order; QModelIndexList newList; - for (int i = 0; i < oldNodes.count(); ++i) { - QModelIndex idx = d->index(oldNodes.at(i).first); - idx = idx.sibling(idx.row(), oldNodes.at(i).second); - newList.append(idx); + const int numOldNodes = oldNodes.size(); + newList.reserve(numOldNodes); + for (int i = 0; i < numOldNodes; ++i) { + const QPair<QFileSystemModelPrivate::QFileSystemNode*, int> &oldNode = oldNodes.at(i); + newList.append(d->index(oldNode.first, oldNode.second)); } changePersistentIndexList(oldList, newList); emit layoutChanged(); @@ -1648,7 +1649,9 @@ QStringList QFileSystemModel::nameFilters() const Q_D(const QFileSystemModel); QStringList filters; #ifndef QT_NO_REGEXP - for (int i = 0; i < d->nameFilters.size(); ++i) { + const int numNameFilters = d->nameFilters.size(); + filters.reserve(numNameFilters); + for (int i = 0; i < numNameFilters; ++i) { filters << d->nameFilters.at(i).pattern(); } #endif diff --git a/src/widgets/dialogs/qfilesystemmodel.h b/src/widgets/dialogs/qfilesystemmodel.h index 7c98a102f32dcffc667c50bb4277dece9cc4bd33..f749c97bcb3c81b58b741588b30609c77a62ff36 100644 --- a/src/widgets/dialogs/qfilesystemmodel.h +++ b/src/widgets/dialogs/qfilesystemmodel.h @@ -69,7 +69,7 @@ public: FilePermissions = Qt::UserRole + 3 }; - explicit QFileSystemModel(QObject *parent = 0); + explicit QFileSystemModel(QObject *parent = Q_NULLPTR); ~QFileSystemModel(); QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; @@ -136,7 +136,7 @@ public: bool remove(const QModelIndex &index); protected: - QFileSystemModel(QFileSystemModelPrivate &, QObject *parent = 0); + QFileSystemModel(QFileSystemModelPrivate &, QObject *parent = Q_NULLPTR); void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE; bool event(QEvent *event) Q_DECL_OVERRIDE; diff --git a/src/widgets/dialogs/qfilesystemmodel_p.h b/src/widgets/dialogs/qfilesystemmodel_p.h index dd4b25d59c2bdea65dee5b184198788d175bb009..57fb4570719b3c41f9e182022c025eff15f6d94e 100644 --- a/src/widgets/dialogs/qfilesystemmodel_p.h +++ b/src/widgets/dialogs/qfilesystemmodel_p.h @@ -70,6 +70,8 @@ class Q_AUTOTEST_EXPORT QFileSystemModelPrivate : public QAbstractItemModelPriva Q_DECLARE_PUBLIC(QFileSystemModel) public: + enum { NumColumns = 4 }; + class QFileSystemNode { public: @@ -220,8 +222,8 @@ public: } QFileSystemNode *node(const QModelIndex &index) const; QFileSystemNode *node(const QString &path, bool fetch = true) const; - inline QModelIndex index(const QString &path) { return index(node(path)); } - QModelIndex index(const QFileSystemNode *node) const; + inline QModelIndex index(const QString &path, int column = 0) { return index(node(path), column); } + QModelIndex index(const QFileSystemNode *node, int column = 0) const; bool filtersAcceptsNode(const QFileSystemNode *node) const; bool passNameFilters(const QFileSystemNode *node) const; void removeNode(QFileSystemNode *parentNode, const QString &name); @@ -318,6 +320,7 @@ public: QList<Fetching> toFetch; }; +Q_DECLARE_TYPEINFO(QFileSystemModelPrivate::Fetching, Q_MOVABLE_TYPE); #endif // QT_NO_FILESYSTEMMODEL QT_END_NAMESPACE diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp index d47dd3562f15410b28aed37a60d4582008b87866..688e8f5c133f4de29734e73fabc0951fa5e6c6bb 100644 --- a/src/widgets/dialogs/qfontdialog.cpp +++ b/src/widgets/dialogs/qfontdialog.cpp @@ -619,6 +619,7 @@ void QFontDialogPrivate::updateSizes() int i = 0; int current = -1; QStringList str_sizes; + str_sizes.reserve(sizes.size()); for(QList<int>::const_iterator it = sizes.constBegin(); it != sizes.constEnd(); ++it) { str_sizes.append(QString::number(*it)); if (current == -1 && *it == size) diff --git a/src/widgets/dialogs/qfontdialog.h b/src/widgets/dialogs/qfontdialog.h index 8ca9bf14dd2a6c845999d2aa8f05c627cb44724f..c3c30501740d5fd5c59d29d7d4848128fde88024 100644 --- a/src/widgets/dialogs/qfontdialog.h +++ b/src/widgets/dialogs/qfontdialog.h @@ -65,8 +65,8 @@ public: Q_DECLARE_FLAGS(FontDialogOptions, FontDialogOption) - explicit QFontDialog(QWidget *parent = 0); - explicit QFontDialog(const QFont &initial, QWidget *parent = 0); + explicit QFontDialog(QWidget *parent = Q_NULLPTR); + explicit QFontDialog(const QFont &initial, QWidget *parent = Q_NULLPTR); ~QFontDialog(); void setCurrentFont(const QFont &font); @@ -84,9 +84,9 @@ public: void setVisible(bool visible) Q_DECL_OVERRIDE; - static QFont getFont(bool *ok, QWidget *parent = 0); - static QFont getFont(bool *ok, const QFont &initial, QWidget *parent = 0, const QString &title = QString(), - FontDialogOptions options = 0); + static QFont getFont(bool *ok, QWidget *parent = Q_NULLPTR); + static QFont getFont(bool *ok, const QFont &initial, QWidget *parent = Q_NULLPTR, const QString &title = QString(), + FontDialogOptions options = FontDialogOptions()); Q_SIGNALS: void currentFontChanged(const QFont &font); diff --git a/src/widgets/dialogs/qinputdialog.cpp b/src/widgets/dialogs/qinputdialog.cpp index 9c78f5e9ac500c62fb2d67c96198e57611ffe47a..fb52fa46519ae28d4d54243fce341a030a6b9d4b 100644 --- a/src/widgets/dialogs/qinputdialog.cpp +++ b/src/widgets/dialogs/qinputdialog.cpp @@ -791,6 +791,7 @@ QStringList QInputDialog::comboBoxItems() const QStringList result; if (d->comboBox) { const int count = d->comboBox->count(); + result.reserve(count); for (int i = 0; i < count; ++i) result.append(d->comboBox->itemText(i)); } diff --git a/src/widgets/dialogs/qinputdialog.h b/src/widgets/dialogs/qinputdialog.h index 84130d5f90bf6f6c5417722d4f180b924807124f..600f6c97538d1ab6a42b1fe76d937e4a75473e5b 100644 --- a/src/widgets/dialogs/qinputdialog.h +++ b/src/widgets/dialogs/qinputdialog.h @@ -83,7 +83,7 @@ public: DoubleInput }; - QInputDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0); + QInputDialog(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); ~QInputDialog(); void setInputMode(InputMode mode); @@ -153,27 +153,29 @@ public: static QString getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode echo = QLineEdit::Normal, - const QString &text = QString(), bool *ok = 0, Qt::WindowFlags flags = 0, + const QString &text = QString(), bool *ok = Q_NULLPTR, + Qt::WindowFlags flags = Qt::WindowFlags(), Qt::InputMethodHints inputMethodHints = Qt::ImhNone); static QString getMultiLineText(QWidget *parent, const QString &title, const QString &label, - const QString &text = QString(), bool *ok = 0, Qt::WindowFlags flags = 0, - Qt::InputMethodHints inputMethodHints = Qt::ImhNone); + const QString &text = QString(), bool *ok = Q_NULLPTR, + Qt::WindowFlags flags = Qt::WindowFlags(), + Qt::InputMethodHints inputMethodHints = Qt::ImhNone); static QString getItem(QWidget *parent, const QString &title, const QString &label, const QStringList &items, int current = 0, bool editable = true, - bool *ok = 0, Qt::WindowFlags flags = 0, + bool *ok = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags(), Qt::InputMethodHints inputMethodHints = Qt::ImhNone); static int getInt(QWidget *parent, const QString &title, const QString &label, int value = 0, int minValue = -2147483647, int maxValue = 2147483647, - int step = 1, bool *ok = 0, Qt::WindowFlags flags = 0); + int step = 1, bool *ok = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); static double getDouble(QWidget *parent, const QString &title, const QString &label, double value = 0, double minValue = -2147483647, double maxValue = 2147483647, - int decimals = 1, bool *ok = 0, Qt::WindowFlags flags = 0); + int decimals = 1, bool *ok = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); #if QT_DEPRECATED_SINCE(5, 0) QT_DEPRECATED static inline int getInteger(QWidget *parent, const QString &title, const QString &label, int value = 0, int minValue = -2147483647, int maxValue = 2147483647, - int step = 1, bool *ok = 0, Qt::WindowFlags flags = 0) + int step = 1, bool *ok = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()) { return getInt(parent, title, label, value, minValue, maxValue, step, ok, flags); } diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index 571b01802db45792a35ef8f96380e68d4b3e9bcd..ef9b55acd68d7a2072584924848a044fd3d2d0fb 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -580,7 +580,7 @@ void QMessageBoxPrivate::_q_clicked(QPlatformDialogHelper::StandardButton button This is the approach recommended in the \l{http://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/AppleHIGuidelines/Windows/Windows.html#//apple_ref/doc/uid/20000961-BABCAJID} - {Mac OS X Guidelines}. Similar guidelines apply for the other + {OS X Guidelines}. Similar guidelines apply for the other platforms, but note the different ways the \l{QMessageBox::informativeText} {informative text} is handled for different platforms. @@ -795,7 +795,7 @@ void QMessageBoxPrivate::_q_clicked(QPlatformDialogHelper::StandardButton button Constructs a message box with no text and no buttons. \a parent is passed to the QDialog constructor. - On Mac OS X, if you want your message box to appear + On OS X, if you want your message box to appear as a Qt::Sheet of its \a parent, set the message box's \l{setWindowModality()} {window modality} to Qt::WindowModal or use open(). Otherwise, the message box will be a standard dialog. @@ -817,7 +817,7 @@ QMessageBox::QMessageBox(QWidget *parent) The message box is an \l{Qt::ApplicationModal} {application modal} dialog box. - On Mac OS X, if \a parent is not 0 and you want your message box + On OS X, if \a parent is not 0 and you want your message box to appear as a Qt::Sheet of that parent, set the message box's \l{setWindowModality()} {window modality} to Qt::WindowModal (default). Otherwise, the message box will be a standard dialog. @@ -985,7 +985,7 @@ QAbstractButton *QMessageBox::button(StandardButton which) const \list 1 \li If there is only one button, it is made the escape button. \li If there is a \l Cancel button, it is made the escape button. - \li On Mac OS X only, if there is exactly one button with the role + \li On OS X only, if there is exactly one button with the role QMessageBox::RejectRole, it is made the escape button. \endlist @@ -1803,7 +1803,7 @@ QMessageBox::StandardButton QMessageBox::critical(QWidget *parent, const QString \li As a last resort it uses the Information icon. \endlist - The about box has a single button labelled "OK". On Mac OS X, the + The about box has a single button labelled "OK". On OS X, the about box is popped up as a modeless window; on other platforms, it is currently application modal. @@ -1857,7 +1857,7 @@ void QMessageBox::about(QWidget *parent, const QString &title, const QString &te QApplication provides this functionality as a slot. - On Mac OS X, the about box is popped up as a modeless window; on + On OS X, the about box is popped up as a modeless window; on other platforms, it is currently application modal. \sa QApplication::aboutQt() @@ -2622,8 +2622,8 @@ void QMessageBox::setInformativeText(const QString &text) This function shadows QWidget::setWindowTitle(). - Sets the title of the message box to \a title. On Mac OS X, - the window title is ignored (as required by the Mac OS X + Sets the title of the message box to \a title. On OS X, + the window title is ignored (as required by the OS X Guidelines). */ void QMessageBox::setWindowTitle(const QString &title) @@ -2644,7 +2644,7 @@ void QMessageBox::setWindowTitle(const QString &title) Sets the modality of the message box to \a windowModality. - On Mac OS X, if the modality is set to Qt::WindowModal and the message box + On OS X, if the modality is set to Qt::WindowModal and the message box has a parent, then the message box will be a Qt::Sheet, otherwise the message box will be a standard dialog. */ diff --git a/src/widgets/dialogs/qmessagebox.h b/src/widgets/dialogs/qmessagebox.h index 464bf734dce615146cd11757b5c08c82b5fc2cac..b1083544669669f44108cb7150b7c460d96a42a7 100644 --- a/src/widgets/dialogs/qmessagebox.h +++ b/src/widgets/dialogs/qmessagebox.h @@ -125,9 +125,9 @@ public: Q_DECLARE_FLAGS(StandardButtons, StandardButton) - explicit QMessageBox(QWidget *parent = 0); + explicit QMessageBox(QWidget *parent = Q_NULLPTR); QMessageBox(Icon icon, const QString &title, const QString &text, - StandardButtons buttons = NoButton, QWidget *parent = 0, + StandardButtons buttons = NoButton, QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint); ~QMessageBox(); @@ -198,7 +198,7 @@ public: QMessageBox(const QString &title, const QString &text, Icon icon, int button0, int button1, int button2, - QWidget *parent = 0, + QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint); static int information(QWidget *parent, const QString &title, diff --git a/src/widgets/dialogs/qprogressdialog.cpp b/src/widgets/dialogs/qprogressdialog.cpp index 4e8e24581389946360b1426de2c5b858a5ff25e5..97e9267a9d4f18c4779eba8a9efcf9cd8e47660d 100644 --- a/src/widgets/dialogs/qprogressdialog.cpp +++ b/src/widgets/dialogs/qprogressdialog.cpp @@ -697,9 +697,6 @@ void QProgressDialog::setValue(int progress) d->shown_once = true; } } -#ifdef Q_DEAD_CODE_FROM_QT4_MAC - QApplication::flush(); -#endif } if (progress == d->bar->maximum() && d->autoReset) diff --git a/src/widgets/dialogs/qprogressdialog.h b/src/widgets/dialogs/qprogressdialog.h index 51c45f5d3074aadddd0f18236566f9b061c4b812..28de6233858373130b03470dfe5f0ccab249dc8a 100644 --- a/src/widgets/dialogs/qprogressdialog.h +++ b/src/widgets/dialogs/qprogressdialog.h @@ -61,9 +61,10 @@ class Q_WIDGETS_EXPORT QProgressDialog : public QDialog Q_PROPERTY(QString labelText READ labelText WRITE setLabelText) public: - explicit QProgressDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit QProgressDialog(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); QProgressDialog(const QString &labelText, const QString &cancelButtonText, - int minimum, int maximum, QWidget *parent = 0, Qt::WindowFlags flags = 0); + int minimum, int maximum, QWidget *parent = Q_NULLPTR, + Qt::WindowFlags flags = Qt::WindowFlags()); ~QProgressDialog(); void setLabel(QLabel *label); diff --git a/src/widgets/dialogs/qsidebar.cpp b/src/widgets/dialogs/qsidebar.cpp index 6fbcce801dc082491c54a71e6e92f909f51f69c9..be3c060ba1d8d74e1dfdf7be6440c7ad40a6b10d 100644 --- a/src/widgets/dialogs/qsidebar.cpp +++ b/src/widgets/dialogs/qsidebar.cpp @@ -274,7 +274,9 @@ void QUrlModel::addUrls(const QList<QUrl> &list, int row, bool move) QList<QUrl> QUrlModel::urls() const { QList<QUrl> list; - for (int i = 0; i < rowCount(); ++i) + const int numRows = rowCount(); + list.reserve(numRows); + for (int i = 0; i < numRows; ++i) list.append(data(index(i, 0), UrlRole).toUrl()); return list; } @@ -334,10 +336,12 @@ void QUrlModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &botto void QUrlModel::layoutChanged() { QStringList paths; - for (int i = 0; i < watching.count(); ++i) + const int numPaths = watching.count(); + paths.reserve(numPaths); + for (int i = 0; i < numPaths; ++i) paths.append(watching.at(i).second); watching.clear(); - for (int i = 0; i < paths.count(); ++i) { + for (int i = 0; i < numPaths; ++i) { QString path = paths.at(i); QModelIndex newIndex = fileSystemModel->index(path); watching.append(QPair<QModelIndex, QString>(newIndex, path)); @@ -453,12 +457,14 @@ void QSidebar::removeEntry() { QList<QModelIndex> idxs = selectionModel()->selectedIndexes(); QList<QPersistentModelIndex> indexes; - for (int i = 0; i < idxs.count(); i++) + const int numIndexes = idxs.count(); + for (int i = 0; i < numIndexes; i++) indexes.append(idxs.at(i)); - for (int i = 0; i < indexes.count(); ++i) + for (int i = 0; i < numIndexes; ++i) { if (!indexes.at(i).data(QUrlModel::UrlRole).toUrl().path().isEmpty()) model()->removeRow(indexes.at(i).row()); + } } /*! diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index bf3e44b6a69d4a38c936caafc3b99bf0af752479..6a1c0eb5926e9bb83ed01cb2003979a6d481659b 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -170,6 +170,7 @@ public: const char *changedSignal) : className(className), property(property), changedSignal(changedSignal) {} }; +Q_DECLARE_TYPEINFO(QWizardDefaultProperty, Q_MOVABLE_TYPE); class QWizardField { @@ -189,6 +190,7 @@ public: QByteArray changedSignal; QVariant initialValue; }; +Q_DECLARE_TYPEINFO(QWizardField, Q_MOVABLE_TYPE); QWizardField::QWizardField(QWizardPage *page, const QString &spec, QObject *object, const char *property, const char *changedSignal) @@ -751,6 +753,7 @@ void QWizardPrivate::init() updateButtonLayout(); + defaultPropertyTable.reserve(NFallbackDefaultProperties); for (uint i = 0; i < NFallbackDefaultProperties; ++i) defaultPropertyTable.append(QWizardDefaultProperty(fallbackProperties[i].className, fallbackProperties[i].property, @@ -876,7 +879,7 @@ void QWizardPrivate::switchToPage(int newId, Direction direction) /* If there is no default button and the Next or Finish button is enabled, give focus directly to it as a convenience to the - user. This is the normal case on Mac OS X. + user. This is the normal case on OS X. Otherwise, give the focus to the new page's first child that can handle it. If there is no such child, give the focus to @@ -1815,7 +1818,7 @@ void QWizardAntiFlickerWidget::paintEvent(QPaintEvent *) \inmodule QtWidgets - A wizard (also called an assistant on Mac OS X) is a special type + A wizard (also called an assistant on OS X) is a special type of input dialog that consists of a sequence of pages. A wizard's purpose is to guide the user through a process step by step. Wizards are useful for complex or infrequent tasks that users may @@ -2113,10 +2116,10 @@ void QWizardAntiFlickerWidget::paintEvent(QPaintEvent *) This enum specifies the buttons in a wizard. - \value BackButton The \uicontrol Back button (\uicontrol {Go Back} on Mac OS X) - \value NextButton The \uicontrol Next button (\uicontrol Continue on Mac OS X) + \value BackButton The \uicontrol Back button (\uicontrol {Go Back} on OS X) + \value NextButton The \uicontrol Next button (\uicontrol Continue on OS X) \value CommitButton The \uicontrol Commit button - \value FinishButton The \uicontrol Finish button (\uicontrol Done on Mac OS X) + \value FinishButton The \uicontrol Finish button (\uicontrol Done on OS X) \value CancelButton The \uicontrol Cancel button (see also NoCancelButton) \value HelpButton The \uicontrol Help button (see also HaveHelpButton) \value CustomButton1 The first user-defined button (see also HaveCustomButton1) @@ -2156,7 +2159,7 @@ void QWizardAntiFlickerWidget::paintEvent(QPaintEvent *) \value ClassicStyle Classic Windows look \value ModernStyle Modern Windows look - \value MacStyle Mac OS X look + \value MacStyle OS X look \value AeroStyle Windows Aero look \omitvalue NStyles @@ -2629,7 +2632,7 @@ bool QWizard::testOption(WizardOption option) const \list \li Windows: HelpButtonOnRight. - \li Mac OS X: NoDefaultButton and NoCancelButton. + \li OS X: NoDefaultButton and NoCancelButton. \li X11 and QWS (Qt for Embedded Linux): none. \endlist @@ -2673,7 +2676,7 @@ QWizard::WizardOptions QWizard::options() const Sets the text on button \a which to be \a text. By default, the text on buttons depends on the wizardStyle. For - example, on Mac OS X, the \uicontrol Next button is called \uicontrol + example, on OS X, the \uicontrol Next button is called \uicontrol Continue. To add extra buttons to the wizard (e.g., a \uicontrol Print button), @@ -2705,7 +2708,7 @@ void QWizard::setButtonText(WizardButton which, const QString &text) If a text has ben set using setButtonText(), this text is returned. By default, the text on buttons depends on the wizardStyle. For - example, on Mac OS X, the \uicontrol Next button is called \uicontrol + example, on OS X, the \uicontrol Next button is called \uicontrol Continue. \sa button(), setButton(), setButtonText(), QWizardPage::buttonText(), @@ -2891,7 +2894,7 @@ void QWizard::setPixmap(WizardPixmap which, const QPixmap &pixmap) Returns the pixmap set for role \a which. By default, the only pixmap that is set is the BackgroundPixmap on - Mac OS X. + OS X. \sa QWizardPage::pixmap(), {Elements of a Wizard Page} */ @@ -3803,7 +3806,7 @@ void QWizardPage::setButtonText(QWizard::WizardButton which, const QString &text this text is returned. By default, the text on buttons depends on the QWizard::wizardStyle. - For example, on Mac OS X, the \uicontrol Next button is called \uicontrol + For example, on OS X, the \uicontrol Next button is called \uicontrol Continue. \sa setButtonText(), QWizard::buttonText(), QWizard::setButtonText() diff --git a/src/widgets/dialogs/qwizard.h b/src/widgets/dialogs/qwizard.h index 517edde377c2ba27f0bef52eba2e4c9c981b1b7f..9193f0b659a75a050178d3dab8780737b7c80d9b 100644 --- a/src/widgets/dialogs/qwizard.h +++ b/src/widgets/dialogs/qwizard.h @@ -114,7 +114,7 @@ public: Q_DECLARE_FLAGS(WizardOptions, WizardOption) - explicit QWizard(QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit QWizard(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); ~QWizard(); int addPage(QWizardPage *page); @@ -209,7 +209,7 @@ class Q_WIDGETS_EXPORT QWizardPage : public QWidget Q_PROPERTY(QString subTitle READ subTitle WRITE setSubTitle) public: - explicit QWizardPage(QWidget *parent = 0); + explicit QWizardPage(QWidget *parent = Q_NULLPTR); ~QWizardPage(); void setTitle(const QString &title); @@ -237,8 +237,8 @@ Q_SIGNALS: protected: void setField(const QString &name, const QVariant &value); QVariant field(const QString &name) const; - void registerField(const QString &name, QWidget *widget, const char *property = 0, - const char *changedSignal = 0); + void registerField(const QString &name, QWidget *widget, const char *property = Q_NULLPTR, + const char *changedSignal = Q_NULLPTR); QWizard *wizard() const; private: diff --git a/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc b/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc index ef9f1fe9190a67c9773493ad23e727db1c67a17f..efb0b33cd194008eabb8135817506f6679fdc629 100644 --- a/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc +++ b/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc @@ -360,7 +360,8 @@ QSpinBox::down-button { height: 10px } //! [59] -/* implicitly sets the size of down-button to the size of spindown.png */ +// implicitly sets the size of down-button to the +// size of spindown.png QSpinBox::down-button { image: url(:/images/spindown.png) } //! [59] @@ -489,7 +490,8 @@ QDialog { etch-disabled-text: 1 } QLabel { border-color: red } /* red red red red */ QLabel { border-color: red blue } /* red blue red blue */ QLabel { border-color: red blue green } /* red blue green blue */ -QLabel { border-color: red blue green yellow } /* red blue green yellow */ +QLabel { border-color: red blue green yellow } +/* red blue green yellow */ //! [82] @@ -522,7 +524,8 @@ QTextEdit { /* linear gradient from white to green */ QTextEdit { background: qlineargradient(x1:0, y1:0, x2:1, y2:1, - stop:0 white, stop: 0.4 rgba(10, 20, 30, 40), stop:1 rgb(0, 200, 230, 200)) + stop:0 white, stop: 0.4 rgba(10, 20, 30, 40), + stop:1 rgb(0, 200, 230, 200)) } @@ -549,7 +552,8 @@ QTextEdit { QMessageBox { dialogbuttonbox-buttons-have-icons: true; dialog-ok-icon: url(ok.svg); - dialog-cancel-icon: url(cancel.png), url(grayed_cancel.png) disabled; + dialog-cancel-icon: url(cancel.png), + url(grayed_cancel.png) disabled; } //! [86] diff --git a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp index 39dfe32ace61ddd3e1bb4ef38e4108932a2216da..e5c0f5cea1a58f35d0af972b39abd2e50d8cbb7e 100644 --- a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp +++ b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp @@ -106,16 +106,6 @@ QStringList files = QFileDialog::getOpenFileNames( //! [9] -//! [10] -QStringList list = files; -QStringList::Iterator it = list.begin(); -while(it != list.end()) { - myProcessing(*it); - ++it; -} -//! [10] - - //! [11] QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "/home/jana/untitled.png", diff --git a/src/widgets/doc/snippets/macmainwindow.mm b/src/widgets/doc/snippets/macmainwindow.mm index e1df77089ce790650eaefdcef401b563bf3e4884..d0d74631ab2d33651a04c35d5596e1d110106e5a 100644 --- a/src/widgets/doc/snippets/macmainwindow.mm +++ b/src/widgets/doc/snippets/macmainwindow.mm @@ -269,7 +269,7 @@ MacMainWindow::MacMainWindow() textedit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); textedit->setText("<br><br><br><br><br><br><center><b>This demo shows how to create a \ Qt main window application that has the same appearance as other \ - Mac OS X applications such as Mail or iTunes. This includes \ + OS X applications such as Mail or iTunes. This includes \ customizing the item views and QSplitter and wrapping native widgets \ such as the search field.</b></center>"); diff --git a/src/widgets/doc/src/graphicsview.qdoc b/src/widgets/doc/src/graphicsview.qdoc index 3b0d841d536be38ee93c54c9af6863982a9b34af..6f3bc68f9884f58310516e050a94dad9e8182153 100644 --- a/src/widgets/doc/src/graphicsview.qdoc +++ b/src/widgets/doc/src/graphicsview.qdoc @@ -491,10 +491,7 @@ not supported. For example, you can create decorated windows by passing the Qt::Window window flag to QGraphicsWidget's constructor, but Graphics View currently doesn't support the Qt::Sheet and - Qt::Drawer flags that are common on Mac OS X. - - The capabilities of QGraphicsWidget are expected to grow depending - on community feedback. + Qt::Drawer flags that are common on OS X. \section3 QGraphicsLayout diff --git a/src/widgets/doc/src/model-view-programming.qdoc b/src/widgets/doc/src/model-view-programming.qdoc index 8fee91f0e5cb6fdd9794d332f7992b9bb18fc5aa..098bb39fe271e93c5d8ff81dc56f3bb58579c2eb 100644 --- a/src/widgets/doc/src/model-view-programming.qdoc +++ b/src/widgets/doc/src/model-view-programming.qdoc @@ -354,7 +354,7 @@ the above code indicates, we need to supply more information when obtaining a model index. - \table + \table 70% \row \li \inlineimage modelview-tablemodel.png \li \b{Rows and columns} @@ -386,7 +386,7 @@ \snippet code/doc_src_model-view-programming.cpp 3 - \table + \table 70% \row \li \inlineimage modelview-treemodel.png \li \b{Parents, rows, and columns} @@ -417,7 +417,7 @@ \snippet code/doc_src_model-view-programming.cpp 6 - \table + \table 70% \row \li \inlineimage modelview-roles.png \li \b{Item roles} @@ -902,7 +902,7 @@ The table below highlights the differences between current item and selected items. - \table + \table 70% \header \li Current Item \li Selected Items @@ -1557,7 +1557,7 @@ of items. The selection mode works in the same way for all of the above widgets. - \table + \table 70% \row \li \image selection-single.png \li \b{Single item selections:} @@ -1957,7 +1957,7 @@ To provide read-only access to data provided by a model, the following functions \e{must} be implemented in the model's subclass: - \table 90% + \table 70% \row \li \l{QAbstractItemModel::flags()}{flags()} \li Used by other components to obtain information about each item provided by the model. In many models, the combination of flags should include @@ -1982,7 +1982,7 @@ Additionally, the following functions \e{must} be implemented in direct subclasses of QAbstractTableModel and QAbstractItemModel: - \table 90% + \table 70% \row \li \l{QAbstractItemModel::columnCount()}{columnCount()} \li Provides the number of columns of data exposed by the model. List models do not provide this function because it is already implemented in QAbstractListModel. @@ -1994,7 +1994,7 @@ functions to allow rows and columns to be inserted and removed. To enable editing, the following functions must be implemented correctly: - \table 90% + \table 70% \row \li \l{QAbstractItemModel::flags()}{flags()} \li Must return an appropriate combination of flags for each item. In particular, the value returned by this function must include \l{Qt::ItemIsEditable} in @@ -2024,7 +2024,7 @@ ensure that the appropriate functions are called to notify attached views and delegates: - \table 90% + \table 70% \row \li \l{QAbstractItemModel::insertRows()}{insertRows()} \li Used to add new rows and items of data to all types of model. Implementations must call @@ -2119,7 +2119,7 @@ structure, it is up to each model subclass to create its own model indexes by providing implementations of the following functions: - \table 90% + \table 70% \row \li \l{QAbstractItemModel::index()}{index()} \li Given a model index for a parent item, this function allows views and delegates to access children of that item. If no valid child item - corresponding to the @@ -2164,7 +2164,7 @@ The following types are used to store information about each item as it is streamed into a QByteArray and stored in a QMimeData object: - \table 90% + \table 70% \header \li Description \li Type \row \li Row \li int \row \li Column \li int @@ -2180,7 +2180,7 @@ export items of data in specialized formats by reimplementing the following function: - \table 90% + \table 70% \row \li \l{QAbstractItemModel::mimeData()}{mimeData()} \li This function can be reimplemented to return data in formats other than the default \c{application/x-qabstractitemmodeldatalist} internal @@ -2215,7 +2215,7 @@ To take advantage of QAbstractItemModel's default implementation for the built-in MIME type, new models must provide reimplementations of the following functions: - \table 90% + \table 70% \row \li \l{QAbstractItemModel::insertRows()}{insertRows()} \li {1, 2} These functions enable the model to automatically insert new data using the existing implementation provided by QAbstractItemModel::dropMimeData(). @@ -2228,7 +2228,7 @@ To accept other forms of data, these functions must be reimplemented: - \table 90% + \table 70% \row \li \l{QAbstractItemModel::supportedDropActions()}{supportedDropActions()} \li Used to return a combination of \l{Qt::DropActions}{drop actions}, indicating the types of drag and drop operations that the model accepts. diff --git a/src/widgets/doc/src/widgets-and-layouts/focus.qdoc b/src/widgets/doc/src/widgets-and-layouts/focus.qdoc index 7add31a194a8c455df8c651241e4f58b6244e221..d7a2361dda3159612ab596574a0045ce2480cdc2 100644 --- a/src/widgets/doc/src/widgets-and-layouts/focus.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/focus.qdoc @@ -162,13 +162,13 @@ \section2 The User Rotates the Mouse Wheel On Microsoft Windows, mouse wheel usage is always handled by the - widget that has keyboard focus. On Mac OS X and X11, it's handled by + widget that has keyboard focus. On OS X and X11, it's handled by the widget that gets other mouse events. The way Qt handles this platform difference is by letting widgets move the keyboard focus when the wheel is used. With the right focus policy on each widget, applications can work idiomatically correctly on - Windows, Mac OS X, and X11. + Windows, OS X, and X11. \section2 The User Moves the Focus to This Window diff --git a/src/widgets/doc/src/widgets-and-layouts/styles.qdoc b/src/widgets/doc/src/widgets-and-layouts/styles.qdoc index c15281cb69c1533ad47d6dc0e19695ea40d50944..0a5a079969954c91f3fea5a06f62d6d1190610fd 100644 --- a/src/widgets/doc/src/widgets-and-layouts/styles.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/styles.qdoc @@ -115,7 +115,7 @@ The widget is passed as the last argument in case the style needs it to perform special effects (such as animated default buttons on - Mac OS X), but it isn't mandatory. + OS X), but it isn't mandatory. In the course of this section, we will look at the style elements, the style options, and the functions of QStyle. Finally, we describe diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc index 8dbc71602791e7f66d6d668494b4fdbebdd960fb..fc3ac345a8b2cc7c2abcc0b67847ce03ce5bef1c 100644 --- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc @@ -80,7 +80,7 @@ the QPalette::Button role to red for a QPushButton to obtain a red push button. However, this wasn't guaranteed to work for all styles, because style authors are restricted by the different - platforms' guidelines and (on Windows XP and Mac OS X) by the + platforms' guidelines and (on Windows XP and OS X) by the native theme engine. Style sheets let you perform all kinds of customizations that are @@ -121,7 +121,7 @@ \row \li \inlineimage stylesheet-coffee-cleanlooks.png \li \inlineimage stylesheet-pagefold-mac.png \row \li Coffee theme running on Ubuntu Linux - \li Pagefold theme running on Mac OS X + \li Pagefold theme running on OS X \endtable When a style sheet is active, the QStyle returned by QWidget::style() @@ -130,7 +130,7 @@ otherwise forwards the drawing operations to the underlying, platform-specific style (e.g., QWindowsXPStyle on Windows XP). - Since Qt 4.5, Qt style sheets fully supports Mac OS X. + Since Qt 4.5, Qt style sheets fully supports OS X. */ @@ -3745,7 +3745,7 @@ \snippet code/doc_src_stylesheet.qdoc 135 If you want the scroll buttons of the scroll bar to be placed together - (instead of the edges) like on Mac OS X, you can use the following + (instead of the edges) like on OS X, you can use the following stylesheet: \snippet code/doc_src_stylesheet.qdoc 136 diff --git a/src/widgets/doc/src/widgets-tutorial.qdoc b/src/widgets/doc/src/widgets-tutorial.qdoc index 31d8c612e91bf98940941512a7ff03b47df420bb..a337a7a487ef4a46c8fd15dff863f69400537dc5 100644 --- a/src/widgets/doc/src/widgets-tutorial.qdoc +++ b/src/widgets/doc/src/widgets-tutorial.qdoc @@ -110,7 +110,7 @@ make sure that the executable is on your path, or enter its full location. - \li On Linux/Unix and Mac OS X, type \c make and press + \li On Linux/Unix and OS X, type \c make and press \uicontrol{Return}; on Windows with Visual Studio, type \c nmake and press \uicontrol{Return}. @@ -160,6 +160,7 @@ \table \row \li \snippet tutorials/widgets/childwidget/main.cpp main program + \row \li \inlineimage widgets-tutorial-childwidget.png \endtable \enddiv @@ -182,6 +183,7 @@ \table \row \li \snippet tutorials/widgets/windowlayout/main.cpp main program + \row \li \inlineimage widgets-tutorial-windowlayout.png \endtable \enddiv diff --git a/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc b/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc index 7610174744ecabf6b4183bbf7c78ac80a2e00aad..0e52944bb01501c87eadee4ca8afe907d074a9cf 100644 --- a/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc +++ b/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc @@ -226,7 +226,11 @@ We create a toolbar as a child of the main window, and add the desired actions to it: - \snippet mainwindows/sdi/mainwindow.cpp 0 + \code + fileToolBar = addToolBar(tr("File")); + fileToolBar->addAction(newAct); + fileToolBar->addAction(openAct); + \endcode \dots \snippet code/doc_src_qt4-mainwindow.cpp 1 diff --git a/src/widgets/effects/qgraphicseffect.h b/src/widgets/effects/qgraphicseffect.h index 678ece3dd2d9264f16c231b3d07604a145cc1051..c43b607d3956299c47ba46e30f749c64c3b226a3 100644 --- a/src/widgets/effects/qgraphicseffect.h +++ b/src/widgets/effects/qgraphicseffect.h @@ -72,7 +72,7 @@ public: PadToEffectiveBoundingRect }; - QGraphicsEffect(QObject *parent = 0); + QGraphicsEffect(QObject *parent = Q_NULLPTR); virtual ~QGraphicsEffect(); virtual QRectF boundingRectFor(const QRectF &sourceRect) const; @@ -88,7 +88,7 @@ Q_SIGNALS: void enabledChanged(bool enabled); protected: - QGraphicsEffect(QGraphicsEffectPrivate &d, QObject *parent = 0); + QGraphicsEffect(QGraphicsEffectPrivate &d, QObject *parent = Q_NULLPTR); virtual void draw(QPainter *painter) = 0; virtual void sourceChanged(ChangeFlags flags); void updateBoundingRect(); @@ -97,7 +97,7 @@ protected: QRectF sourceBoundingRect(Qt::CoordinateSystem system = Qt::LogicalCoordinates) const; void drawSource(QPainter *painter); QPixmap sourcePixmap(Qt::CoordinateSystem system = Qt::LogicalCoordinates, - QPoint *offset = 0, + QPoint *offset = Q_NULLPTR, PixmapPadMode mode = PadToEffectiveBoundingRect) const; private: @@ -122,7 +122,7 @@ class Q_WIDGETS_EXPORT QGraphicsColorizeEffect: public QGraphicsEffect Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) public: - QGraphicsColorizeEffect(QObject *parent = 0); + QGraphicsColorizeEffect(QObject *parent = Q_NULLPTR); ~QGraphicsColorizeEffect(); QColor color() const; @@ -159,7 +159,7 @@ public: }; Q_DECLARE_FLAGS(BlurHints, BlurHint) - QGraphicsBlurEffect(QObject *parent = 0); + QGraphicsBlurEffect(QObject *parent = Q_NULLPTR); ~QGraphicsBlurEffect(); QRectF boundingRectFor(const QRectF &rect) const Q_DECL_OVERRIDE; @@ -194,7 +194,7 @@ class Q_WIDGETS_EXPORT QGraphicsDropShadowEffect: public QGraphicsEffect Q_PROPERTY(qreal blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged) Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) public: - QGraphicsDropShadowEffect(QObject *parent = 0); + QGraphicsDropShadowEffect(QObject *parent = Q_NULLPTR); ~QGraphicsDropShadowEffect(); QRectF boundingRectFor(const QRectF &rect) const Q_DECL_OVERRIDE; @@ -247,7 +247,7 @@ class Q_WIDGETS_EXPORT QGraphicsOpacityEffect: public QGraphicsEffect Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged) Q_PROPERTY(QBrush opacityMask READ opacityMask WRITE setOpacityMask NOTIFY opacityMaskChanged) public: - QGraphicsOpacityEffect(QObject *parent = 0); + QGraphicsOpacityEffect(QObject *parent = Q_NULLPTR); ~QGraphicsOpacityEffect(); qreal opacity() const; diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout.h b/src/widgets/graphicsview/qgraphicsanchorlayout.h index 90406fe71f8981264e79ab3045c8190cb9cc675b..2fdfe75be9272d8d1d0a634f0bd8bd3e369763c1 100644 --- a/src/widgets/graphicsview/qgraphicsanchorlayout.h +++ b/src/widgets/graphicsview/qgraphicsanchorlayout.h @@ -71,7 +71,7 @@ private: class Q_WIDGETS_EXPORT QGraphicsAnchorLayout : public QGraphicsLayout { public: - QGraphicsAnchorLayout(QGraphicsLayoutItem *parent = 0); + QGraphicsAnchorLayout(QGraphicsLayoutItem *parent = Q_NULLPTR); virtual ~QGraphicsAnchorLayout(); QGraphicsAnchor *addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp index 8327777217e0d0630ed8f84426ead0be90f2fcad..dac8e6164587827ac5b112eaac86043e431591f8 100644 --- a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp @@ -751,9 +751,12 @@ static AnchorData *createSequence(Graph<AnchorVertex, AnchorData> *graph, AnchorVertex *prev = before; QVector<AnchorData *> edges; + edges.reserve(vertices.count() + 1); + const int numVertices = vertices.count(); + edges.reserve(numVertices + 1); // Take from the graph, the edges that will be simplificated - for (int i = 0; i < vertices.count(); ++i) { + for (int i = 0; i < numVertices; ++i) { AnchorVertex *next = vertices.at(i); AnchorData *ad = graph->takeEdge(prev, next); Q_ASSERT(ad); @@ -2569,6 +2572,7 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation) if (!remainingConstraints.isEmpty()) { QList<QSimplexConstraint *> nonTrunkConstraints; + nonTrunkConstraints.reserve(remainingConstraints.size()); QLinkedList<QSimplexConstraint *>::iterator it = remainingConstraints.begin(); while (it != remainingConstraints.end()) { nonTrunkConstraints += *it; diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout_p.h b/src/widgets/graphicsview/qgraphicsanchorlayout_p.h index c0bb8ef63acf1c38cabad7d3bd447ab0b0cf8ade..a5c7f1e2ce4184f25d00124bd631afc49f384911 100644 --- a/src/widgets/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.h @@ -317,6 +317,7 @@ public: QSet<AnchorData *> positives; QSet<AnchorData *> negatives; }; +Q_DECLARE_TYPEINFO(GraphPath, Q_MOVABLE_TYPE); class QGraphicsAnchorLayoutPrivate; /*! diff --git a/src/widgets/graphicsview/qgraphicsgridlayout.h b/src/widgets/graphicsview/qgraphicsgridlayout.h index 90cc316025edfd6c736314768c38835216a2fdc8..f6aa3af91d90f6e5f1e53730a0259a64df861fd5 100644 --- a/src/widgets/graphicsview/qgraphicsgridlayout.h +++ b/src/widgets/graphicsview/qgraphicsgridlayout.h @@ -47,12 +47,12 @@ class QGraphicsGridLayoutPrivate; class Q_WIDGETS_EXPORT QGraphicsGridLayout : public QGraphicsLayout { public: - QGraphicsGridLayout(QGraphicsLayoutItem *parent = 0); + QGraphicsGridLayout(QGraphicsLayoutItem *parent = Q_NULLPTR); virtual ~QGraphicsGridLayout(); void addItem(QGraphicsLayoutItem *item, int row, int column, int rowSpan, int columnSpan, - Qt::Alignment alignment = 0); - inline void addItem(QGraphicsLayoutItem *item, int row, int column, Qt::Alignment alignment = 0); + Qt::Alignment alignment = Qt::Alignment()); + inline void addItem(QGraphicsLayoutItem *item, int row, int column, Qt::Alignment alignment = Qt::Alignment()); void setHorizontalSpacing(qreal spacing); qreal horizontalSpacing() const; diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index 1fdbe0fc1817941625c3f7bd16deb47a6f52a14b..0259ce216b3e801629708d409ab9a5c28aa79614 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -428,7 +428,7 @@ \note If both this flag and ItemClipsChildrenToShape are set, the clip will be enforced. This is equivalent to just setting ItemClipsChildrenToShape. - . + This flag was introduced in Qt 5.4. */ diff --git a/src/widgets/graphicsview/qgraphicsitem.h b/src/widgets/graphicsview/qgraphicsitem.h index d3540beb77d37f751be3026e6fffbf0a80291af6..b2f8fcbe74752298a23822b194e3b96f66ac6660 100644 --- a/src/widgets/graphicsview/qgraphicsitem.h +++ b/src/widgets/graphicsview/qgraphicsitem.h @@ -153,7 +153,7 @@ public: SceneModal }; - explicit QGraphicsItem(QGraphicsItem *parent = 0); + explicit QGraphicsItem(QGraphicsItem *parent = Q_NULLPTR); virtual ~QGraphicsItem(); QGraphicsScene *scene() const; @@ -189,7 +189,7 @@ public: PanelModality panelModality() const; void setPanelModality(PanelModality panelModality); - bool isBlockedByModalPanel(QGraphicsItem **blockingPanel = 0) const; + bool isBlockedByModalPanel(QGraphicsItem **blockingPanel = Q_NULLPTR) const; #ifndef QT_NO_TOOLTIP QString toolTip() const; @@ -285,7 +285,7 @@ public: QTransform transform() const; QTransform sceneTransform() const; QTransform deviceTransform(const QTransform &viewportTransform) const; - QTransform itemTransform(const QGraphicsItem *other, bool *ok = 0) const; + QTransform itemTransform(const QGraphicsItem *other, bool *ok = Q_NULLPTR) const; void setTransform(const QTransform &matrix, bool combine = false); void resetTransform(); #if QT_DEPRECATED_SINCE(5, 0) @@ -336,7 +336,7 @@ public: void setBoundingRegionGranularity(qreal granularity); // Drawing - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR) = 0; void update(const QRectF &rect = QRectF()); inline void update(qreal x, qreal y, qreal width, qreal height); void scroll(qreal dx, qreal dy, const QRectF &rect = QRectF()); @@ -553,7 +553,7 @@ class Q_WIDGETS_EXPORT QGraphicsObject : public QObject, public QGraphicsItem Q_CLASSINFO("DefaultProperty", "children") Q_INTERFACES(QGraphicsItem) public: - explicit QGraphicsObject(QGraphicsItem *parent = 0); + explicit QGraphicsObject(QGraphicsItem *parent = Q_NULLPTR); ~QGraphicsObject(); using QObject::children; @@ -595,7 +595,7 @@ class QAbstractGraphicsShapeItemPrivate; class Q_WIDGETS_EXPORT QAbstractGraphicsShapeItem : public QGraphicsItem { public: - explicit QAbstractGraphicsShapeItem(QGraphicsItem *parent = 0); + explicit QAbstractGraphicsShapeItem(QGraphicsItem *parent = Q_NULLPTR); ~QAbstractGraphicsShapeItem(); QPen pen() const; @@ -620,8 +620,8 @@ class QGraphicsPathItemPrivate; class Q_WIDGETS_EXPORT QGraphicsPathItem : public QAbstractGraphicsShapeItem { public: - explicit QGraphicsPathItem(QGraphicsItem *parent = 0); - explicit QGraphicsPathItem(const QPainterPath &path, QGraphicsItem *parent = 0); + explicit QGraphicsPathItem(QGraphicsItem *parent = Q_NULLPTR); + explicit QGraphicsPathItem(const QPainterPath &path, QGraphicsItem *parent = Q_NULLPTR); ~QGraphicsPathItem(); QPainterPath path() const; @@ -631,7 +631,7 @@ public: QPainterPath shape() const Q_DECL_OVERRIDE; bool contains(const QPointF &point) const Q_DECL_OVERRIDE; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) Q_DECL_OVERRIDE; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR) Q_DECL_OVERRIDE; bool isObscuredBy(const QGraphicsItem *item) const Q_DECL_OVERRIDE; QPainterPath opaqueArea() const Q_DECL_OVERRIDE; @@ -653,9 +653,9 @@ class QGraphicsRectItemPrivate; class Q_WIDGETS_EXPORT QGraphicsRectItem : public QAbstractGraphicsShapeItem { public: - explicit QGraphicsRectItem(QGraphicsItem *parent = 0); - explicit QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent = 0); - explicit QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0); + explicit QGraphicsRectItem(QGraphicsItem *parent = Q_NULLPTR); + explicit QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent = Q_NULLPTR); + explicit QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = Q_NULLPTR); ~QGraphicsRectItem(); QRectF rect() const; @@ -666,7 +666,7 @@ public: QPainterPath shape() const Q_DECL_OVERRIDE; bool contains(const QPointF &point) const Q_DECL_OVERRIDE; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) Q_DECL_OVERRIDE; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR) Q_DECL_OVERRIDE; bool isObscuredBy(const QGraphicsItem *item) const Q_DECL_OVERRIDE; QPainterPath opaqueArea() const Q_DECL_OVERRIDE; @@ -691,9 +691,9 @@ class QGraphicsEllipseItemPrivate; class Q_WIDGETS_EXPORT QGraphicsEllipseItem : public QAbstractGraphicsShapeItem { public: - explicit QGraphicsEllipseItem(QGraphicsItem *parent = 0); - explicit QGraphicsEllipseItem(const QRectF &rect, QGraphicsItem *parent = 0); - explicit QGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0); + explicit QGraphicsEllipseItem(QGraphicsItem *parent = Q_NULLPTR); + explicit QGraphicsEllipseItem(const QRectF &rect, QGraphicsItem *parent = Q_NULLPTR); + explicit QGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = Q_NULLPTR); ~QGraphicsEllipseItem(); QRectF rect() const; @@ -710,7 +710,7 @@ public: QPainterPath shape() const Q_DECL_OVERRIDE; bool contains(const QPointF &point) const Q_DECL_OVERRIDE; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) Q_DECL_OVERRIDE; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR) Q_DECL_OVERRIDE; bool isObscuredBy(const QGraphicsItem *item) const Q_DECL_OVERRIDE; QPainterPath opaqueArea() const Q_DECL_OVERRIDE; @@ -735,9 +735,9 @@ class QGraphicsPolygonItemPrivate; class Q_WIDGETS_EXPORT QGraphicsPolygonItem : public QAbstractGraphicsShapeItem { public: - explicit QGraphicsPolygonItem(QGraphicsItem *parent = 0); + explicit QGraphicsPolygonItem(QGraphicsItem *parent = Q_NULLPTR); explicit QGraphicsPolygonItem(const QPolygonF &polygon, - QGraphicsItem *parent = 0); + QGraphicsItem *parent = Q_NULLPTR); ~QGraphicsPolygonItem(); QPolygonF polygon() const; @@ -750,7 +750,7 @@ public: QPainterPath shape() const Q_DECL_OVERRIDE; bool contains(const QPointF &point) const Q_DECL_OVERRIDE; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) Q_DECL_OVERRIDE; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR) Q_DECL_OVERRIDE; bool isObscuredBy(const QGraphicsItem *item) const Q_DECL_OVERRIDE; QPainterPath opaqueArea() const Q_DECL_OVERRIDE; @@ -772,9 +772,9 @@ class QGraphicsLineItemPrivate; class Q_WIDGETS_EXPORT QGraphicsLineItem : public QGraphicsItem { public: - explicit QGraphicsLineItem(QGraphicsItem *parent = 0); - explicit QGraphicsLineItem(const QLineF &line, QGraphicsItem *parent = 0); - explicit QGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent = 0); + explicit QGraphicsLineItem(QGraphicsItem *parent = Q_NULLPTR); + explicit QGraphicsLineItem(const QLineF &line, QGraphicsItem *parent = Q_NULLPTR); + explicit QGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent = Q_NULLPTR); ~QGraphicsLineItem(); QPen pen() const; @@ -789,7 +789,7 @@ public: QPainterPath shape() const Q_DECL_OVERRIDE; bool contains(const QPointF &point) const Q_DECL_OVERRIDE; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) Q_DECL_OVERRIDE; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR) Q_DECL_OVERRIDE; bool isObscuredBy(const QGraphicsItem *item) const Q_DECL_OVERRIDE; QPainterPath opaqueArea() const Q_DECL_OVERRIDE; @@ -817,8 +817,8 @@ public: HeuristicMaskShape }; - explicit QGraphicsPixmapItem(QGraphicsItem *parent = 0); - explicit QGraphicsPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent = 0); + explicit QGraphicsPixmapItem(QGraphicsItem *parent = Q_NULLPTR); + explicit QGraphicsPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent = Q_NULLPTR); ~QGraphicsPixmapItem(); QPixmap pixmap() const; @@ -869,8 +869,8 @@ class Q_WIDGETS_EXPORT QGraphicsTextItem : public QGraphicsObject QDOC_PROPERTY(QTextCursor textCursor READ textCursor WRITE setTextCursor) public: - explicit QGraphicsTextItem(QGraphicsItem *parent = 0); - explicit QGraphicsTextItem(const QString &text, QGraphicsItem *parent = 0); + explicit QGraphicsTextItem(QGraphicsItem *parent = Q_NULLPTR); + explicit QGraphicsTextItem(const QString &text, QGraphicsItem *parent = Q_NULLPTR); ~QGraphicsTextItem(); QString toHtml() const; @@ -960,8 +960,8 @@ class QGraphicsSimpleTextItemPrivate; class Q_WIDGETS_EXPORT QGraphicsSimpleTextItem : public QAbstractGraphicsShapeItem { public: - explicit QGraphicsSimpleTextItem(QGraphicsItem *parent = 0); - explicit QGraphicsSimpleTextItem(const QString &text, QGraphicsItem *parent = 0); + explicit QGraphicsSimpleTextItem(QGraphicsItem *parent = Q_NULLPTR); + explicit QGraphicsSimpleTextItem(const QString &text, QGraphicsItem *parent = Q_NULLPTR); ~QGraphicsSimpleTextItem(); void setText(const QString &text); @@ -996,14 +996,14 @@ class QGraphicsItemGroupPrivate; class Q_WIDGETS_EXPORT QGraphicsItemGroup : public QGraphicsItem { public: - explicit QGraphicsItemGroup(QGraphicsItem *parent = 0); + explicit QGraphicsItemGroup(QGraphicsItem *parent = Q_NULLPTR); ~QGraphicsItemGroup(); void addToGroup(QGraphicsItem *item); void removeFromGroup(QGraphicsItem *item); QRectF boundingRect() const Q_DECL_OVERRIDE; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) Q_DECL_OVERRIDE; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR) Q_DECL_OVERRIDE; bool isObscuredBy(const QGraphicsItem *item) const Q_DECL_OVERRIDE; QPainterPath opaqueArea() const Q_DECL_OVERRIDE; diff --git a/src/widgets/graphicsview/qgraphicsitem_p.h b/src/widgets/graphicsview/qgraphicsitem_p.h index bf788d2c39cca6c3cb14ff975f5f48c0b2dea4ab..fe4bac12bced2081ac5b12eb3da1af91670daf46 100644 --- a/src/widgets/graphicsview/qgraphicsitem_p.h +++ b/src/widgets/graphicsview/qgraphicsitem_p.h @@ -353,6 +353,7 @@ public: } struct ExtraStruct { + ExtraStruct() {} // for QVector, don't use ExtraStruct(Extra type, QVariant value) : type(type), value(value) { } @@ -364,7 +365,7 @@ public: { return type < extra; } }; - QList<ExtraStruct> extras; + QVector<ExtraStruct> extras; QGraphicsItemCache *maybeExtraItemCache() const; QGraphicsItemCache *extraItemCache() const; @@ -584,6 +585,7 @@ public: int globalStackingOrder; QGraphicsItem *q_ptr; }; +Q_DECLARE_TYPEINFO(QGraphicsItemPrivate::ExtraStruct, Q_MOVABLE_TYPE); struct QGraphicsItemPrivate::TransformData { diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.cpp b/src/widgets/graphicsview/qgraphicsitemanimation.cpp index 0a6fccf55937a57669cd947e7c5df6b2f2fe2977..585539de94fb6b0610852addbab588f97c36bf27 100644 --- a/src/widgets/graphicsview/qgraphicsitemanimation.cpp +++ b/src/widgets/graphicsview/qgraphicsitemanimation.cpp @@ -116,7 +116,6 @@ public: qreal step; struct Pair { - Pair(qreal a, qreal b) : step(a), value(b) {} bool operator <(const Pair &other) const { return step < other.step; } bool operator==(const Pair &other) const @@ -124,21 +123,22 @@ public: qreal step; qreal value; }; - QList<Pair> xPosition; - QList<Pair> yPosition; - QList<Pair> rotation; - QList<Pair> verticalScale; - QList<Pair> horizontalScale; - QList<Pair> verticalShear; - QList<Pair> horizontalShear; - QList<Pair> xTranslation; - QList<Pair> yTranslation; - - qreal linearValueForStep(qreal step, QList<Pair> *source, qreal defaultValue = 0); - void insertUniquePair(qreal step, qreal value, QList<Pair> *binList, const char* method); + QVector<Pair> xPosition; + QVector<Pair> yPosition; + QVector<Pair> rotation; + QVector<Pair> verticalScale; + QVector<Pair> horizontalScale; + QVector<Pair> verticalShear; + QVector<Pair> horizontalShear; + QVector<Pair> xTranslation; + QVector<Pair> yTranslation; + + qreal linearValueForStep(qreal step, QVector<Pair> *source, qreal defaultValue = 0); + void insertUniquePair(qreal step, qreal value, QVector<Pair> *binList, const char* method); }; +Q_DECLARE_TYPEINFO(QGraphicsItemAnimationPrivate::Pair, Q_PRIMITIVE_TYPE); -qreal QGraphicsItemAnimationPrivate::linearValueForStep(qreal step, QList<Pair> *source, qreal defaultValue) +qreal QGraphicsItemAnimationPrivate::linearValueForStep(qreal step, QVector<Pair> *source, qreal defaultValue) { if (source->isEmpty()) return defaultValue; @@ -168,20 +168,18 @@ qreal QGraphicsItemAnimationPrivate::linearValueForStep(qreal step, QList<Pair> return valueBefore + (valueAfter - valueBefore) * ((step - stepBefore) / (stepAfter - stepBefore)); } -void QGraphicsItemAnimationPrivate::insertUniquePair(qreal step, qreal value, QList<Pair> *binList, const char* method) +void QGraphicsItemAnimationPrivate::insertUniquePair(qreal step, qreal value, QVector<Pair> *binList, const char* method) { if (!check_step_valid(step, method)) return; - Pair pair(step, value); + const Pair pair = { step, value }; - QList<Pair>::iterator result = std::lower_bound(binList->begin(), binList->end(), pair); - if ((result != binList->end()) && !(pair < *result)) + const QVector<Pair>::iterator result = std::lower_bound(binList->begin(), binList->end(), pair); + if (result == binList->end() || pair < *result) + binList->insert(result, pair); + else result->value = value; - else { - *binList << pair; - std::sort(binList->begin(), binList->end()); - } } /*! @@ -284,7 +282,9 @@ void QGraphicsItemAnimation::setPosAt(qreal step, const QPointF &pos) QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::posList() const { QList<QPair<qreal, QPointF> > list; - for (int i = 0; i < d->xPosition.size(); ++i) + const int xPosCount = d->xPosition.size(); + list.reserve(xPosCount); + for (int i = 0; i < xPosCount; ++i) list << QPair<qreal, QPointF>(d->xPosition.at(i).step, QPointF(d->xPosition.at(i).value, d->yPosition.at(i).value)); return list; @@ -338,7 +338,9 @@ void QGraphicsItemAnimation::setRotationAt(qreal step, qreal angle) QList<QPair<qreal, qreal> > QGraphicsItemAnimation::rotationList() const { QList<QPair<qreal, qreal> > list; - for (int i = 0; i < d->rotation.size(); ++i) + const int numRotations = d->rotation.size(); + list.reserve(numRotations); + for (int i = 0; i < numRotations; ++i) list << QPair<qreal, qreal>(d->rotation.at(i).step, d->rotation.at(i).value); return list; @@ -386,7 +388,9 @@ void QGraphicsItemAnimation::setTranslationAt(qreal step, qreal dx, qreal dy) QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::translationList() const { QList<QPair<qreal, QPointF> > list; - for (int i = 0; i < d->xTranslation.size(); ++i) + const int numTranslations = d->xTranslation.size(); + list.reserve(numTranslations); + for (int i = 0; i < numTranslations; ++i) list << QPair<qreal, QPointF>(d->xTranslation.at(i).step, QPointF(d->xTranslation.at(i).value, d->yTranslation.at(i).value)); return list; @@ -435,7 +439,9 @@ void QGraphicsItemAnimation::setScaleAt(qreal step, qreal sx, qreal sy) QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::scaleList() const { QList<QPair<qreal, QPointF> > list; - for (int i = 0; i < d->horizontalScale.size(); ++i) + const int numScales = d->horizontalScale.size(); + list.reserve(numScales); + for (int i = 0; i < numScales; ++i) list << QPair<qreal, QPointF>(d->horizontalScale.at(i).step, QPointF(d->horizontalScale.at(i).value, d->verticalScale.at(i).value)); return list; @@ -483,7 +489,9 @@ void QGraphicsItemAnimation::setShearAt(qreal step, qreal sh, qreal sv) QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::shearList() const { QList<QPair<qreal, QPointF> > list; - for (int i = 0; i < d->horizontalShear.size(); ++i) + const int numShears = d->horizontalShear.size(); + list.reserve(numShears); + for (int i = 0; i < numShears; ++i) list << QPair<qreal, QPointF>(d->horizontalShear.at(i).step, QPointF(d->horizontalShear.at(i).value, d->verticalShear.at(i).value)); return list; diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.h b/src/widgets/graphicsview/qgraphicsitemanimation.h index 02a20f3f01878da8f98076bb5567b0841dfb1f28..a54ba3a9e979e91eafed49c202e023f29dee85e7 100644 --- a/src/widgets/graphicsview/qgraphicsitemanimation.h +++ b/src/widgets/graphicsview/qgraphicsitemanimation.h @@ -52,7 +52,7 @@ class Q_WIDGETS_EXPORT QGraphicsItemAnimation : public QObject { Q_OBJECT public: - QGraphicsItemAnimation(QObject *parent = 0); + QGraphicsItemAnimation(QObject *parent = Q_NULLPTR); virtual ~QGraphicsItemAnimation(); QGraphicsItem *item() const; diff --git a/src/widgets/graphicsview/qgraphicslayout.h b/src/widgets/graphicsview/qgraphicslayout.h index ebd90735f1a6ded3710b82684e65818ed072b774..84a8d9794315384b633f0983be052170bb2057ae 100644 --- a/src/widgets/graphicsview/qgraphicslayout.h +++ b/src/widgets/graphicsview/qgraphicslayout.h @@ -48,7 +48,7 @@ class QGraphicsWidget; class Q_WIDGETS_EXPORT QGraphicsLayout : public QGraphicsLayoutItem { public: - QGraphicsLayout(QGraphicsLayoutItem *parent = 0); + QGraphicsLayout(QGraphicsLayoutItem *parent = Q_NULLPTR); ~QGraphicsLayout(); void setContentsMargins(qreal left, qreal top, qreal right, qreal bottom); diff --git a/src/widgets/graphicsview/qgraphicslayoutitem.h b/src/widgets/graphicsview/qgraphicslayoutitem.h index 85b6d901f20c5bd7094ed301cd819fe4c857851f..1608d798362474cb90348989510c745d0a297110 100644 --- a/src/widgets/graphicsview/qgraphicslayoutitem.h +++ b/src/widgets/graphicsview/qgraphicslayoutitem.h @@ -48,7 +48,7 @@ class QGraphicsItem; class Q_WIDGETS_EXPORT QGraphicsLayoutItem { public: - QGraphicsLayoutItem(QGraphicsLayoutItem *parent = 0, bool isLayout = false); + QGraphicsLayoutItem(QGraphicsLayoutItem *parent = Q_NULLPTR, bool isLayout = false); virtual ~QGraphicsLayoutItem(); void setSizePolicy(const QSizePolicy &policy); diff --git a/src/widgets/graphicsview/qgraphicslinearlayout.h b/src/widgets/graphicsview/qgraphicslinearlayout.h index 997bff7da1d98293509eb17eb2bf4c71712bfeb4..3232da22cafdf6d1a100d3ed96e8a7f3c785e414 100644 --- a/src/widgets/graphicsview/qgraphicslinearlayout.h +++ b/src/widgets/graphicsview/qgraphicslinearlayout.h @@ -47,8 +47,8 @@ class QGraphicsLinearLayoutPrivate; class Q_WIDGETS_EXPORT QGraphicsLinearLayout : public QGraphicsLayout { public: - QGraphicsLinearLayout(QGraphicsLayoutItem *parent = 0); - QGraphicsLinearLayout(Qt::Orientation orientation, QGraphicsLayoutItem *parent = 0); + QGraphicsLinearLayout(QGraphicsLayoutItem *parent = Q_NULLPTR); + QGraphicsLinearLayout(Qt::Orientation orientation, QGraphicsLayoutItem *parent = Q_NULLPTR); virtual ~QGraphicsLinearLayout(); void setOrientation(Qt::Orientation orientation); diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.h b/src/widgets/graphicsview/qgraphicsproxywidget.h index ae52f88f16ce2c9d784dda38d17e50d37ed1fdac..5a03a8a9dd015de00655b3ca6d325b3a1260fb3b 100644 --- a/src/widgets/graphicsview/qgraphicsproxywidget.h +++ b/src/widgets/graphicsview/qgraphicsproxywidget.h @@ -47,7 +47,7 @@ class Q_WIDGETS_EXPORT QGraphicsProxyWidget : public QGraphicsWidget { Q_OBJECT public: - QGraphicsProxyWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); + QGraphicsProxyWidget(QGraphicsItem *parent = Q_NULLPTR, Qt::WindowFlags wFlags = Qt::WindowFlags()); ~QGraphicsProxyWidget(); void setWidget(QWidget *widget); diff --git a/src/widgets/graphicsview/qgraphicsscene.h b/src/widgets/graphicsview/qgraphicsscene.h index 68382bf498394eff16f7f505decb71da60c9e772..c93db207160cae6ae4ae28c002493d4cd0aab63e 100644 --- a/src/widgets/graphicsview/qgraphicsscene.h +++ b/src/widgets/graphicsview/qgraphicsscene.h @@ -115,9 +115,9 @@ public: }; Q_DECLARE_FLAGS(SceneLayers, SceneLayer) - QGraphicsScene(QObject *parent = 0); - QGraphicsScene(const QRectF &sceneRect, QObject *parent = 0); - QGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent = 0); + QGraphicsScene(QObject *parent = Q_NULLPTR); + QGraphicsScene(const QRectF &sceneRect, QObject *parent = Q_NULLPTR); + QGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent = Q_NULLPTR); virtual ~QGraphicsScene(); QRectF sceneRect() const; @@ -192,7 +192,7 @@ public: QGraphicsRectItem *addRect(const QRectF &rect, const QPen &pen = QPen(), const QBrush &brush = QBrush()); QGraphicsTextItem *addText(const QString &text, const QFont &font = QFont()); QGraphicsSimpleTextItem *addSimpleText(const QString &text, const QFont &font = QFont()); - QGraphicsProxyWidget *addWidget(QWidget *widget, Qt::WindowFlags wFlags = 0); + QGraphicsProxyWidget *addWidget(QWidget *widget, Qt::WindowFlags wFlags = Qt::WindowFlags()); inline QGraphicsEllipseItem *addEllipse(qreal x, qreal y, qreal w, qreal h, const QPen &pen = QPen(), const QBrush &brush = QBrush()) { return addEllipse(QRectF(x, y, w, h), pen, brush); } inline QGraphicsLineItem *addLine(qreal x1, qreal y1, qreal x2, qreal y2, const QPen &pen = QPen()) @@ -279,7 +279,7 @@ protected: virtual void drawItems(QPainter *painter, int numItems, QGraphicsItem *items[], const QStyleOptionGraphicsItem options[], - QWidget *widget = 0); + QWidget *widget = Q_NULLPTR); protected Q_SLOTS: // ### Qt 6: make unconditional diff --git a/src/widgets/graphicsview/qgraphicssceneevent.cpp b/src/widgets/graphicsview/qgraphicssceneevent.cpp index 425bd50d42a3de22295542561dc802751a7482b0..071d34280a2323bd54f14c86efd5f0a2030f1b19 100644 --- a/src/widgets/graphicsview/qgraphicssceneevent.cpp +++ b/src/widgets/graphicsview/qgraphicssceneevent.cpp @@ -143,7 +143,7 @@ platforms, this means the right mouse button was clicked. \value Keyboard The keyboard caused this event to be sent. On - Windows and Mac OS X, this means the menu button was pressed. + Windows and OS X, this means the menu button was pressed. \value Other The event was sent by some other means (i.e. not by the mouse or keyboard). diff --git a/src/widgets/graphicsview/qgraphicssceneindex.cpp b/src/widgets/graphicsview/qgraphicssceneindex.cpp index 8662f73d64808f75af68458a67c15b9c2c02db94..a76f6b6565adaca8def5c5d049a36e9f5dfbec92 100644 --- a/src/widgets/graphicsview/qgraphicssceneindex.cpp +++ b/src/widgets/graphicsview/qgraphicssceneindex.cpp @@ -520,7 +520,9 @@ QList<QGraphicsItem *> QGraphicsSceneIndex::estimateTopLevelItems(const QRectF & scened->ensureSortedTopLevelItems(); if (order == Qt::DescendingOrder) { QList<QGraphicsItem *> sorted; - for (int i = scened->topLevelItems.size() - 1; i >= 0; --i) + const int numTopLevelItems = scened->topLevelItems.size(); + sorted.reserve(numTopLevelItems); + for (int i = numTopLevelItems - 1; i >= 0; --i) sorted << scened->topLevelItems.at(i); return sorted; } diff --git a/src/widgets/graphicsview/qgraphicstransform.h b/src/widgets/graphicsview/qgraphicstransform.h index 4a7a3d0c0b12a54730884c212ede153e4c214297..6fa76683f2def19954eb6091c7e801dca3583c50 100644 --- a/src/widgets/graphicsview/qgraphicstransform.h +++ b/src/widgets/graphicsview/qgraphicstransform.h @@ -50,7 +50,7 @@ class Q_WIDGETS_EXPORT QGraphicsTransform : public QObject { Q_OBJECT public: - QGraphicsTransform(QObject *parent = 0); + QGraphicsTransform(QObject *parent = Q_NULLPTR); ~QGraphicsTransform(); virtual void applyTo(QMatrix4x4 *matrix) const = 0; @@ -78,7 +78,7 @@ class Q_WIDGETS_EXPORT QGraphicsScale : public QGraphicsTransform Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY yScaleChanged) Q_PROPERTY(qreal zScale READ zScale WRITE setZScale NOTIFY zScaleChanged) public: - QGraphicsScale(QObject *parent = 0); + QGraphicsScale(QObject *parent = Q_NULLPTR); ~QGraphicsScale(); QVector3D origin() const; @@ -116,7 +116,7 @@ class Q_WIDGETS_EXPORT QGraphicsRotation : public QGraphicsTransform Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) Q_PROPERTY(QVector3D axis READ axis WRITE setAxis NOTIFY axisChanged) public: - QGraphicsRotation(QObject *parent = 0); + QGraphicsRotation(QObject *parent = Q_NULLPTR); ~QGraphicsRotation(); QVector3D origin() const; diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index decb4559885ab04a64bdaf8898b858d7f22f9459..ac8cd45f9ea6b326013285ece8ba825dc0138f5d 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -2464,6 +2464,7 @@ QPolygonF QGraphicsView::mapToScene(const QRect &rect) const QPolygonF QGraphicsView::mapToScene(const QPolygon &polygon) const { QPolygonF poly; + poly.reserve(polygon.count()); foreach (const QPoint &point, polygon) poly << mapToScene(point); return poly; @@ -2559,6 +2560,7 @@ QPolygon QGraphicsView::mapFromScene(const QRectF &rect) const QPolygon QGraphicsView::mapFromScene(const QPolygonF &polygon) const { QPolygon poly; + poly.reserve(polygon.count()); foreach (const QPointF &point, polygon) poly << mapFromScene(point); return poly; @@ -2673,7 +2675,9 @@ void QGraphicsView::updateScene(const QList<QRectF> &rects) // Extract and reset dirty scene rect info. QVector<QRect> dirtyViewportRects; const QVector<QRect> &dirtyRects = d->dirtyRegion.rects(); - for (int i = 0; i < dirtyRects.size(); ++i) + const int dirtyRectsCount = dirtyRects.size(); + dirtyViewportRects.reserve(dirtyRectsCount + rects.count()); + for (int i = 0; i < dirtyRectsCount; ++i) dirtyViewportRects += dirtyRects.at(i); d->dirtyRegion = QRegion(); d->dirtyBoundingRect = QRect(); diff --git a/src/widgets/graphicsview/qgraphicsview.h b/src/widgets/graphicsview/qgraphicsview.h index d426273d97ecfb87fd7834fe509d5d3623039ba2..667fa76fe71e4643195b9436a6181ca10eb575fd 100644 --- a/src/widgets/graphicsview/qgraphicsview.h +++ b/src/widgets/graphicsview/qgraphicsview.h @@ -108,8 +108,8 @@ public: }; Q_DECLARE_FLAGS(OptimizationFlags, OptimizationFlag) - QGraphicsView(QWidget *parent = 0); - QGraphicsView(QGraphicsScene *scene, QWidget *parent = 0); + QGraphicsView(QWidget *parent = Q_NULLPTR); + QGraphicsView(QGraphicsScene *scene, QWidget *parent = Q_NULLPTR); ~QGraphicsView(); QSize sizeHint() const Q_DECL_OVERRIDE; @@ -230,7 +230,7 @@ protected Q_SLOTS: void setupViewport(QWidget *widget) Q_DECL_OVERRIDE; protected: - QGraphicsView(QGraphicsViewPrivate &, QWidget *parent = 0); + QGraphicsView(QGraphicsViewPrivate &, QWidget *parent = Q_NULLPTR); bool event(QEvent *event) Q_DECL_OVERRIDE; bool viewportEvent(QEvent *event) Q_DECL_OVERRIDE; diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp index 6f10e2854c8314fc171693918fbec0bfd958d3c3..67311ed2c34df60f4e5760e58a6cda6a39e3dc94 100644 --- a/src/widgets/graphicsview/qgraphicswidget.cpp +++ b/src/widgets/graphicsview/qgraphicswidget.cpp @@ -304,6 +304,7 @@ void QGraphicsWidget::resize(const QSizeF &size) /*! \fn void QGraphicsWidget::resize(qreal w, qreal h) + \overload This convenience function is equivalent to calling resize(QSizeF(w, h)). diff --git a/src/widgets/graphicsview/qgraphicswidget.h b/src/widgets/graphicsview/qgraphicswidget.h index 3ecdeac1588d75bd47d67cde07b3e90731ff0259..0878e020bcd2fe927aebbaaca1294cf8bd3a5f56 100644 --- a/src/widgets/graphicsview/qgraphicswidget.h +++ b/src/widgets/graphicsview/qgraphicswidget.h @@ -74,7 +74,7 @@ class Q_WIDGETS_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphic Q_PROPERTY(bool autoFillBackground READ autoFillBackground WRITE setAutoFillBackground) Q_PROPERTY(QGraphicsLayout* layout READ layout WRITE setLayout NOTIFY layoutChanged) public: - QGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); + QGraphicsWidget(QGraphicsItem *parent = Q_NULLPTR, Qt::WindowFlags wFlags = Qt::WindowFlags()); ~QGraphicsWidget(); QGraphicsLayout *layout() const; void setLayout(QGraphicsLayout *layout); @@ -156,8 +156,8 @@ public: }; int type() const Q_DECL_OVERRIDE; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) Q_DECL_OVERRIDE; - virtual void paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR) Q_DECL_OVERRIDE; + virtual void paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR); QRectF boundingRect() const Q_DECL_OVERRIDE; QPainterPath shape() const Q_DECL_OVERRIDE; @@ -213,7 +213,7 @@ protected: virtual void ungrabMouseEvent(QEvent *event); virtual void grabKeyboardEvent(QEvent *event); virtual void ungrabKeyboardEvent(QEvent *event); - QGraphicsWidget(QGraphicsWidgetPrivate &, QGraphicsItem *parent, Qt::WindowFlags wFlags = 0); + QGraphicsWidget(QGraphicsWidgetPrivate &, QGraphicsItem *parent, Qt::WindowFlags wFlags = Qt::WindowFlags()); private: Q_DISABLE_COPY(QGraphicsWidget) diff --git a/src/widgets/itemviews/itemviews.pri b/src/widgets/itemviews/itemviews.pri index 2bbf7ac1ffac6c1b327ef5dfe66fbf87cc48612f..245962d35fa07670880c5a0770c30a68fbc04102 100644 --- a/src/widgets/itemviews/itemviews.pri +++ b/src/widgets/itemviews/itemviews.pri @@ -4,6 +4,7 @@ HEADERS += \ itemviews/qabstractitemview.h \ itemviews/qabstractitemview_p.h \ itemviews/qheaderview.h \ + itemviews/qheaderview_p.h \ itemviews/qlistview.h \ itemviews/qlistview_p.h \ itemviews/qbsptree_p.h \ diff --git a/src/widgets/itemviews/qabstractitemdelegate.h b/src/widgets/itemviews/qabstractitemdelegate.h index c25017908765a227e41f0a2c4d6272fa553bf4b7..b29717d1e1e9db75f9c50315ba30922531abac59 100644 --- a/src/widgets/itemviews/qabstractitemdelegate.h +++ b/src/widgets/itemviews/qabstractitemdelegate.h @@ -63,7 +63,7 @@ public: RevertModelCache }; - explicit QAbstractItemDelegate(QObject *parent = 0); + explicit QAbstractItemDelegate(QObject *parent = Q_NULLPTR); virtual ~QAbstractItemDelegate(); // painting @@ -113,7 +113,7 @@ Q_SIGNALS: void sizeHintChanged(const QModelIndex &); protected: - QAbstractItemDelegate(QObjectPrivate &, QObject *parent = 0); + QAbstractItemDelegate(QObjectPrivate &, QObject *parent = Q_NULLPTR); private: Q_DECLARE_PRIVATE(QAbstractItemDelegate) Q_DISABLE_COPY(QAbstractItemDelegate) diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 5b955a6e144923fbba7683ea0d5f65f418a25974..c5601b63b25f7c6e985fb330dd852267009bfb9e 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -2385,7 +2385,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) } #endif break; -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX case Qt::Key_Enter: case Qt::Key_Return: // Propagate the enter if you couldn't edit the item and there are no @@ -2415,7 +2415,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) selectAll(); break; } -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX if (event->key() == Qt::Key_O && event->modifiers() & Qt::ControlModifier && currentIndex().isValid()) { emit activated(currentIndex()); break; @@ -3016,9 +3016,8 @@ int QAbstractItemView::sizeHintForRow(int row) const QStyleOptionViewItem option = d->viewOptionsV1(); int height = 0; int colCount = d->model->columnCount(d->root); - QModelIndex index; for (int c = 0; c < colCount; ++c) { - index = d->model->index(row, c, d->root); + const QModelIndex index = d->model->index(row, c, d->root); if (QWidget *editor = d->editorForIndex(index).widget.data()) height = qMax(height, editor->height()); int hint = d->delegateForIndex(index)->sizeHint(option, index).height(); @@ -3047,9 +3046,8 @@ int QAbstractItemView::sizeHintForColumn(int column) const QStyleOptionViewItem option = d->viewOptionsV1(); int width = 0; int rows = d->model->rowCount(d->root); - QModelIndex index; for (int r = 0; r < rows; ++r) { - index = d->model->index(r, column, d->root); + const QModelIndex index = d->model->index(r, column, d->root); if (QWidget *editor = d->editorForIndex(index).widget.data()) width = qMax(width, editor->sizeHint().width()); int hint = d->delegateForIndex(index)->sizeHint(option, index).width(); diff --git a/src/widgets/itemviews/qabstractitemview.h b/src/widgets/itemviews/qabstractitemview.h index 1be17b6c0e9dcf4409924a375f67db7fce720db3..ff1848b1497b15fe755fb6fbca3b7e0e874b2d33 100644 --- a/src/widgets/itemviews/qabstractitemview.h +++ b/src/widgets/itemviews/qabstractitemview.h @@ -115,7 +115,7 @@ public: }; Q_ENUM(ScrollMode) - explicit QAbstractItemView(QWidget *parent = 0); + explicit QAbstractItemView(QWidget *parent = Q_NULLPTR); ~QAbstractItemView(); virtual void setModel(QAbstractItemModel *model); @@ -258,7 +258,7 @@ Q_SIGNALS: void iconSizeChanged(const QSize &size); protected: - QAbstractItemView(QAbstractItemViewPrivate &, QWidget *parent = 0); + QAbstractItemView(QAbstractItemViewPrivate &, QWidget *parent = Q_NULLPTR); void setHorizontalStepsPerItem(int steps); int horizontalStepsPerItem() const; @@ -283,7 +283,7 @@ protected: virtual bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event); virtual QItemSelectionModel::SelectionFlags selectionCommand(const QModelIndex &index, - const QEvent *event = 0) const; + const QEvent *event = Q_NULLPTR) const; #ifndef QT_NO_DRAGANDDROP virtual void startDrag(Qt::DropActions supportedActions); diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h index 016c50436b3e3fbf805545018524fc05dcff3b41..bb88b25652bbb6d9c130369e0a53d21915ca4458 100644 --- a/src/widgets/itemviews/qabstractitemview_p.h +++ b/src/widgets/itemviews/qabstractitemview_p.h @@ -74,7 +74,7 @@ typedef QHash<QWidget *, QPersistentModelIndex> QEditorIndexHash; typedef QHash<QPersistentModelIndex, QEditorInfo> QIndexEditorHash; typedef QPair<QRect, QModelIndex> QItemViewPaintPair; -typedef QList<QItemViewPaintPair> QItemViewPaintPairs; +typedef QVector<QItemViewPaintPair> QItemViewPaintPairs; class QEmptyModel : public QAbstractItemModel { diff --git a/src/widgets/itemviews/qcolumnview.cpp b/src/widgets/itemviews/qcolumnview.cpp index 0ee03035a416df6aa028f03ea6e498f7c8c03fb4..92bbdf6b697898025de2cb08336c7c449099705e 100644 --- a/src/widgets/itemviews/qcolumnview.cpp +++ b/src/widgets/itemviews/qcolumnview.cpp @@ -861,11 +861,15 @@ void QColumnView::setColumnWidths(const QList<int> &list) { Q_D(QColumnView); int i = 0; - for (; (i < list.count() && i < d->columns.count()); ++i) { + const int listCount = list.count(); + const int count = qMin(listCount, d->columns.count()); + for (; i < count; ++i) { d->columns.at(i)->resize(list.at(i), d->columns.at(i)->height()); d->columnSizes[i] = list.at(i); } - for (; i < list.count(); ++i) + + d->columnSizes.reserve(listCount); + for (; i < listCount; ++i) d->columnSizes.append(list.at(i)); } diff --git a/src/widgets/itemviews/qcolumnview.h b/src/widgets/itemviews/qcolumnview.h index 792ae04eb69cb56ee049eee3a94135fcd02c0c9b..58472ddd8e3e7016ffb15338ed08f5f7be96c2af 100644 --- a/src/widgets/itemviews/qcolumnview.h +++ b/src/widgets/itemviews/qcolumnview.h @@ -52,7 +52,7 @@ Q_SIGNALS: void updatePreviewWidget(const QModelIndex &index); public: - explicit QColumnView(QWidget *parent = 0); + explicit QColumnView(QWidget *parent = Q_NULLPTR); ~QColumnView(); // QAbstractItemView overloads @@ -76,7 +76,7 @@ public: QList<int> columnWidths() const; protected: - QColumnView(QColumnViewPrivate &dd, QWidget *parent = 0); + QColumnView(QColumnViewPrivate &dd, QWidget *parent = Q_NULLPTR); // QAbstractItemView overloads bool isIndexHidden(const QModelIndex &index) const Q_DECL_OVERRIDE; diff --git a/src/widgets/itemviews/qdatawidgetmapper.cpp b/src/widgets/itemviews/qdatawidgetmapper.cpp index c9fdf9967a49393b0b6d10efabcb075b71e5a463..ee7b3613a2ff4c652a7db3f3669dc9e5537e6bd4 100644 --- a/src/widgets/itemviews/qdatawidgetmapper.cpp +++ b/src/widgets/itemviews/qdatawidgetmapper.cpp @@ -756,7 +756,7 @@ void QDataWidgetMapper::clearMapping() QList<QDataWidgetMapperPrivate::WidgetMapper> copy; d->widgetMap.swap(copy); // a C++98 move - for (std::reverse_iterator<QList<QDataWidgetMapperPrivate::WidgetMapper>::const_iterator> it(copy.cend()), end(copy.cbegin()); it != end; ++it) { + for (QList<QDataWidgetMapperPrivate::WidgetMapper>::const_reverse_iterator it = copy.crbegin(), end = copy.crend(); it != end; ++it) { if (it->widget) it->widget->removeEventFilter(d->delegate); } diff --git a/src/widgets/itemviews/qdatawidgetmapper.h b/src/widgets/itemviews/qdatawidgetmapper.h index 5ccbee4d6814257fa181a8ce2d4655d063ad0aa1..4dd5e0e14c9c443c104e3da89a5cc85d3a7b1ecf 100644 --- a/src/widgets/itemviews/qdatawidgetmapper.h +++ b/src/widgets/itemviews/qdatawidgetmapper.h @@ -55,7 +55,7 @@ class Q_WIDGETS_EXPORT QDataWidgetMapper: public QObject Q_PROPERTY(SubmitPolicy submitPolicy READ submitPolicy WRITE setSubmitPolicy) public: - explicit QDataWidgetMapper(QObject *parent = 0); + explicit QDataWidgetMapper(QObject *parent = Q_NULLPTR); ~QDataWidgetMapper(); void setModel(QAbstractItemModel *model); diff --git a/src/widgets/itemviews/qdirmodel.cpp b/src/widgets/itemviews/qdirmodel.cpp index 50406b51f49b5c054a496136f8365ad3a92e888a..0c157c940f5bf39e5e2a72289dc5c6ced28c0523 100644 --- a/src/widgets/itemviews/qdirmodel.cpp +++ b/src/widgets/itemviews/qdirmodel.cpp @@ -66,7 +66,6 @@ public: struct QDirNode { QDirNode() : parent(0), populated(false), stat(false) {} - ~QDirNode() { children.clear(); } QDirNode *parent; QFileInfo info; QIcon icon; // cache the icon diff --git a/src/widgets/itemviews/qdirmodel.h b/src/widgets/itemviews/qdirmodel.h index dcc337244c151b84c0809e2c6dbbc912a18893d9..536e5299a26abfd4460cc00a858d487f2df0b366 100644 --- a/src/widgets/itemviews/qdirmodel.h +++ b/src/widgets/itemviews/qdirmodel.h @@ -60,8 +60,8 @@ public: }; QDirModel(const QStringList &nameFilters, QDir::Filters filters, - QDir::SortFlags sort, QObject *parent = 0); - explicit QDirModel(QObject *parent = 0); + QDir::SortFlags sort, QObject *parent = Q_NULLPTR); + explicit QDirModel(QObject *parent = Q_NULLPTR); ~QDirModel(); QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; @@ -127,7 +127,7 @@ public Q_SLOTS: void refresh(const QModelIndex &parent = QModelIndex()); protected: - QDirModel(QDirModelPrivate &, QObject *parent = 0); + QDirModel(QDirModelPrivate &, QObject *parent = Q_NULLPTR); friend class QFileDialogPrivate; private: diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp index cab32619c530ae35b7fd38d140d9a884d425b237..f43bcd5d5abad2b6aa6fefdf72cfccb404ac9f4f 100644 --- a/src/widgets/itemviews/qfileiconprovider.cpp +++ b/src/widgets/itemviews/qfileiconprovider.cpp @@ -63,8 +63,8 @@ static bool isCacheable(const QFileInfo &fi); class QFileIconEngine : public QPixmapIconEngine { public: - QFileIconEngine(const QFileIconProvider *fip, const QFileInfo &info) - : QPixmapIconEngine(), m_fileIconProvider(fip), m_fileInfo(info) + QFileIconEngine(const QFileInfo &info, QFileIconProvider::Options opts) + : QPixmapIconEngine(), m_fileInfo(info), m_fipOpts(opts) { } QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE @@ -90,7 +90,7 @@ public: } QPlatformTheme::IconOptions iconOptions; - if (m_fileIconProvider->options() & QFileIconProvider::DontUseCustomDirectoryIcons) + if (m_fipOpts & QFileIconProvider::DontUseCustomDirectoryIcons) iconOptions |= QPlatformTheme::DontUseCustomDirectoryIcons; pixmap = theme->fileIconPixmap(m_fileInfo, size, iconOptions); @@ -153,8 +153,8 @@ public: } private: - const QFileIconProvider *m_fileIconProvider; QFileInfo m_fileInfo; + QFileIconProvider::Options m_fipOpts; }; @@ -347,8 +347,7 @@ QIcon QFileIconProviderPrivate::getIcon(const QFileInfo &fi) const if (sizes.isEmpty()) return QIcon(); - Q_Q(const QFileIconProvider); - return QIcon(new QFileIconEngine(q, fi)); + return QIcon(new QFileIconEngine(fi, options)); } /*! @@ -446,7 +445,7 @@ QString QFileIconProvider::type(const QFileInfo &info) const if (info.isSymLink()) #ifdef Q_OS_MAC - return QApplication::translate("QFileDialog", "Alias", "Mac OS X Finder"); + return QApplication::translate("QFileDialog", "Alias", "OS X Finder"); #else return QApplication::translate("QFileDialog", "Shortcut", "All other platforms"); #endif diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index bca315f80b36be319192de807a242dfb2ff5cca0..4cb28d080432900398bc9934d95eabc827d54f9f 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -2450,7 +2450,7 @@ void QHeaderView::mouseMoveEvent(QMouseEvent *e) case QHeaderViewPrivate::SelectSections: { int logical = logicalIndexAt(qMax(-d->offset, pos)); if (logical == -1 && pos > 0) - logical = d->lastVisibleVisualIndex(); + logical = logicalIndex(d->lastVisibleVisualIndex()); if (logical == d->pressed) return; // nothing to do else if (d->pressed != -1) diff --git a/src/widgets/itemviews/qheaderview.h b/src/widgets/itemviews/qheaderview.h index e0f57130c01e59d7e1be013dde9247a17e1e82ab..d892614a39b8a82bbbe5e712d6345a58394fe209 100644 --- a/src/widgets/itemviews/qheaderview.h +++ b/src/widgets/itemviews/qheaderview.h @@ -68,7 +68,7 @@ public: }; Q_ENUM(ResizeMode) - explicit QHeaderView(Qt::Orientation orientation, QWidget *parent = 0); + explicit QHeaderView(Qt::Orientation orientation, QWidget *parent = Q_NULLPTR); virtual ~QHeaderView(); void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE; @@ -202,7 +202,7 @@ protected Q_SLOTS: void sectionsAboutToBeRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast); protected: - QHeaderView(QHeaderViewPrivate &dd, Qt::Orientation orientation, QWidget *parent = 0); + QHeaderView(QHeaderViewPrivate &dd, Qt::Orientation orientation, QWidget *parent = Q_NULLPTR); void initialize(); void initializeSections(); diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h index 621c3c990ebc6aea207801ebd3e746890cdbe004..7f92d2a81b1b1f61f6d41ea0a55a972440c91b19 100644 --- a/src/widgets/itemviews/qheaderview_p.h +++ b/src/widgets/itemviews/qheaderview_p.h @@ -369,6 +369,7 @@ public: #endif }; +Q_DECLARE_TYPEINFO(QHeaderViewPrivate::SectionItem, Q_PRIMITIVE_TYPE); QT_END_NAMESPACE diff --git a/src/widgets/itemviews/qitemdelegate.h b/src/widgets/itemviews/qitemdelegate.h index edc224b0f3582dbc5c6befa8ae1e6e82aaee1cd7..beba6b90fbd16022ed28657bd5345b255ba340db 100644 --- a/src/widgets/itemviews/qitemdelegate.h +++ b/src/widgets/itemviews/qitemdelegate.h @@ -53,7 +53,7 @@ class Q_WIDGETS_EXPORT QItemDelegate : public QAbstractItemDelegate Q_PROPERTY(bool clipping READ hasClipping WRITE setClipping) public: - explicit QItemDelegate(QObject *parent = 0); + explicit QItemDelegate(QObject *parent = Q_NULLPTR); ~QItemDelegate(); bool hasClipping() const; diff --git a/src/widgets/itemviews/qlistview.h b/src/widgets/itemviews/qlistview.h index ac65a47d9f51f0976a3550244cccb705e815e105..433933b5002cea2fec643d79249b429049484ad0 100644 --- a/src/widgets/itemviews/qlistview.h +++ b/src/widgets/itemviews/qlistview.h @@ -72,7 +72,7 @@ public: enum ViewMode { ListMode, IconMode }; Q_ENUM(ViewMode) - explicit QListView(QWidget *parent = 0); + explicit QListView(QWidget *parent = Q_NULLPTR); ~QListView(); void setMovement(Movement movement); @@ -131,7 +131,7 @@ Q_SIGNALS: void indexesMoved(const QModelIndexList &indexes); protected: - QListView(QListViewPrivate &, QWidget *parent = 0); + QListView(QListViewPrivate &, QWidget *parent = Q_NULLPTR); bool event(QEvent *e) Q_DECL_OVERRIDE; diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h index fe059d73dd395c6384219c204bc1643c2481b238..c1b5b8772c8564ae1d959e6c160165145a88131a 100644 --- a/src/widgets/itemviews/qlistview_p.h +++ b/src/widgets/itemviews/qlistview_p.h @@ -93,6 +93,7 @@ private: mutable int indexHint; uint visited; }; +Q_DECLARE_TYPEINFO(QListViewItem, Q_PRIMITIVE_TYPE); struct QListViewLayoutInfo { @@ -105,6 +106,7 @@ struct QListViewLayoutInfo QListView::Flow flow; int max; }; +Q_DECLARE_TYPEINFO(QListViewLayoutInfo, Q_PRIMITIVE_TYPE); class QListView; class QListViewPrivate; diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp index 668bfda59d6cd970298db79ccf8981de1b8c3c53..0e1e56e966a417226204f34bb008045d4049952f 100644 --- a/src/widgets/itemviews/qlistwidget.cpp +++ b/src/widgets/itemviews/qlistwidget.cpp @@ -1699,7 +1699,9 @@ QList<QListWidgetItem*> QListWidget::selectedItems() const Q_D(const QListWidget); QModelIndexList indexes = selectionModel()->selectedIndexes(); QList<QListWidgetItem*> items; - for (int i = 0; i < indexes.count(); ++i) + const int numIndexes = indexes.count(); + items.reserve(numIndexes); + for (int i = 0; i < numIndexes; ++i) items.append(d->listModel()->at(indexes.at(i).row())); return items; } diff --git a/src/widgets/itemviews/qlistwidget.h b/src/widgets/itemviews/qlistwidget.h index 8ab864c930efe2763551f0e9113b301208125d2c..1fbdc472dbe3a5e915f728eae28745298d7e954d 100644 --- a/src/widgets/itemviews/qlistwidget.h +++ b/src/widgets/itemviews/qlistwidget.h @@ -55,10 +55,10 @@ class Q_WIDGETS_EXPORT QListWidgetItem friend class QListWidget; public: enum ItemType { Type = 0, UserType = 1000 }; - explicit QListWidgetItem(QListWidget *view = 0, int type = Type); - explicit QListWidgetItem(const QString &text, QListWidget *view = 0, int type = Type); + explicit QListWidgetItem(QListWidget *view = Q_NULLPTR, int type = Type); + explicit QListWidgetItem(const QString &text, QListWidget *view = Q_NULLPTR, int type = Type); explicit QListWidgetItem(const QIcon &icon, const QString &text, - QListWidget *view = 0, int type = Type); + QListWidget *view = Q_NULLPTR, int type = Type); QListWidgetItem(const QListWidgetItem &other); virtual ~QListWidgetItem(); @@ -198,7 +198,7 @@ class Q_WIDGETS_EXPORT QListWidget : public QListView friend class QListWidgetItem; friend class QListModel; public: - explicit QListWidget(QWidget *parent = 0); + explicit QListWidget(QWidget *parent = Q_NULLPTR); ~QListWidget(); QListWidgetItem *item(int row) const; @@ -299,7 +299,7 @@ private: }; inline void QListWidget::removeItemWidget(QListWidgetItem *aItem) -{ setItemWidget(aItem, 0); } +{ setItemWidget(aItem, Q_NULLPTR); } inline void QListWidget::addItem(QListWidgetItem *aitem) { insertItem(count(), aitem); } diff --git a/src/widgets/itemviews/qstyleditemdelegate.h b/src/widgets/itemviews/qstyleditemdelegate.h index 590ddf6614f63b57099cdc7f6f5030ba2f828bbc..541830239a814f29f97656d56a04061b140888a1 100644 --- a/src/widgets/itemviews/qstyleditemdelegate.h +++ b/src/widgets/itemviews/qstyleditemdelegate.h @@ -52,7 +52,7 @@ class Q_WIDGETS_EXPORT QStyledItemDelegate : public QAbstractItemDelegate Q_OBJECT public: - explicit QStyledItemDelegate(QObject *parent = 0); + explicit QStyledItemDelegate(QObject *parent = Q_NULLPTR); ~QStyledItemDelegate(); // painting diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index ae31387faf6eab267bfbc3252099651280a9720e..3e3e3099c89b5e2250fc7e2b9c1dd139dafedf2a 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -1884,6 +1884,7 @@ void QTableView::setSelection(const QRect &rect, QItemSelectionModel::SelectionF break; } } while (expanded); + selection.reserve((right - left + 1) * (bottom - top + 1)); for (int horizontal = left; horizontal <= right; ++horizontal) { int column = d->logicalColumn(horizontal); for (int vertical = top; vertical <= bottom; ++vertical) { @@ -1897,6 +1898,7 @@ void QTableView::setSelection(const QRect &rect, QItemSelectionModel::SelectionF int left = d->visualColumn(tl.column()); int bottom = d->visualRow(br.row()); int right = d->visualColumn(br.column()); + selection.reserve((right - left + 1) * (bottom - top + 1)); for (int horizontal = left; horizontal <= right; ++horizontal) { int column = d->logicalColumn(horizontal); for (int vertical = top; vertical <= bottom; ++vertical) { @@ -1908,6 +1910,7 @@ void QTableView::setSelection(const QRect &rect, QItemSelectionModel::SelectionF } else if (horizontalMoved) { int left = d->visualColumn(tl.column()); int right = d->visualColumn(br.column()); + selection.reserve(right - left + 1); for (int visual = left; visual <= right; ++visual) { int column = d->logicalColumn(visual); QModelIndex topLeft = d->model->index(tl.row(), column, d->root); @@ -1917,6 +1920,7 @@ void QTableView::setSelection(const QRect &rect, QItemSelectionModel::SelectionF } else if (verticalMoved) { int top = d->visualRow(tl.row()); int bottom = d->visualRow(br.row()); + selection.reserve(bottom - top + 1); for (int visual = top; visual <= bottom; ++visual) { int row = d->logicalRow(visual); QModelIndex topLeft = d->model->index(row, tl.column(), d->root); @@ -2540,7 +2544,7 @@ void QTableView::setColumnHidden(int column, bool hide) */ /*! - If \a enabled true enables sorting for the table and immediately + If \a enable is true, enables sorting for the table and immediately trigger a call to sortByColumn() with the current sort section and order */ diff --git a/src/widgets/itemviews/qtableview.h b/src/widgets/itemviews/qtableview.h index d69b78c6fe770311709f25ae0143ec1b833b83fd..1bb23844ccea208a8dc2f1b476d716e70e58a84d 100644 --- a/src/widgets/itemviews/qtableview.h +++ b/src/widgets/itemviews/qtableview.h @@ -54,7 +54,7 @@ class Q_WIDGETS_EXPORT QTableView : public QAbstractItemView Q_PROPERTY(bool cornerButtonEnabled READ isCornerButtonEnabled WRITE setCornerButtonEnabled) public: - explicit QTableView(QWidget *parent = 0); + explicit QTableView(QWidget *parent = Q_NULLPTR); ~QTableView(); void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE; diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp index b2d4abe5ac6bbd0054dbbb215deecf2cd6d560bc..f0c7ac0d327ed7406623fb30cfcdeffd1ec87621 100644 --- a/src/widgets/itemviews/qtablewidget.cpp +++ b/src/widgets/itemviews/qtablewidget.cpp @@ -507,11 +507,15 @@ void QTableModel::sort(int column, Qt::SortOrder order) QVector<QTableWidgetItem*> sorted_table(tableItems.count()); QModelIndexList from; QModelIndexList to; - for (int i = 0; i < rowCount(); ++i) { + const int numRows = rowCount(); + const int numColumns = columnCount(); + from.reserve(numRows * numColumns); + to.reserve(numRows * numColumns); + for (int i = 0; i < numRows; ++i) { int r = (i < sortable.count() ? sortable.at(i).second : unsortable.at(i - sortable.count())); - for (int c = 0; c < columnCount(); ++c) { + for (int c = 0; c < numColumns; ++c) { sorted_table[tableIndex(i, c)] = item(r, c); from.append(createIndex(r, c)); to.append(createIndex(i, c)); diff --git a/src/widgets/itemviews/qtablewidget.h b/src/widgets/itemviews/qtablewidget.h index 93639f0753beeddfb1684fc6df4fc7e4830d9e35..9acdc1986397a2bd71f0067b555773e69e328640 100644 --- a/src/widgets/itemviews/qtablewidget.h +++ b/src/widgets/itemviews/qtablewidget.h @@ -214,8 +214,8 @@ class Q_WIDGETS_EXPORT QTableWidget : public QTableView friend class QTableModel; public: - explicit QTableWidget(QWidget *parent = 0); - QTableWidget(int rows, int columns, QWidget *parent = 0); + explicit QTableWidget(QWidget *parent = Q_NULLPTR); + QTableWidget(int rows, int columns, QWidget *parent = Q_NULLPTR); ~QTableWidget(); void setRowCount(int rows); @@ -344,7 +344,7 @@ private: }; inline void QTableWidget::removeCellWidget(int arow, int acolumn) -{ setCellWidget(arow, acolumn, 0); } +{ setCellWidget(arow, acolumn, Q_NULLPTR); } inline QTableWidgetItem *QTableWidget::itemAt(int ax, int ay) const { return itemAt(QPoint(ax, ay)); } diff --git a/src/widgets/itemviews/qtreeview.h b/src/widgets/itemviews/qtreeview.h index e9e2e78e17ba32438a137d51650d3fadacc6a26b..546cc488cb8d58c78918d3b765455df2f80a038b 100644 --- a/src/widgets/itemviews/qtreeview.h +++ b/src/widgets/itemviews/qtreeview.h @@ -60,7 +60,7 @@ class Q_WIDGETS_EXPORT QTreeView : public QAbstractItemView Q_PROPERTY(bool expandsOnDoubleClick READ expandsOnDoubleClick WRITE setExpandsOnDoubleClick) public: - explicit QTreeView(QWidget *parent = 0); + explicit QTreeView(QWidget *parent = Q_NULLPTR); ~QTreeView(); void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE; @@ -163,7 +163,7 @@ protected Q_SLOTS: void rowsRemoved(const QModelIndex &parent, int first, int last); protected: - QTreeView(QTreeViewPrivate &dd, QWidget *parent = 0); + QTreeView(QTreeViewPrivate &dd, QWidget *parent = Q_NULLPTR); void scrollContentsBy(int dx, int dy) Q_DECL_OVERRIDE; void rowsInserted(const QModelIndex &parent, int start, int end) Q_DECL_OVERRIDE; void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) Q_DECL_OVERRIDE; diff --git a/src/widgets/itemviews/qtreewidget.h b/src/widgets/itemviews/qtreewidget.h index 564e10ac1a39d0fb50c1cfed8f6cd9d2981e488f..995528fe375facb24f7e049495cc63729f12546f 100644 --- a/src/widgets/itemviews/qtreewidget.h +++ b/src/widgets/itemviews/qtreewidget.h @@ -172,7 +172,7 @@ public: inline QTreeWidgetItem *parent() const { return par; } inline QTreeWidgetItem *child(int index) const { if (index < 0 || index >= children.size()) - return 0; + return Q_NULLPTR; executePendingSort(); return children.at(index); } @@ -255,7 +255,7 @@ class Q_WIDGETS_EXPORT QTreeWidget : public QTreeView friend class QTreeModel; friend class QTreeWidgetItem; public: - explicit QTreeWidget(QWidget *parent = 0); + explicit QTreeWidget(QWidget *parent = Q_NULLPTR); ~QTreeWidget(); int columnCount() const; @@ -375,7 +375,7 @@ private: }; inline void QTreeWidget::removeItemWidget(QTreeWidgetItem *item, int column) -{ setItemWidget(item, column, 0); } +{ setItemWidget(item, column, Q_NULLPTR); } inline QTreeWidgetItem *QTreeWidget::itemAt(int ax, int ay) const { return itemAt(QPoint(ax, ay)); } diff --git a/src/widgets/itemviews/qwidgetitemdata_p.h b/src/widgets/itemviews/qwidgetitemdata_p.h index 307d228c749fe632a70b6da56f3f4a4bc2a1a7bb..d8c1fc2ff7f7ad02b33a490b7195aa4252b74b37 100644 --- a/src/widgets/itemviews/qwidgetitemdata_p.h +++ b/src/widgets/itemviews/qwidgetitemdata_p.h @@ -58,6 +58,7 @@ public: QVariant value; inline bool operator==(const QWidgetItemData &other) const { return role == other.role && value == other.value; } }; +Q_DECLARE_TYPEINFO(QWidgetItemData, Q_MOVABLE_TYPE); #ifndef QT_NO_DATASTREAM diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri index 16de5fd6c6fdc6d47482e9ed8ff45db02c40f704..c097da2303379ba6ebffc29b4ce7e9821e15216c 100644 --- a/src/widgets/kernel/kernel.pri +++ b/src/widgets/kernel/kernel.pri @@ -71,7 +71,7 @@ macx: { SOURCES += kernel/qmacgesturerecognizer.cpp } -wince*: { +wince { HEADERS += \ ../corelib/kernel/qfunctions_wince.h \ kernel/qwidgetsfunctions_wince.h diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp index 9fbcf28aadcade36888de3f52744a0baf76b3923..255ffbd258e954f49612acd112874a5ddb3815f3 100644 --- a/src/widgets/kernel/qaction.cpp +++ b/src/widgets/kernel/qaction.cpp @@ -228,8 +228,9 @@ void QActionPrivate::setShortcutEnabled(bool enable, QShortcutMap &map) \snippet mainwindows/application/mainwindow.cpp 19 \codeline - \snippet mainwindows/application/mainwindow.cpp 28 - \snippet mainwindows/application/mainwindow.cpp 31 + \code + fileMenu->addAction(openAct); + \endcode We recommend that actions are created as children of the window they are used in. In most cases actions will be children of diff --git a/src/widgets/kernel/qaction.h b/src/widgets/kernel/qaction.h index 1d696946998255b6eb67d7c5fa1c8947d3a3e41c..8ef26b60bf1c2af11a793e92737f35d45186ea59 100644 --- a/src/widgets/kernel/qaction.h +++ b/src/widgets/kernel/qaction.h @@ -153,7 +153,7 @@ public: enum ActionEvent { Trigger, Hover }; void activate(ActionEvent event); - bool showStatusText(QWidget *widget=0); + bool showStatusText(QWidget *widget = Q_NULLPTR); void setMenuRole(MenuRole menuRole); MenuRole menuRole() const; diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index f457993168c620986b1328b06ab335a75262b78c..f82fac836a0e57b14f5e42119f4794230611dd67 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1530,7 +1530,7 @@ void QApplicationPrivate::setPalette_helper(const QPalette &palette, const char* \note Some styles do not use the palette for all drawing, for instance, if they make use of native theme engines. This is the case for the Windows XP, - Windows Vista, and Mac OS X styles. + Windows Vista, and OS X styles. \sa QWidget::setPalette(), palette(), QStyle::polish() */ @@ -3229,7 +3229,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, e, relpos); // ### Qt 5 These dynamic tool tips should be an OPT-IN feature. Some platforms - // like Mac OS X (probably others too), can optimize their views by not + // like OS X (probably others too), can optimize their views by not // dispatching mouse move events. We have attributes to control hover, // and mouse tracking, but as long as we are deciding to implement this // feature without choice of opting-in or out, you ALWAYS have to have @@ -3688,7 +3688,9 @@ bool QApplication::notify(QObject *receiver, QEvent *e) bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e) { // send to all application event filters - if (sendThroughApplicationEventFilters(receiver, e)) + if (threadRequiresCoreApplication() + && receiver->d_func()->threadData->thread == mainThread() + && sendThroughApplicationEventFilters(receiver, e)) return true; if (receiver->isWidgetType()) { @@ -3933,7 +3935,7 @@ bool QApplication::keypadNavigationEnabled() Currently this function does nothing on Qt for Embedded Linux. - On Mac OS X, this works more at the application level and will cause the + On OS X, this works more at the application level and will cause the application icon to bounce in the dock. On Windows, this causes the window's taskbar entry to flash for a time. If diff --git a/src/widgets/kernel/qapplication.h b/src/widgets/kernel/qapplication.h index d4b2326afd84b630be9fbba7169ca9cb913c5d08..7aaea2a947204a218358318c0495d5486ec2aa70 100644 --- a/src/widgets/kernel/qapplication.h +++ b/src/widgets/kernel/qapplication.h @@ -104,11 +104,11 @@ public: using QGuiApplication::palette; static QPalette palette(const QWidget *); static QPalette palette(const char *className); - static void setPalette(const QPalette &, const char* className = 0); + static void setPalette(const QPalette &, const char* className = Q_NULLPTR); static QFont font(); static QFont font(const QWidget*); static QFont font(const char *className); - static void setFont(const QFont &, const char* className = 0); + static void setFont(const QFont &, const char* className = Q_NULLPTR); static QFontMetrics fontMetrics(); #if QT_VERSION < 0x060000 // remove these forwarders in Qt 6 diff --git a/src/widgets/kernel/qboxlayout.h b/src/widgets/kernel/qboxlayout.h index 5ce9ca26f6eceed75f89c7e7ffe8d7862a461895..10209e05c9ac975dfa635b104f42eb57a8fe33a2 100644 --- a/src/widgets/kernel/qboxlayout.h +++ b/src/widgets/kernel/qboxlayout.h @@ -54,7 +54,7 @@ public: enum Direction { LeftToRight, RightToLeft, TopToBottom, BottomToTop, Down = TopToBottom, Up = BottomToTop }; - explicit QBoxLayout(Direction, QWidget *parent = 0); + explicit QBoxLayout(Direction, QWidget *parent = Q_NULLPTR); ~QBoxLayout(); @@ -64,7 +64,7 @@ public: void addSpacing(int size); void addStretch(int stretch = 0); void addSpacerItem(QSpacerItem *spacerItem); - void addWidget(QWidget *, int stretch = 0, Qt::Alignment alignment = 0); + void addWidget(QWidget *, int stretch = 0, Qt::Alignment alignment = Qt::Alignment()); void addLayout(QLayout *layout, int stretch = 0); void addStrut(int); void addItem(QLayoutItem *) Q_DECL_OVERRIDE; @@ -72,7 +72,7 @@ public: void insertSpacing(int index, int size); void insertStretch(int index, int stretch = 0); void insertSpacerItem(int index, QSpacerItem *spacerItem); - void insertWidget(int index, QWidget *widget, int stretch = 0, Qt::Alignment alignment = 0); + void insertWidget(int index, QWidget *widget, int stretch = 0, Qt::Alignment alignment = Qt::Alignment()); void insertLayout(int index, QLayout *layout, int stretch = 0); void insertItem(int index, QLayoutItem *); diff --git a/src/widgets/kernel/qdesktopwidget.h b/src/widgets/kernel/qdesktopwidget.h index 5412c5bc4ada0aaaa68a7b8fd7872b71b81935d7..c0cc4f1b81f651e2b035cbfdcfc905cfa3c5ef45 100644 --- a/src/widgets/kernel/qdesktopwidget.h +++ b/src/widgets/kernel/qdesktopwidget.h @@ -58,7 +58,7 @@ public: int screenCount() const; int primaryScreen() const; - int screenNumber(const QWidget *widget = 0) const; + int screenNumber(const QWidget *widget = Q_NULLPTR) const; int screenNumber(const QPoint &) const; QWidget *screen(int screen = -1); diff --git a/src/widgets/kernel/qdesktopwidget.qdoc b/src/widgets/kernel/qdesktopwidget.qdoc index 6ce312dc2f1062aaac94cc74d0f06f1d370d9bdc..31a99f1acb54c3f48a799c8ca6d14ad330d44229 100644 --- a/src/widgets/kernel/qdesktopwidget.qdoc +++ b/src/widgets/kernel/qdesktopwidget.qdoc @@ -149,7 +149,7 @@ Returns the available geometry of the screen with index \a screen. What is available will be subrect of screenGeometry() based on what the platform decides is available (for example excludes the dock and menu bar - on Mac OS X, or the task bar on Windows). The default screen is used if + on OS X, or the task bar on Windows). The default screen is used if \a screen is -1. \sa screenNumber(), screenGeometry() diff --git a/src/widgets/kernel/qformlayout.h b/src/widgets/kernel/qformlayout.h index 18f3c843543745f47c9e98405c623532101a191f..0767d78ce6a463fced3bfd97a762008763104216 100644 --- a/src/widgets/kernel/qformlayout.h +++ b/src/widgets/kernel/qformlayout.h @@ -74,7 +74,7 @@ public: }; Q_ENUM(ItemRole) - explicit QFormLayout(QWidget *parent = 0); + explicit QFormLayout(QWidget *parent = Q_NULLPTR); ~QFormLayout(); void setFieldGrowthPolicy(FieldGrowthPolicy policy); diff --git a/src/widgets/kernel/qgesture.h b/src/widgets/kernel/qgesture.h index dfe94503650fdb510f88cd7b43d5259793840774..bcf583a507596b3c95143e1ed527abf99770c205 100644 --- a/src/widgets/kernel/qgesture.h +++ b/src/widgets/kernel/qgesture.h @@ -63,7 +63,7 @@ class Q_WIDGETS_EXPORT QGesture : public QObject Q_PROPERTY(bool hasHotSpot READ hasHotSpot) public: - explicit QGesture(QObject *parent = 0); + explicit QGesture(QObject *parent = Q_NULLPTR); ~QGesture(); Qt::GestureType gestureType() const; @@ -107,7 +107,7 @@ class Q_WIDGETS_EXPORT QPanGesture : public QGesture Q_PRIVATE_PROPERTY(QPanGesture::d_func(), qreal verticalVelocity READ verticalVelocity WRITE setVerticalVelocity) public: - explicit QPanGesture(QObject *parent = 0); + explicit QPanGesture(QObject *parent = Q_NULLPTR); ~QPanGesture(); QPointF lastOffset() const; @@ -154,7 +154,7 @@ public: Q_PROPERTY(QPointF centerPoint READ centerPoint WRITE setCenterPoint) public: - explicit QPinchGesture(QObject *parent = 0); + explicit QPinchGesture(QObject *parent = Q_NULLPTR); ~QPinchGesture(); ChangeFlags totalChangeFlags() const; @@ -210,7 +210,7 @@ public: enum SwipeDirection { NoDirection, Left, Right, Up, Down }; Q_ENUM(SwipeDirection) - explicit QSwipeGesture(QObject *parent = 0); + explicit QSwipeGesture(QObject *parent = Q_NULLPTR); ~QSwipeGesture(); SwipeDirection horizontalDirection() const; @@ -231,7 +231,7 @@ class Q_WIDGETS_EXPORT QTapGesture : public QGesture Q_PROPERTY(QPointF position READ position WRITE setPosition) public: - explicit QTapGesture(QObject *parent = 0); + explicit QTapGesture(QObject *parent = Q_NULLPTR); ~QTapGesture(); QPointF position() const; @@ -249,7 +249,7 @@ class Q_WIDGETS_EXPORT QTapAndHoldGesture : public QGesture Q_PROPERTY(QPointF position READ position WRITE setPosition) public: - explicit QTapAndHoldGesture(QObject *parent = 0); + explicit QTapAndHoldGesture(QObject *parent = Q_NULLPTR); ~QTapAndHoldGesture(); QPointF position() const; diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index b5d3a56d3f4cb738c32401c496029cfcd83da189..8cb7c2b560b8045c2ad3d2873df3dc3c14f227b2 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -569,18 +569,19 @@ void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures, } // for each gesture type - foreach (Qt::GestureType type, gestureByTypes.keys()) { - QHash<QWidget *, QGesture *> gestures = gestureByTypes.value(type); - foreach (QWidget *widget, gestures.keys()) { + for (GestureByTypes::const_iterator git = gestureByTypes.cbegin(), gend = gestureByTypes.cend(); git != gend; ++git) { + const QHash<QWidget *, QGesture *> &gestures = git.value(); + for (QHash<QWidget *, QGesture *>::const_iterator wit = gestures.cbegin(), wend = gestures.cend(); wit != wend; ++wit) { + QWidget *widget = wit.key(); QWidget *w = widget->parentWidget(); while (w) { QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator it - = w->d_func()->gestureContext.constFind(type); + = w->d_func()->gestureContext.constFind(git.key()); if (it != w->d_func()->gestureContext.constEnd()) { // i.e. 'w' listens to gesture 'type' if (!(it.value() & Qt::DontStartGestureOnChildren) && w != widget) { // conflicting gesture! - (*conflicts)[widget].append(gestures[widget]); + (*conflicts)[widget].append(wit.value()); break; } } @@ -591,7 +592,7 @@ void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures, w = w->parentWidget(); } if (!w) - (*normal)[widget].append(gestures[widget]); + (*normal)[widget].append(wit.value()); } } } diff --git a/src/widgets/kernel/qgridlayout.h b/src/widgets/kernel/qgridlayout.h index a582d3163437fc483a85a584aa582b51e8e3cddc..ae3fe125b6c8e9b871d05cc792de14c4c6e9309b 100644 --- a/src/widgets/kernel/qgridlayout.h +++ b/src/widgets/kernel/qgridlayout.h @@ -93,10 +93,10 @@ public: void invalidate() Q_DECL_OVERRIDE; inline void addWidget(QWidget *w) { QLayout::addWidget(w); } - void addWidget(QWidget *, int row, int column, Qt::Alignment = 0); - void addWidget(QWidget *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = 0); - void addLayout(QLayout *, int row, int column, Qt::Alignment = 0); - void addLayout(QLayout *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = 0); + void addWidget(QWidget *, int row, int column, Qt::Alignment = Qt::Alignment()); + void addWidget(QWidget *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = Qt::Alignment()); + void addLayout(QLayout *, int row, int column, Qt::Alignment = Qt::Alignment()); + void addLayout(QLayout *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = Qt::Alignment()); void setOriginCorner(Qt::Corner); Qt::Corner originCorner() const; @@ -107,7 +107,7 @@ public: int count() const Q_DECL_OVERRIDE; void setGeometry(const QRect&) Q_DECL_OVERRIDE; - void addItem(QLayoutItem *item, int row, int column, int rowSpan = 1, int columnSpan = 1, Qt::Alignment = 0); + void addItem(QLayoutItem *item, int row, int column, int rowSpan = 1, int columnSpan = 1, Qt::Alignment = Qt::Alignment()); void setDefaultPositioning(int n, Qt::Orientation orient); void getItemPosition(int idx, int *row, int *column, int *rowSpan, int *columnSpan) const; diff --git a/src/widgets/kernel/qlayoutitem.cpp b/src/widgets/kernel/qlayoutitem.cpp index 21f4c9a221f4cea1136b0b2c66f01585bc08a000..3d444136e370b11490ac3e45c70f7163828846ec 100644 --- a/src/widgets/kernel/qlayoutitem.cpp +++ b/src/widgets/kernel/qlayoutitem.cpp @@ -332,14 +332,11 @@ QSpacerItem * QSpacerItem::spacerItem() } /*! + \fn QSizePolicy QSpacerItem::sizePolicy() const \since 5.5 Returns the size policy of this item. */ -QSizePolicy QSpacerItem::sizePolicy() const -{ - return sizeP; -} /*! If this item is a QWidget, it is returned as a QWidget; otherwise diff --git a/src/widgets/kernel/qlayoutitem.h b/src/widgets/kernel/qlayoutitem.h index eaa129a85b0aea10371b9be322bca62fba424ccb..cdb612728f70ff9d2c22606018b1de1c30a1f4ef 100644 --- a/src/widgets/kernel/qlayoutitem.h +++ b/src/widgets/kernel/qlayoutitem.h @@ -53,7 +53,7 @@ class QSize; class Q_WIDGETS_EXPORT QLayoutItem { public: - inline explicit QLayoutItem(Qt::Alignment alignment = 0); + inline explicit QLayoutItem(Qt::Alignment alignment = Qt::Alignment()); virtual ~QLayoutItem(); virtual QSize sizeHint() const = 0; virtual QSize minimumSize() const = 0; @@ -102,7 +102,7 @@ public: void setGeometry(const QRect&); QRect geometry() const; QSpacerItem *spacerItem(); - QSizePolicy sizePolicy() const; + QSizePolicy sizePolicy() const { return sizeP; } private: int width; diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 9bfdc62e6012e46cb31e955e982df407e6d18b51..ea7a761bf14c0e16a04328c27b4b7c7b31d83e9a 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -639,7 +639,7 @@ GLuint QOpenGLWidgetPrivate::textureId() const Q_Q(const QOpenGLWidget); if (!q->isWindow() && q->internalWinId()) { qWarning() << "QOpenGLWidget cannot be used as a native child widget." - << "Consider setting Qt::AA_DontCreateNativeWidgetAncestors and Siblings."; + << "Consider setting Qt::WA_DontCreateNativeAncestors and Qt::AA_DontCreateNativeWidgetSiblings."; return 0; } return resolvedFbo ? resolvedFbo->texture() : (fbo ? fbo->texture() : 0); @@ -695,7 +695,7 @@ void QOpenGLWidgetPrivate::recreateFbo() format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); format.setSamples(samples); - const QSize deviceSize = q->size() * q->devicePixelRatio(); + const QSize deviceSize = q->size() * q->devicePixelRatioF(); fbo = new QOpenGLFramebufferObject(deviceSize, format); if (samples > 0) resolvedFbo = new QOpenGLFramebufferObject(deviceSize); @@ -704,7 +704,7 @@ void QOpenGLWidgetPrivate::recreateFbo() context->functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); paintDevice->setSize(deviceSize); - paintDevice->setDevicePixelRatio(q->devicePixelRatio()); + paintDevice->setDevicePixelRatio(q->devicePixelRatioF()); emit q->resized(); } @@ -778,8 +778,8 @@ void QOpenGLWidgetPrivate::initialize() } paintDevice = new QOpenGLWidgetPaintDevice(q); - paintDevice->setSize(q->size() * q->devicePixelRatio()); - paintDevice->setDevicePixelRatio(q->devicePixelRatio()); + paintDevice->setSize(q->size() * q->devicePixelRatioF()); + paintDevice->setDevicePixelRatio(q->devicePixelRatioF()); context = ctx.take(); initialized = true; @@ -808,7 +808,7 @@ void QOpenGLWidgetPrivate::invokeUserPaint() QOpenGLFunctions *f = ctx->functions(); QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = fbo->handle(); - f->glViewport(0, 0, q->width() * q->devicePixelRatio(), q->height() * q->devicePixelRatio()); + f->glViewport(0, 0, q->width() * q->devicePixelRatioF(), q->height() * q->devicePixelRatioF()); q->paintGL(); flushPending = true; @@ -859,8 +859,8 @@ QImage QOpenGLWidgetPrivate::grabFramebuffer() render(); resolveSamples(); q->makeCurrent(); - QImage res = qt_gl_read_framebuffer(q->size() * q->devicePixelRatio(), false, false); - res.setDevicePixelRatio(q->devicePixelRatio()); + QImage res = qt_gl_read_framebuffer(q->size() * q->devicePixelRatioF(), false, false); + res.setDevicePixelRatio(q->devicePixelRatioF()); return res; } @@ -879,7 +879,7 @@ void QOpenGLWidgetPrivate::resizeViewportFramebuffer() if (!initialized) return; - if (!fbo || q->size() * q->devicePixelRatio() != fbo->size()) + if (!fbo || q->size() * q->devicePixelRatioF() != fbo->size()) recreateFbo(); } @@ -1196,6 +1196,7 @@ int QOpenGLWidget::metric(QPaintDevice::PaintDeviceMetric metric) const return QWidget::metric(metric); QWidget *tlw = window(); + QWindow *window = tlw ? tlw->windowHandle() : 0; QScreen *screen = tlw && tlw->windowHandle() ? tlw->windowHandle()->screen() : 0; if (!screen && QGuiApplication::primaryScreen()) screen = QGuiApplication::primaryScreen(); @@ -1243,8 +1244,13 @@ int QOpenGLWidget::metric(QPaintDevice::PaintDeviceMetric metric) const else return qRound(dpmy * 0.0254); case PdmDevicePixelRatio: - if (screen) - return screen->devicePixelRatio(); + if (window) + return int(window->devicePixelRatio()); + else + return 1.0; + case PdmDevicePixelRatioScaled: + if (window) + return int(window->devicePixelRatio() * devicePixelRatioFScale()); else return 1.0; default: @@ -1304,7 +1310,7 @@ bool QOpenGLWidget::event(QEvent *e) } break; case QEvent::ScreenChangeInternal: - if (d->initialized && d->paintDevice->devicePixelRatio() != devicePixelRatio()) + if (d->initialized && d->paintDevice->devicePixelRatioF() != devicePixelRatioF()) d->recreateFbo(); break; default: diff --git a/src/widgets/kernel/qopenglwidget.h b/src/widgets/kernel/qopenglwidget.h index 4a9edb818019c29faa865e475d54f8d3d80bb5fb..ca65d75ca817320ab416d061f6010c816a0c2310 100644 --- a/src/widgets/kernel/qopenglwidget.h +++ b/src/widgets/kernel/qopenglwidget.h @@ -57,7 +57,7 @@ public: PartialUpdate }; - explicit QOpenGLWidget(QWidget* parent = 0, Qt::WindowFlags f = 0); + explicit QOpenGLWidget(QWidget* parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); ~QOpenGLWidget(); void setUpdateBehavior(UpdateBehavior updateBehavior); diff --git a/src/widgets/kernel/qshortcut.h b/src/widgets/kernel/qshortcut.h index 9171f855bad226e5afac3837cd1a862c8e3b5d1e..e816bbe06d6750a5a961fd387610270a777740e4 100644 --- a/src/widgets/kernel/qshortcut.h +++ b/src/widgets/kernel/qshortcut.h @@ -55,7 +55,7 @@ class Q_WIDGETS_EXPORT QShortcut : public QObject public: explicit QShortcut(QWidget *parent); QShortcut(const QKeySequence& key, QWidget *parent, - const char *member = 0, const char *ambiguousMember = 0, + const char *member = Q_NULLPTR, const char *ambiguousMember = Q_NULLPTR, Qt::ShortcutContext context = Qt::WindowShortcut); ~QShortcut(); diff --git a/src/widgets/kernel/qsizepolicy.cpp b/src/widgets/kernel/qsizepolicy.cpp index 1476b4c5d78e7a6ce83a178fedb71ac5cdd3c986..3c28f5ccf73b4c9027185fd36a36f4b7ab68d516 100644 --- a/src/widgets/kernel/qsizepolicy.cpp +++ b/src/widgets/kernel/qsizepolicy.cpp @@ -331,6 +331,15 @@ void QSizePolicy::setControlType(ControlType type) \sa operator==() */ +/*! + \fn uint qHash(QSizePolicy key, uint seed = 0) + \since 5.6 + \relates QSizePolicy + + Returns the hash value for \a key, using + \a seed to seed the calculation. +*/ + /*! \fn int QSizePolicy::horizontalStretch() const diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h index 6cd511f5132fc0e3c5e5a3d71adfa3814240ba12..7c9a356973cb03e3a9c196c636efb94d1de57a4f 100644 --- a/src/widgets/kernel/qsizepolicy.h +++ b/src/widgets/kernel/qsizepolicy.h @@ -40,6 +40,9 @@ QT_BEGIN_NAMESPACE class QVariant; +class QSizePolicy; + +Q_DECL_CONST_FUNCTION inline uint qHash(QSizePolicy key, uint seed = 0) Q_DECL_NOTHROW; class Q_WIDGETS_EXPORT QSizePolicy { @@ -112,6 +115,9 @@ public: bool operator==(const QSizePolicy& s) const { return data == s.data; } bool operator!=(const QSizePolicy& s) const { return data != s.data; } + + friend Q_DECL_CONST_FUNCTION uint qHash(QSizePolicy key, uint seed) Q_DECL_NOTHROW { return qHash(key.data, seed); } + operator QVariant() const; int horizontalStretch() const { return static_cast<int>(bits.horStretch); } diff --git a/src/widgets/kernel/qstandardgestures.cpp b/src/widgets/kernel/qstandardgestures.cpp index d19e473d18e94c2de062754a4bfd17d36ffdc696..d7589cc594aff116e3b25f93f5c88c3c882629ca 100644 --- a/src/widgets/kernel/qstandardgestures.cpp +++ b/src/widgets/kernel/qstandardgestures.cpp @@ -53,7 +53,7 @@ QGesture *QPanGestureRecognizer::create(QObject *target) { if (target && target->isWidgetType()) { #if (defined(Q_OS_MACX) || defined(Q_OS_WIN)) && !defined(QT_NO_NATIVE_GESTURES) - // for scroll areas on Windows and Mac OS X we want to use native gestures instead + // for scroll areas on Windows and OS X we want to use native gestures instead if (!qobject_cast<QAbstractScrollArea *>(target->parent())) static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents); #else @@ -334,23 +334,27 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state, d->swipeAngle = QLineF(p1.startScreenPos(), p1.screenPos()).angle(); static const int MoveThreshold = 50; + static const int directionChangeThreshold = MoveThreshold / 8; if (qAbs(xDistance) > MoveThreshold || qAbs(yDistance) > MoveThreshold) { // measure the distance to check if the direction changed d->lastPositions[0] = p1.screenPos().toPoint(); d->lastPositions[1] = p2.screenPos().toPoint(); d->lastPositions[2] = p3.screenPos().toPoint(); - QSwipeGesture::SwipeDirection horizontal = - xDistance > 0 ? QSwipeGesture::Right : QSwipeGesture::Left; - QSwipeGesture::SwipeDirection vertical = - yDistance > 0 ? QSwipeGesture::Down : QSwipeGesture::Up; - if (d->verticalDirection == QSwipeGesture::NoDirection) + result = QGestureRecognizer::TriggerGesture; + // QTBUG-46195, small changes in direction should not cause the gesture to be canceled. + if (d->verticalDirection == QSwipeGesture::NoDirection || qAbs(yDistance) > directionChangeThreshold) { + const QSwipeGesture::SwipeDirection vertical = yDistance > 0 + ? QSwipeGesture::Down : QSwipeGesture::Up; + if (d->verticalDirection != QSwipeGesture::NoDirection && d->verticalDirection != vertical) + result = QGestureRecognizer::CancelGesture; d->verticalDirection = vertical; - if (d->horizontalDirection == QSwipeGesture::NoDirection) + } + if (d->horizontalDirection == QSwipeGesture::NoDirection || qAbs(xDistance) > directionChangeThreshold) { + const QSwipeGesture::SwipeDirection horizontal = xDistance > 0 + ? QSwipeGesture::Right : QSwipeGesture::Left; + if (d->horizontalDirection != QSwipeGesture::NoDirection && d->horizontalDirection != horizontal) + result = QGestureRecognizer::CancelGesture; d->horizontalDirection = horizontal; - if (d->verticalDirection != vertical || d->horizontalDirection != horizontal) { - result = QGestureRecognizer::CancelGesture; - } else { - result = QGestureRecognizer::TriggerGesture; } } else { if (q->state() != Qt::NoGesture) diff --git a/src/widgets/kernel/qtooltip.h b/src/widgets/kernel/qtooltip.h index 286d8fb3278d8d53437f4d146736f850bd35e712..54cf71d2f04a08a48c47a27d262f6c2b97cb1d53 100644 --- a/src/widgets/kernel/qtooltip.h +++ b/src/widgets/kernel/qtooltip.h @@ -46,7 +46,7 @@ class Q_WIDGETS_EXPORT QToolTip QToolTip() Q_DECL_EQ_DELETE; public: // ### Qt 6 - merge the three showText functions below - static void showText(const QPoint &pos, const QString &text, QWidget *w = 0); + static void showText(const QPoint &pos, const QString &text, QWidget *w = Q_NULLPTR); static void showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect); static void showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect, int msecShowTime); static inline void hideText() { showText(QPoint(), QString()); } diff --git a/src/widgets/kernel/qwhatsthis.h b/src/widgets/kernel/qwhatsthis.h index 999c66486c1c8a70c5551eb1c16f453c4f79fdda..367b8aab3c4304a2f50d20630adc3c10094bb7bb 100644 --- a/src/widgets/kernel/qwhatsthis.h +++ b/src/widgets/kernel/qwhatsthis.h @@ -53,10 +53,10 @@ public: static bool inWhatsThisMode(); static void leaveWhatsThisMode(); - static void showText(const QPoint &pos, const QString &text, QWidget *w = 0); + static void showText(const QPoint &pos, const QString &text, QWidget *w = Q_NULLPTR); static void hideText(); - static QAction *createAction(QObject *parent = 0); + static QAction *createAction(QObject *parent = Q_NULLPTR); }; diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index b4943bbe053833ff137101763c6247202170101e..9195c1e5fa40a28af92028fcd855b840f115cab1 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -68,6 +68,7 @@ #include "private/qstylesheetstyle_p.h" #include "private/qstyle_p.h" #include "qfileinfo.h" +#include <QtGui/private/qhighdpiscaling_p.h> #include <QtGui/qinputmethod.h> #include <QtGui/qopenglcontext.h> #include <QtGui/private/qopenglcontext_p.h> @@ -289,8 +290,15 @@ QWidgetPrivate::QWidgetPrivate(int version) return; } +#ifdef QT_BUILD_INTERNAL + // Don't check the version parameter in internal builds. + // This allows incompatible versions to be loaded, possibly for testing. + Q_UNUSED(version); +#else if (version != QObjectPrivateVersion) - qFatal("Cannot mix incompatible Qt libraries"); + qFatal("Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)", + version, QObjectPrivateVersion); +#endif isWidget = true; memset(high_attributes, 0, sizeof(high_attributes)); @@ -2028,7 +2036,7 @@ void QWidgetPrivate::setSystemClip(QPaintDevice *paintDevice, const QRegion ® // Transform the system clip region from device-independent pixels to device pixels QPaintEngine *paintEngine = paintDevice->paintEngine(); QTransform scaleTransform; - const qreal devicePixelRatio = paintDevice->devicePixelRatio(); + const qreal devicePixelRatio = paintDevice->devicePixelRatioF(); scaleTransform.scale(devicePixelRatio, devicePixelRatio); paintEngine->d_func()->systemClip = scaleTransform.map(region); } @@ -2454,7 +2462,7 @@ QWidget *QWidget::find(WId id) If a widget is non-native (alien) and winId() is invoked on it, that widget will be provided a native handle. - On Mac OS X, the type returned depends on which framework Qt was linked + On OS X, the type returned depends on which framework Qt was linked against. If Qt is using Carbon, the {WId} is actually an HIViewRef. If Qt is using Cocoa, {WId} is a pointer to an NSView. @@ -2590,7 +2598,7 @@ QWindow *QWidget::windowHandle() const The style sheet contains a textual description of customizations to the widget's style, as described in the \l{Qt Style Sheets} document. - Since Qt 4.5, Qt style sheets fully supports Mac OS X. + Since Qt 4.5, Qt style sheets fully supports OS X. \warning Qt style sheets are currently not supported for custom QStyle subclasses. We plan to address this in some future release. @@ -5065,7 +5073,7 @@ void QWidget::render(QPaintDevice *target, const QPoint &targetOffset, Transformations and settings applied to the \a painter will be used when rendering. - \note The \a painter must be active. On Mac OS X the widget will be + \note The \a painter must be active. On OS X the widget will be rendered into a QPixmap and then drawn by the \a painter. \sa QPainter::device() @@ -5354,7 +5362,7 @@ void QWidgetPrivate::render_helper(QPainter *painter, const QPoint &targetOffset if (size.isNull()) return; - const qreal pixmapDevicePixelRatio = qreal(painter->device()->devicePixelRatio()); + const qreal pixmapDevicePixelRatio = painter->device()->devicePixelRatioF(); QPixmap pixmap(size * pixmapDevicePixelRatio); pixmap.setDevicePixelRatio(pixmapDevicePixelRatio); @@ -6200,7 +6208,7 @@ QString QWidget::windowIconText() const If the window title is set at any point, then the window title takes precedence and will be shown instead of the file path string. - Additionally, on Mac OS X, this has an added benefit that it sets the + Additionally, on OS X, this has an added benefit that it sets the \l{http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGWindows/chapter_17_section_3.html}{proxy icon} for the window, assuming that the file path exists. @@ -9730,6 +9738,8 @@ void QWidget::setInputMethodHints(Qt::InputMethodHints hints) d->imHints = hints; if (this == QGuiApplication::focusObject()) QGuiApplication::inputMethod()->update(Qt::ImHints); +#else + Q_UNUSED(hints); #endif //QT_NO_IM } @@ -11223,7 +11233,7 @@ bool QWidget::testAttribute_helper(Qt::WidgetAttribute attribute) const By default the value of this property is 1.0. - This feature is available on Embedded Linux, Mac OS X, Windows, + This feature is available on Embedded Linux, OS X, Windows, and X11 platforms that support the Composite extension. This feature is not available on Windows CE. @@ -11286,7 +11296,7 @@ void QWidgetPrivate::setWindowOpacity_sys(qreal level) A modified window is a window whose content has changed but has not been saved to disk. This flag will have different effects - varied by the platform. On Mac OS X the close button will have a + varied by the platform. On OS X the close button will have a modified look; on other platforms, the window title will have an '*' (asterisk). @@ -11824,13 +11834,11 @@ void QWidgetPrivate::updateFrameStrut() Q_Q(QWidget); if (q->data->fstrut_dirty) { if (QTLWExtra *te = maybeTopData()) { - if (te->window) { - if (const QPlatformWindow *pw = te->window->handle()) { - const QMargins margins = pw->frameMargins(); - if (!margins.isNull()) { - te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom()); - q->data->fstrut_dirty = false; - } + if (te->window && te->window->handle()) { + const QMargins margins = te->window->frameMargins(); + if (!margins.isNull()) { + te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom()); + q->data->fstrut_dirty = false; } } } @@ -12283,20 +12291,21 @@ QPaintEngine *QWidget::paintEngine() const */ QPoint QWidget::mapToGlobal(const QPoint &pos) const { -#ifndef QT_NO_GRAPHICSVIEW - Q_D(const QWidget); - if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) { - const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views(); - if (!views.isEmpty()) { - const QPointF scenePos = d->extra->proxyWidget->mapToScene(pos); - const QPoint viewPortPos = views.first()->mapFromScene(scenePos); - return views.first()->viewport()->mapToGlobal(viewPortPos); - } - } -#endif // !QT_NO_GRAPHICSVIEW int x = pos.x(), y = pos.y(); const QWidget *w = this; while (w) { +#ifndef QT_NO_GRAPHICSVIEW + const QWidgetPrivate *d = w->d_func(); + if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) { + const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views(); + if (!views.isEmpty()) { + const QPointF scenePos = d->extra->proxyWidget->mapToScene(QPoint(x, y)); + const QPoint viewPortPos = views.first()->mapFromScene(scenePos); + return views.first()->viewport()->mapToGlobal(viewPortPos); + } + } +#endif // !QT_NO_GRAPHICSVIEW + QWindow *window = w->windowHandle(); if (window && window->handle()) return window->mapToGlobal(QPoint(x, y)); @@ -12318,20 +12327,21 @@ QPoint QWidget::mapToGlobal(const QPoint &pos) const */ QPoint QWidget::mapFromGlobal(const QPoint &pos) const { -#ifndef QT_NO_GRAPHICSVIEW - Q_D(const QWidget); - if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) { - const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views(); - if (!views.isEmpty()) { - const QPoint viewPortPos = views.first()->viewport()->mapFromGlobal(pos); - const QPointF scenePos = views.first()->mapToScene(viewPortPos); - return d->extra->proxyWidget->mapFromScene(scenePos).toPoint(); - } - } -#endif // !QT_NO_GRAPHICSVIEW int x = pos.x(), y = pos.y(); const QWidget *w = this; while (w) { +#ifndef QT_NO_GRAPHICSVIEW + const QWidgetPrivate *d = w->d_func(); + if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) { + const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views(); + if (!views.isEmpty()) { + const QPoint viewPortPos = views.first()->viewport()->mapFromGlobal(QPoint(x, y)); + const QPointF scenePos = views.first()->mapToScene(viewPortPos); + return d->extra->proxyWidget->mapFromScene(scenePos).toPoint(); + } + } +#endif // !QT_NO_GRAPHICSVIEW + QWindow *window = w->windowHandle(); if (window && window->handle()) return window->mapFromGlobal(QPoint(x, y)); @@ -12647,6 +12657,9 @@ int QWidget::metric(PaintDeviceMetric m) const return qRound(screen->physicalDotsPerInchY()); } else if (m == PdmDevicePixelRatio) { return topLevelWindow ? topLevelWindow->devicePixelRatio() : qApp->devicePixelRatio(); + } else if (m == PdmDevicePixelRatioScaled) { + return (QPaintDevice::devicePixelRatioFScale() * + (topLevelWindow ? topLevelWindow->devicePixelRatio() : qApp->devicePixelRatio())); } else { val = QPaintDevice::metric(m);// XXX } @@ -12762,7 +12775,7 @@ void QWidgetPrivate::setMask_sys(const QRegion ®ion) Q_Q(QWidget); if (const QWindow *window = q->windowHandle()) if (QPlatformWindow *platformWindow = window->handle()) - platformWindow->setMask(region); + platformWindow->setMask(QHighDpi::toNativeLocalRegion(region, window)); } /*! @@ -12862,7 +12875,7 @@ QDebug operator<<(QDebug debug, const QWidget *widget) frameGeometry.bottom() - geometry.bottom()); debug << ", margins=" << margins; } - debug << ", devicePixelRatio=" << widget->devicePixelRatio(); + debug << ", devicePixelRatio=" << widget->devicePixelRatioF(); if (const WId wid = widget->internalWinId()) debug << ", winId=0x" << hex << wid << dec; } diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 782c892a32401903e83a91f0b20c561b4636b44f..a56f6e1133574492040f55993e82b1a8a9510e20 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -203,7 +203,7 @@ public: }; Q_DECLARE_FLAGS(RenderFlags, RenderFlag) - explicit QWidget(QWidget* parent = 0, Qt::WindowFlags f = 0); + explicit QWidget(QWidget* parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); ~QWidget(); int devType() const Q_DECL_OVERRIDE; @@ -593,7 +593,7 @@ public: QWindow *windowHandle() const; - static QWidget *createWindowContainer(QWindow *window, QWidget *parent=0, Qt::WindowFlags flags=0); + static QWidget *createWindowContainer(QWindow *window, QWidget *parent=Q_NULLPTR, Qt::WindowFlags flags=Qt::WindowFlags()); friend class QDesktopScreenWidget; @@ -734,12 +734,12 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QWidget::RenderFlags) #ifndef Q_QDOC template <> inline QWidget *qobject_cast<QWidget*>(QObject *o) { - if (!o || !o->isWidgetType()) return 0; + if (!o || !o->isWidgetType()) return Q_NULLPTR; return static_cast<QWidget*>(o); } template <> inline const QWidget *qobject_cast<const QWidget*>(const QObject *o) { - if (!o || !o->isWidgetType()) return 0; + if (!o || !o->isWidgetType()) return Q_NULLPTR; return static_cast<const QWidget*>(o); } #endif // !Q_QDOC diff --git a/src/widgets/kernel/qwidgetaction.cpp b/src/widgets/kernel/qwidgetaction.cpp index 27d4a650b404df2991882963ba343449ece455de..3c0c203fd644ff7b1abd3dae55348696d2cccb26 100644 --- a/src/widgets/kernel/qwidgetaction.cpp +++ b/src/widgets/kernel/qwidgetaction.cpp @@ -79,8 +79,8 @@ QT_BEGIN_NAMESPACE Note that it is up to the widget to activate the action, for example by reimplementing mouse event handlers and calling QAction::trigger(). - \b {Mac OS X}: If you add a widget to a menu in the application's menu - bar on Mac OS X, the widget will be added and it will function but with some + \b {OS X}: If you add a widget to a menu in the application's menu + bar on OS X, the widget will be added and it will function but with some limitations: \list 1 \li The widget is reparented away from the QMenu to the native menu diff --git a/src/widgets/kernel/qwidgetsfunctions_wince.cpp b/src/widgets/kernel/qwidgetsfunctions_wince.cpp index f06514dbe45558cafef3ff5c505b210d620a32b1..d42e4ebc210960fc9c2babfd17c60453102e7c4e 100644 --- a/src/widgets/kernel/qwidgetsfunctions_wince.cpp +++ b/src/widgets/kernel/qwidgetsfunctions_wince.cpp @@ -51,14 +51,10 @@ HINSTANCE qt_wince_ShellExecute(HWND hwnd, LPCWSTR, LPCWSTR file, LPCWSTR params } #endif -#ifndef SPI_GETPLATFORMTYPE -#define SPI_GETPLATFORMTYPE 257 -#endif - // Internal Qt ----------------------------------------------------- bool qt_wince_is_platform(const QString &platformString) { wchar_t tszPlatform[64]; - if (SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(tszPlatform) / sizeof(wchar_t), tszPlatform, 0)) + if (SystemParametersInfo(SPI_GETPLATFORMNAME, sizeof(tszPlatform) / sizeof(wchar_t), tszPlatform, 0)) if (0 == _tcsicmp(reinterpret_cast<const wchar_t *> (platformString.utf16()), tszPlatform)) return true; return false; diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 01d6d8985729e37748e4b0474c91177249c9b823..633e7108530ff690eca7a234e9f8417a711f5554 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -45,6 +45,7 @@ #include <qpa/qplatformtheme.h> #include <qpa/qplatformwindow.h> #include <private/qgesturemanager_p.h> +#include <private/qhighdpiscaling_p.h> QT_BEGIN_NAMESPACE @@ -671,7 +672,7 @@ void QWidgetWindow::updateNormalGeometry() // Ask platform window, default to widget geometry. QRect normalGeometry; if (const QPlatformWindow *pw = handle()) - normalGeometry = pw->normalGeometry(); + normalGeometry = QHighDpi::fromNativePixels(pw->normalGeometry(), this); if (!normalGeometry.isValid() && effectiveState(m_widget->windowState()) == Qt::WindowNoState) normalGeometry = m_widget->geometry(); if (normalGeometry.isValid()) diff --git a/src/widgets/kernel/win.pri b/src/widgets/kernel/win.pri index 76bb709e2b8e99930c7e91ad88eb4858536a78a7..e2d5afdeecc0a03b3ad2a353b1ba175db650703a 100644 --- a/src/widgets/kernel/win.pri +++ b/src/widgets/kernel/win.pri @@ -2,6 +2,6 @@ # -------------------------------------------------------------------- INCLUDEPATH += ../3rdparty/wintab -!wince*:!winrt { +!wince:!winrt { LIBS_PRIVATE *= -lshell32 } diff --git a/src/widgets/statemachine/qkeyeventtransition.cpp b/src/widgets/statemachine/qkeyeventtransition.cpp index 3283003e2e9449ea4097b0cb2495aca999eccd14..67af85dd27a64b57d86edfbf6bde6139117bdf01 100644 --- a/src/widgets/statemachine/qkeyeventtransition.cpp +++ b/src/widgets/statemachine/qkeyeventtransition.cpp @@ -117,7 +117,7 @@ int QKeyEventTransition::key() const } /*! - Sets the key that this key event transition will check for. + Sets the \a key that this key event transition will check for. */ void QKeyEventTransition::setKey(int key) { diff --git a/src/widgets/statemachine/qkeyeventtransition.h b/src/widgets/statemachine/qkeyeventtransition.h index 5dd0685d0be85060b753f9d776669e6a20fddc5a..ad159eaa2202166bda698da11d3917e5f21da4b4 100644 --- a/src/widgets/statemachine/qkeyeventtransition.h +++ b/src/widgets/statemachine/qkeyeventtransition.h @@ -48,9 +48,9 @@ class Q_WIDGETS_EXPORT QKeyEventTransition : public QEventTransition Q_PROPERTY(int key READ key WRITE setKey) Q_PROPERTY(Qt::KeyboardModifiers modifierMask READ modifierMask WRITE setModifierMask) public: - QKeyEventTransition(QState *sourceState = 0); + QKeyEventTransition(QState *sourceState = Q_NULLPTR); QKeyEventTransition(QObject *object, QEvent::Type type, int key, - QState *sourceState = 0); + QState *sourceState = Q_NULLPTR); ~QKeyEventTransition(); int key() const; diff --git a/src/widgets/statemachine/qmouseeventtransition.h b/src/widgets/statemachine/qmouseeventtransition.h index d9bac9e1a03d01c067999dbfd73ad64f29b6ddc0..b4db61279d7155f6e6f1a6033aafa6ac9c128c40 100644 --- a/src/widgets/statemachine/qmouseeventtransition.h +++ b/src/widgets/statemachine/qmouseeventtransition.h @@ -49,9 +49,9 @@ class Q_WIDGETS_EXPORT QMouseEventTransition : public QEventTransition Q_PROPERTY(Qt::MouseButton button READ button WRITE setButton) Q_PROPERTY(Qt::KeyboardModifiers modifierMask READ modifierMask WRITE setModifierMask) public: - QMouseEventTransition(QState *sourceState = 0); + QMouseEventTransition(QState *sourceState = Q_NULLPTR); QMouseEventTransition(QObject *object, QEvent::Type type, - Qt::MouseButton button, QState *sourceState = 0); + Qt::MouseButton button, QState *sourceState = Q_NULLPTR); ~QMouseEventTransition(); Qt::MouseButton button() const; diff --git a/src/widgets/styles/qcommonstyle.h b/src/widgets/styles/qcommonstyle.h index 06fd755fa1ff6fe08228259aa0e5c5ba53f49ebe..0d040f1b3e0f14a5442480f88b73048298d12f88 100644 --- a/src/widgets/styles/qcommonstyle.h +++ b/src/widgets/styles/qcommonstyle.h @@ -49,34 +49,34 @@ public: ~QCommonStyle(); void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, - const QWidget *w = 0) const Q_DECL_OVERRIDE; + const QWidget *w = Q_NULLPTR) const Q_DECL_OVERRIDE; void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, - const QWidget *w = 0) const Q_DECL_OVERRIDE; - QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const Q_DECL_OVERRIDE; + const QWidget *w = Q_NULLPTR) const Q_DECL_OVERRIDE; + QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, - const QWidget *w = 0) const Q_DECL_OVERRIDE; + const QWidget *w = Q_NULLPTR) const Q_DECL_OVERRIDE; SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, - const QPoint &pt, const QWidget *w = 0) const Q_DECL_OVERRIDE; + const QPoint &pt, const QWidget *w = Q_NULLPTR) const Q_DECL_OVERRIDE; QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, - const QWidget *w = 0) const Q_DECL_OVERRIDE; + const QWidget *w = Q_NULLPTR) const Q_DECL_OVERRIDE; QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, - const QSize &contentsSize, const QWidget *widget = 0) const Q_DECL_OVERRIDE; + const QSize &contentsSize, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; - int pixelMetric(PixelMetric m, const QStyleOption *opt = 0, const QWidget *widget = 0) const Q_DECL_OVERRIDE; + int pixelMetric(PixelMetric m, const QStyleOption *opt = Q_NULLPTR, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; - int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0, - QStyleHintReturn *shret = 0) const Q_DECL_OVERRIDE; + int styleHint(StyleHint sh, const QStyleOption *opt = Q_NULLPTR, const QWidget *w = Q_NULLPTR, + QStyleHintReturn *shret = Q_NULLPTR) const Q_DECL_OVERRIDE; - QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *opt = 0, - const QWidget *widget = 0) const Q_DECL_OVERRIDE; - QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt = 0, - const QWidget *widget = 0) const Q_DECL_OVERRIDE; + QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *opt = Q_NULLPTR, + const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt = Q_NULLPTR, + const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const Q_DECL_OVERRIDE; int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, - Qt::Orientation orientation, const QStyleOption *option = 0, - const QWidget *widget = 0) const Q_DECL_OVERRIDE; + Qt::Orientation orientation, const QStyleOption *option = Q_NULLPTR, + const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; void polish(QPalette &) Q_DECL_OVERRIDE; void polish(QApplication *app) Q_DECL_OVERRIDE; diff --git a/src/widgets/styles/qdrawutil.h b/src/widgets/styles/qdrawutil.h index 1f2078a931ab77d5bca009b575fbaa5ffd434913..f34a2857a7253243e2b16343351137320eec2be3 100644 --- a/src/widgets/styles/qdrawutil.h +++ b/src/widgets/styles/qdrawutil.h @@ -63,42 +63,42 @@ Q_WIDGETS_EXPORT void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint Q_WIDGETS_EXPORT void qDrawShadeRect(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken = false, int lineWidth = 1, int midLineWidth = 0, - const QBrush *fill = 0); + const QBrush *fill = Q_NULLPTR); Q_WIDGETS_EXPORT void qDrawShadeRect(QPainter *p, const QRect &r, const QPalette &pal, bool sunken = false, int lineWidth = 1, int midLineWidth = 0, - const QBrush *fill = 0); + const QBrush *fill = Q_NULLPTR); Q_WIDGETS_EXPORT void qDrawShadePanel(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken = false, - int lineWidth = 1, const QBrush *fill = 0); + int lineWidth = 1, const QBrush *fill = Q_NULLPTR); Q_WIDGETS_EXPORT void qDrawShadePanel(QPainter *p, const QRect &r, const QPalette &pal, bool sunken = false, - int lineWidth = 1, const QBrush *fill = 0); + int lineWidth = 1, const QBrush *fill = Q_NULLPTR); Q_WIDGETS_EXPORT void qDrawWinButton(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken = false, - const QBrush *fill = 0); + const QBrush *fill = Q_NULLPTR); Q_WIDGETS_EXPORT void qDrawWinButton(QPainter *p, const QRect &r, const QPalette &pal, bool sunken = false, - const QBrush *fill = 0); + const QBrush *fill = Q_NULLPTR); Q_WIDGETS_EXPORT void qDrawWinPanel(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken = false, - const QBrush *fill = 0); + const QBrush *fill = Q_NULLPTR); Q_WIDGETS_EXPORT void qDrawWinPanel(QPainter *p, const QRect &r, const QPalette &pal, bool sunken = false, - const QBrush *fill = 0); + const QBrush *fill = Q_NULLPTR); Q_WIDGETS_EXPORT void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &, - int lineWidth = 1, const QBrush *fill = 0); + int lineWidth = 1, const QBrush *fill = Q_NULLPTR); Q_WIDGETS_EXPORT void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &, - int lineWidth = 1, const QBrush *fill = 0); + int lineWidth = 1, const QBrush *fill = Q_NULLPTR); @@ -145,7 +145,7 @@ Q_WIDGETS_EXPORT void qDrawBorderPixmap(QPainter *painter, const QMargins &sourceMargins, const QTileRules &rules = QTileRules() #ifndef Q_QDOC - , QDrawBorderPixmap::DrawingHints hints = 0 + , QDrawBorderPixmap::DrawingHints hints = QDrawBorderPixmap::DrawingHints() #endif ); diff --git a/src/widgets/styles/qgtk2painter.cpp b/src/widgets/styles/qgtk2painter.cpp index 489d456617454d130d4bb11b9aaa1d591bccd4fc..ea8afbc93c92af3448d1a978b26bb980bb5cb810 100644 --- a/src/widgets/styles/qgtk2painter.cpp +++ b/src/widgets/styles/qgtk2painter.cpp @@ -93,6 +93,7 @@ namespace QGtk2PainterPrivate { static void initGtk() { +#ifndef QT_NO_LIBRARY static bool initialized = false; if (!initialized) { // enforce the "0" suffix, so we'll open libgtk-x11-2.0.so.0 @@ -123,6 +124,7 @@ static void initGtk() initialized = true; } +#endif // !QT_NO_LIBRARY } // To recover alpha we apply the gtk painting function two times to diff --git a/src/widgets/styles/qgtkstyle_p.cpp b/src/widgets/styles/qgtkstyle_p.cpp index 0e119a11ae065fecdccb42d783d8d1fc72271e2a..00682c1c0f5dcc988290018e633c4ccdee5116f7 100644 --- a/src/widgets/styles/qgtkstyle_p.cpp +++ b/src/widgets/styles/qgtkstyle_p.cpp @@ -326,6 +326,7 @@ void QGtkStylePrivate::gtkWidgetSetFocus(GtkWidget *widget, bool focus) */ void QGtkStylePrivate::resolveGtk() const { +#ifndef QT_NO_LIBRARY // enforce the "0" suffix, so we'll open libgtk-x11-2.0.so.0 QLibrary libgtk(QLS("gtk-x11-2.0"), 0, 0); @@ -427,6 +428,7 @@ void QGtkStylePrivate::resolveGtk() const gnome_icon_lookup_sync = (Ptr_gnome_icon_lookup_sync)QLibrary::resolve(QLS("gnomeui-2"), 0, "gnome_icon_lookup_sync"); gnome_vfs_init= (Ptr_gnome_vfs_init)QLibrary::resolve(QLS("gnomevfs-2"), 0, "gnome_vfs_init"); +#endif // !QT_NO_LIBRARY } /* \internal @@ -593,11 +595,13 @@ void QGtkStylePrivate::cleanupGtkWidgets() static bool resolveGConf() { +#ifndef QT_NO_LIBRARY if (!QGtkStylePrivate::gconf_client_get_default) { QGtkStylePrivate::gconf_client_get_default = (Ptr_gconf_client_get_default)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_default"); QGtkStylePrivate::gconf_client_get_string = (Ptr_gconf_client_get_string)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_string"); QGtkStylePrivate::gconf_client_get_bool = (Ptr_gconf_client_get_bool)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_bool"); } +#endif // !QT_NO_LIBRARY return (QGtkStylePrivate::gconf_client_get_default !=0); } diff --git a/src/widgets/styles/qmacstyle.qdoc b/src/widgets/styles/qmacstyle.qdoc index 58a185d15c033923071f1a449b8839b6a2b2870b..0800e2d608071e03418d258df3ea5979646d860a 100644 --- a/src/widgets/styles/qmacstyle.qdoc +++ b/src/widgets/styles/qmacstyle.qdoc @@ -28,7 +28,7 @@ /*! \class QMacStyle - \brief The QMacStyle class provides a Mac OS X style using the Apple Appearance Manager. + \brief The QMacStyle class provides a OS X style using the Apple Appearance Manager. \ingroup appearance \inmodule QtWidgets @@ -36,10 +36,10 @@ This class is implemented as a wrapper to the HITheme APIs, allowing applications to be styled according to the current - theme in use on Mac OS X. This is done by having primitives - in QStyle implemented in terms of what Mac OS X would normally theme. + theme in use on OS X. This is done by having primitives + in QStyle implemented in terms of what OS X would normally theme. - \warning This style is only available on Mac OS X because it relies on the + \warning This style is only available on OS X because it relies on the HITheme APIs. There are additional issues that should be taken @@ -56,7 +56,7 @@ involve horizontal and vertical widget alignment and widget size (covered below). - \li Widget size - Mac OS X allows widgets to have specific fixed sizes. Qt + \li Widget size - OS X allows widgets to have specific fixed sizes. Qt does not fully implement this behavior so as to maintain cross-platform compatibility. As a result some widgets sizes may be inappropriate (and subsequently not rendered correctly by the HITheme APIs).The @@ -75,7 +75,7 @@ There are other issues that need to be considered in the feel of your application (including the general color scheme to match the Aqua colors). The Guidelines mentioned above will remain current - with new advances and design suggestions for Mac OS X. + with new advances and design suggestions for OS X. Note that the functions provided by QMacStyle are reimplementations of QStyle functions; see QStyle for their diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 50c8fd7ed8f25f28899c39359d578c7e68a6c344..aa1a78357768565d9a07c50b6c509d5045f6fbb3 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -114,7 +114,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(NotificationReceiver); { Q_UNUSED(notification); QEvent event(QEvent::StyleChange); - QMutableSetIterator<QPointer<QObject> > it(QMacStylePrivate::scrollBars); + QMutableVectorIterator<QPointer<QObject> > it(QMacStylePrivate::scrollBars); while (it.hasNext()) { if (!it.next()) it.remove(); @@ -138,12 +138,7 @@ const int QMacStylePrivate::BevelButtonW = 50; const int QMacStylePrivate::BevelButtonH = 22; const int QMacStylePrivate::PushButtonContentPadding = 6; -QSet<QPointer<QObject> > QMacStylePrivate::scrollBars; - -static uint qHash(const QPointer<QObject> &ptr) -{ - return qHash(ptr.data()); -} +QVector<QPointer<QObject> > QMacStylePrivate::scrollBars; // Title bar gradient colors for Lion were determined by inspecting PSDs exported // using CoreUI's CoreThemeDocument; there is no public API to retrieve them @@ -1977,7 +1972,7 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD } } - int devicePixelRatio = p->device()->devicePixelRatio(); + int devicePixelRatio = p->device()->devicePixelRatioF(); int width = devicePixelRatio * (int(macRect.size.width) + extraWidth); int height = devicePixelRatio * (int(macRect.size.height) + extraHeight); @@ -5367,7 +5362,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex // there is not enough space for them. if (cc == CC_ScrollBar) { if (opt && opt->styleObject && !QMacStylePrivate::scrollBars.contains(opt->styleObject)) - QMacStylePrivate::scrollBars.insert(QPointer<QObject>(opt->styleObject)); + QMacStylePrivate::scrollBars.append(QPointer<QObject>(opt->styleObject)); const int scrollBarLength = (slider->orientation == Qt::Horizontal) ? slider->rect.width() : slider->rect.height(); const QMacStyle::WidgetSizePolicy sizePolicy = widgetSizePolicy(widget, opt); @@ -7181,7 +7176,7 @@ static CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintD returned if it can't be obtained. It is the caller's responsibility to CGContextRelease the context when finished using it. - \warning This function is only available on Mac OS X. + \warning This function is only available on OS X. \warning This function is duplicated in the Cocoa platform plugin. */ @@ -7204,7 +7199,7 @@ CGContextRef qt_mac_cg_context(const QPaintDevice *pdev) } CGContextTranslateCTM(ret, 0, pm->height()); - int devicePixelRatio = pdev->devicePixelRatio(); + qreal devicePixelRatio = pdev->devicePixelRatioF(); CGContextScaleCTM(ret, devicePixelRatio, devicePixelRatio); CGContextScaleCTM(ret, 1, -1); return ret; diff --git a/src/widgets/styles/qmacstyle_mac_p_p.h b/src/widgets/styles/qmacstyle_mac_p_p.h index b09e81d595013a41a6770aa912ae653adc028ac1..33818568ec71ba0f6c53f8b1bf7ef6f73a6859ae 100644 --- a/src/widgets/styles/qmacstyle_mac_p_p.h +++ b/src/widgets/styles/qmacstyle_mac_p_p.h @@ -86,7 +86,7 @@ #include <qdatetimeedit.h> #include <qmath.h> #include <qpair.h> -#include <qset.h> +#include <qvector.h> #include <QtWidgets/qgraphicsproxywidget.h> #include <QtWidgets/qgraphicsview.h> @@ -213,7 +213,7 @@ public: mutable QPointer<QObject> pressedButton; mutable QPointer<QObject> defaultButton; mutable QPointer<QObject> autoDefaultButton; - static QSet<QPointer<QObject> > scrollBars; + static QVector<QPointer<QObject> > scrollBars; struct ButtonState { int frame; diff --git a/src/widgets/styles/qproxystyle.h b/src/widgets/styles/qproxystyle.h index cac4cde0f23281506fd171ca250a339ed6db26cf..072965bbd7c93c41a825059fc3c9ece1165385bf 100644 --- a/src/widgets/styles/qproxystyle.h +++ b/src/widgets/styles/qproxystyle.h @@ -47,16 +47,16 @@ class Q_WIDGETS_EXPORT QProxyStyle : public QCommonStyle Q_OBJECT public: - QProxyStyle(QStyle *style = 0); + QProxyStyle(QStyle *style = Q_NULLPTR); QProxyStyle(const QString &key); ~QProxyStyle(); QStyle *baseStyle() const; void setBaseStyle(QStyle *style); - void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const Q_DECL_OVERRIDE; - void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const Q_DECL_OVERRIDE; - void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = 0) const Q_DECL_OVERRIDE; + void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; void drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled, const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const Q_DECL_OVERRIDE; virtual void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const Q_DECL_OVERRIDE; @@ -68,14 +68,14 @@ public: QRect itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const Q_DECL_OVERRIDE; QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const Q_DECL_OVERRIDE; - SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget = 0) const Q_DECL_OVERRIDE; - int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const Q_DECL_OVERRIDE; - int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const Q_DECL_OVERRIDE; + SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + int styleHint(StyleHint hint, const QStyleOption *option = Q_NULLPTR, const QWidget *widget = Q_NULLPTR, QStyleHintReturn *returnData = Q_NULLPTR) const Q_DECL_OVERRIDE; + int pixelMetric(PixelMetric metric, const QStyleOption *option = Q_NULLPTR, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, - Qt::Orientation orientation, const QStyleOption *option = 0, const QWidget *widget = 0) const Q_DECL_OVERRIDE; + Qt::Orientation orientation, const QStyleOption *option = Q_NULLPTR, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; - QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = 0, const QWidget *widget = 0) const Q_DECL_OVERRIDE; - QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = 0) const Q_DECL_OVERRIDE; + QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = Q_NULLPTR, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const Q_DECL_OVERRIDE; QPalette standardPalette() const Q_DECL_OVERRIDE; diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 1849331b7913305f9c864357b9ab1a8190775bc5..5e51866d8fc8d742d8ff884c4ed1fe989686fae1 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -98,7 +98,7 @@ static int unpackControlTypes(QSizePolicy::ControlTypes controls, QSizePolicy::C The style gets all the information it needs to render the graphical element from the QStyleOption class. The widget is passed as the last argument in case the style needs it to perform - special effects (such as animated default buttons on Mac OS X), + special effects (such as animated default buttons on OS X), but it isn't mandatory. In fact, QStyle can be used to draw on any paint device (not just widgets), in which case the widget argument is a zero pointer. @@ -197,7 +197,7 @@ static int unpackControlTypes(QSizePolicy::ControlTypes controls, QSizePolicy::C QStyle gets all the information it needs to render the graphical element from QStyleOption. The widget is passed as the last argument in case the style needs it to perform special effects - (such as animated default buttons on Mac OS X), but it isn't + (such as animated default buttons on OS X), but it isn't mandatory. In fact, you can use QStyle to draw on any paint device, not just widgets, by setting the QPainter properly. diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index b41762795d3007c32e2d288a635a0e1f7abc7d7a..1e9d15c9932e6090ecf5505c79dcf9b3e2489373 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -192,7 +192,7 @@ public: Q_ENUM(PrimitiveElement) virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, - const QWidget *w = 0) const = 0; + const QWidget *w = Q_NULLPTR) const = 0; enum ControlElement { CE_PushButton, CE_PushButtonBevel, @@ -263,7 +263,7 @@ public: Q_ENUM(ControlElement) virtual void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, - const QWidget *w = 0) const = 0; + const QWidget *w = Q_NULLPTR) const = 0; enum SubElement { SE_PushButtonContents, @@ -347,7 +347,7 @@ public: Q_ENUM(SubElement) virtual QRect subElementRect(SubElement subElement, const QStyleOption *option, - const QWidget *widget = 0) const = 0; + const QWidget *widget = Q_NULLPTR) const = 0; enum ComplexControl { @@ -426,11 +426,11 @@ public: virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, - const QWidget *widget = 0) const = 0; + const QWidget *widget = Q_NULLPTR) const = 0; virtual SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, - const QPoint &pt, const QWidget *widget = 0) const = 0; + const QPoint &pt, const QWidget *widget = Q_NULLPTR) const = 0; virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, - SubControl sc, const QWidget *widget = 0) const = 0; + SubControl sc, const QWidget *widget = Q_NULLPTR) const = 0; enum PixelMetric { PM_ButtonMargin, @@ -561,8 +561,8 @@ public: }; Q_ENUM(PixelMetric) - virtual int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, - const QWidget *widget = 0) const = 0; + virtual int pixelMetric(PixelMetric metric, const QStyleOption *option = Q_NULLPTR, + const QWidget *widget = Q_NULLPTR) const = 0; enum ContentsType { CT_PushButton, @@ -594,7 +594,7 @@ public: Q_ENUM(ContentsType) virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, - const QSize &contentsSize, const QWidget *w = 0) const = 0; + const QSize &contentsSize, const QWidget *w = Q_NULLPTR) const = 0; enum RequestSoftwareInputPanel { RSIP_OnMouseClickAndAlreadyFocused, @@ -724,8 +724,8 @@ public: }; Q_ENUM(StyleHint) - virtual int styleHint(StyleHint stylehint, const QStyleOption *opt = 0, - const QWidget *widget = 0, QStyleHintReturn* returnData = 0) const = 0; + virtual int styleHint(StyleHint stylehint, const QStyleOption *opt = Q_NULLPTR, + const QWidget *widget = Q_NULLPTR, QStyleHintReturn* returnData = Q_NULLPTR) const = 0; enum StandardPixmap { SP_TitleBarMenuButton, @@ -804,11 +804,11 @@ public: }; Q_ENUM(StandardPixmap) - virtual QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt = 0, - const QWidget *widget = 0) const = 0; + virtual QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt = Q_NULLPTR, + const QWidget *widget = Q_NULLPTR) const = 0; - virtual QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = 0, - const QWidget *widget = 0) const = 0; + virtual QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = Q_NULLPTR, + const QWidget *widget = Q_NULLPTR) const = 0; virtual QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const = 0; @@ -827,10 +827,10 @@ public: virtual int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, - const QStyleOption *option = 0, const QWidget *widget = 0) const = 0; + const QStyleOption *option = Q_NULLPTR, const QWidget *widget = Q_NULLPTR) const = 0; int combinedLayoutSpacing(QSizePolicy::ControlTypes controls1, QSizePolicy::ControlTypes controls2, Qt::Orientation orientation, - QStyleOption *option = 0, QWidget *widget = 0) const; + QStyleOption *option = Q_NULLPTR, QWidget *widget = Q_NULLPTR) const; const QStyle * proxy() const; diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp index f4977103a52fbcf23ce430d8fb34c6c1b1fe6e60..cab56e329eb2c483978d7ac46f0c6c57faf02a78 100644 --- a/src/widgets/styles/qstyleoption.cpp +++ b/src/widgets/styles/qstyleoption.cpp @@ -1739,7 +1739,7 @@ QStyleOptionMenuItem::QStyleOptionMenuItem(int version) \value DefaultItem A menu item that is the default action as specified with \l QMenu::defaultAction(). \value Separator A menu separator. \value SubMenu Indicates the menu item points to a sub-menu. - \value Scroller A popup menu scroller (currently only used on Mac OS X). + \value Scroller A popup menu scroller (currently only used on OS X). \value TearOff A tear-off handle for the menu. \value Margin The margin of the menu. \value EmptyArea The empty area of the menu. diff --git a/src/widgets/styles/qstylepainter.h b/src/widgets/styles/qstylepainter.h index 33d17d42b923cfe8dc18690dd0cf9fc5934981ab..8492d231ae6783c22507e553a1315eb1ab9ee9ab 100644 --- a/src/widgets/styles/qstylepainter.h +++ b/src/widgets/styles/qstylepainter.h @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE class QStylePainter : public QPainter { public: - inline QStylePainter() : QPainter(), widget(0), wstyle(0) {} + inline QStylePainter() : QPainter(), widget(Q_NULLPTR), wstyle(Q_NULLPTR) {} inline explicit QStylePainter(QWidget *w) { begin(w, w); } inline QStylePainter(QPaintDevice *pd, QWidget *w) { begin(pd, w); } inline bool begin(QWidget *w) { return begin(w, w); } diff --git a/src/widgets/styles/qstyleplugin.h b/src/widgets/styles/qstyleplugin.h index b83774a39daf08488ec7d48f7c2b846dfb0f1d62..c8f6344758ae1f8e646b0898891a4e2ddf0e94a8 100644 --- a/src/widgets/styles/qstyleplugin.h +++ b/src/widgets/styles/qstyleplugin.h @@ -48,7 +48,7 @@ class Q_WIDGETS_EXPORT QStylePlugin : public QObject { Q_OBJECT public: - explicit QStylePlugin(QObject *parent = 0); + explicit QStylePlugin(QObject *parent = Q_NULLPTR); ~QStylePlugin(); virtual QStyle *create(const QString &key) = 0; diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 40b8aaae9a8ac5a7c0a3049aeff2e60b5e10abd2..662e1f9b96edaf8b0ae59cd108fc596f45dc27da 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -460,7 +460,6 @@ class QRenderRule public: QRenderRule() : features(0), hasFont(false), pal(0), b(0), bg(0), bd(0), ou(0), geo(0), p(0), img(0), clipset(0) { } QRenderRule(const QVector<QCss::Declaration> &, const QObject *); - ~QRenderRule() { } QRect borderRect(const QRect &r) const; QRect outlineRect(const QRect &r) const; @@ -558,16 +557,22 @@ public: return csz; } + bool hasStyleHint(const QString &sh) const { return styleHints.contains(sh); } + QVariant styleHint(const QString &sh) const { return styleHints.value(sh); } + + void fixupBorder(int); + + // Shouldn't be here + void setClip(QPainter *p, const QRect &rect); + void unsetClip(QPainter *); + +public: int features; QBrush defaultBackground; QFont font; bool hasFont; QHash<QString, QVariant> styleHints; - bool hasStyleHint(const QString& sh) const { return styleHints.contains(sh); } - QVariant styleHint(const QString& sh) const { return styleHints.value(sh); } - - void fixupBorder(int); QSharedDataPointer<QStyleSheetPaletteData> pal; QSharedDataPointer<QStyleSheetBoxData> b; @@ -578,12 +583,10 @@ public: QSharedDataPointer<QStyleSheetPositionData> p; QSharedDataPointer<QStyleSheetImageData> img; - // Shouldn't be here - void setClip(QPainter *p, const QRect &rect); - void unsetClip(QPainter *); int clipset; QPainterPath clipPath; }; +Q_DECLARE_TYPEINFO(QRenderRule, Q_MOVABLE_TYPE); /////////////////////////////////////////////////////////////////////////////////////////// static const char *const knownStyleHints[] = { @@ -728,6 +731,7 @@ namespace { int width; }; } +template <> class QTypeInfo<ButtonInfo> : public QTypeInfoMerger<ButtonInfo, QRenderRule, int> {}; QHash<QStyle::SubControl, QRect> QStyleSheetStyle::titleBarLayout(const QWidget *w, const QStyleOptionTitleBar *tb) const { @@ -742,16 +746,19 @@ QHash<QStyle::SubControl, QRect> QStyleSheetStyle::titleBarLayout(const QWidget int offsets[3] = { 0, 0, 0 }; enum Where { Left, Right, Center, NoWhere } where = Left; - QList<ButtonInfo> infos; - for (int i = 0; i < layout.count(); i++) { - ButtonInfo info; - info.element = layout[i].toInt(); - if (info.element == '(') { + QVector<ButtonInfo> infos; + const int numLayouts = layout.size(); + infos.reserve(numLayouts); + for (int i = 0; i < numLayouts; i++) { + const int element = layout[i].toInt(); + if (element == '(') { where = Center; - } else if (info.element == ')') { + } else if (element == ')') { where = Right; } else { - switch (info.element) { + ButtonInfo info; + info.element = element; + switch (element) { case PseudoElement_TitleBar: if (!(tb->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint))) continue; @@ -796,14 +803,14 @@ QHash<QStyle::SubControl, QRect> QStyleSheetStyle::titleBarLayout(const QWidget info.rule = subRule; info.offset = offsets[where]; info.where = where; - infos.append(info); + infos.append(qMove(info)); offsets[where] += info.width; } } - for (int i = 0; i < infos.count(); i++) { - ButtonInfo info = infos[i]; + for (int i = 0; i < infos.size(); i++) { + const ButtonInfo &info = infos[i]; QRect lr = cr; switch (info.where) { case Center: { diff --git a/src/widgets/styles/qwindowsstyle_p_p.h b/src/widgets/styles/qwindowsstyle_p_p.h index 3d1206b3695b242a27cab8af0d950c815edd7a9b..c8778cc9149bafe25b5b3ee37bed5ceba7d605ab 100644 --- a/src/widgets/styles/qwindowsstyle_p_p.h +++ b/src/widgets/styles/qwindowsstyle_p_p.h @@ -65,7 +65,7 @@ public: static int pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0); static int fixedPixelMetric(QStyle::PixelMetric pm); static int devicePixelRatio(const QWidget *widget = 0) - { return widget ? widget->devicePixelRatio() : QWindowsStylePrivate::appDevicePixelRatio(); } + { return widget ? int(widget->devicePixelRatioF()) : QWindowsStylePrivate::appDevicePixelRatio(); } bool hasSeenAlt(const QWidget *widget) const; bool altDown() const { return alt_down; } diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index daa8ab12a9198ff052cf95413911a97629266e97..b8ed82fee3fe781b8556a12e528748fecadbe9d2 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -396,7 +396,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt case PE_IndicatorBranch: { - XPThemeData theme(0, painter, QWindowsXPStylePrivate::TreeViewTheme); + XPThemeData theme(widget, painter, QWindowsXPStylePrivate::TreeViewTheme); static int decoration_size = 0; if (d->initTreeViewTheming() && theme.isValid() && !decoration_size) { XPThemeData themeSize = theme; @@ -657,6 +657,8 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt newStyle = !qobject_cast<const QTableView*>(view); selectionBehavior = view->selectionBehavior(); selectionMode = view->selectionMode(); + } else if (!widget) { + newStyle = !QStyleHelper::hasAncestor(option->styleObject, QAccessible::MenuItem) ; } if (newStyle && (vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option))) { @@ -710,7 +712,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt state = LISS_HOT; QPainter pixmapPainter(&pixmap); - XPThemeData theme(0, &pixmapPainter, + XPThemeData theme(widget, &pixmapPainter, QWindowsXPStylePrivate::TreeViewTheme, LVP_LISTITEM, state, QRect(0, 0, sectionSize.width(), sectionSize.height())); if (d->initTreeViewTheming() && theme.isValid()) { diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index 54271c5ce8367760a1a70ffea144e194b61225e9..7776773b871359bc55ffe5c7fdfc3d75eec81b57 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -1224,7 +1224,7 @@ void QWindowsXPStyle::polish(QWidget *widget) if (!d->hasInitColors) { // Get text color for group box labels COLORREF cref; - XPThemeData theme(0, 0, QWindowsXPStylePrivate::ButtonTheme, 0, 0); + XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, 0, 0); QWindowsXPStylePrivate::pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, &cref); d->groupBoxTextColor = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref)); QWindowsXPStylePrivate::pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_DISABLED, TMT_TEXTCOLOR, &cref); @@ -1540,7 +1540,7 @@ case PE_Frame: return; themeNumber = QWindowsXPStylePrivate::ListViewTheme; partId = LVP_LISTGROUP; - XPThemeData theme(0, 0, themeNumber, partId, 0); + XPThemeData theme(widget, 0, themeNumber, partId, 0); if (!(flags & State_Enabled)) stateId = ETS_DISABLED; diff --git a/src/widgets/util/qcompleter.h b/src/widgets/util/qcompleter.h index 22230fc39eb0e61237f1b300f989bb2e91f2b907..32ee6296ca810810e812c54f765ccb73d325a199 100644 --- a/src/widgets/util/qcompleter.h +++ b/src/widgets/util/qcompleter.h @@ -76,10 +76,10 @@ public: CaseInsensitivelySortedModel }; - QCompleter(QObject *parent = 0); - QCompleter(QAbstractItemModel *model, QObject *parent = 0); + QCompleter(QObject *parent = Q_NULLPTR); + QCompleter(QAbstractItemModel *model, QObject *parent = Q_NULLPTR); #ifndef QT_NO_STRINGLISTMODEL - QCompleter(const QStringList& completions, QObject *parent = 0); + QCompleter(const QStringList& completions, QObject *parent = Q_NULLPTR); #endif ~QCompleter(); diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp index e3ac7348e74fe1a4bbcb881746bd73eb73c47d30..de12983f21bc3c5d67200d159728b706d7d684c2 100644 --- a/src/widgets/util/qscroller.cpp +++ b/src/widgets/util/qscroller.cpp @@ -558,7 +558,7 @@ void QScroller::stop() \note Please note that this value should be physically correct. The actual DPI settings that Qt returns for the display may be reported wrongly on purpose by the underlying - windowing system, for example on Mac OS X. + windowing system, for example on OS X. */ QPointF QScroller::pixelPerMeter() const { diff --git a/src/widgets/util/qscroller_p.h b/src/widgets/util/qscroller_p.h index bb00c12905de1d44aab766c9a38d5e2218c75420..d09f78d130045617eb6f29a21c39d39d981ff158 100644 --- a/src/widgets/util/qscroller_p.h +++ b/src/widgets/util/qscroller_p.h @@ -196,6 +196,9 @@ public: QScroller *q_ptr; }; +template <> +class QTypeInfo<QScrollerPrivate::ScrollSegment> + : public QTypeInfoMerger<QScrollerPrivate::ScrollSegment, QEasingCurve> {}; QT_END_NAMESPACE diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index dc2737cbf83fa8a8569414d4d31272ff76e3f9da..358e4c38d622dc95c86a2e810df323ed55d5233e 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -76,7 +76,7 @@ QT_BEGIN_NAMESPACE \li All X11 desktop environments that implement the D-Bus \l{http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/ StatusNotifierItem} specification, including recent versions of KDE and Unity. - \li All supported versions of Mac OS X. Note that the Growl + \li All supported versions of OS X. Note that the Growl notification system must be installed for QSystemTrayIcon::showMessage() to display messages on Mac OS X prior to 10.8 (Mountain Lion). \endlist @@ -157,7 +157,7 @@ QSystemTrayIcon::~QSystemTrayIcon() The menu will pop up when the user requests the context menu for the system tray icon by clicking the mouse button. - On Mac OS X, this is currenly converted to a NSMenu, so the + On OS X, this is currenly converted to a NSMenu, so the aboutToHide() signal is not emitted. \note The system tray icon does not take ownership of the menu. You must @@ -323,7 +323,7 @@ bool QSystemTrayIcon::event(QEvent *e) This signal is emitted when the message displayed using showMessage() was clicked by the user. - Currently this signal is not sent on Mac OS X. + Currently this signal is not sent on OS X. \note We follow Microsoft Windows XP/Vista behavior, so the signal is also emitted when the user clicks on a tray icon with @@ -374,7 +374,7 @@ bool QSystemTrayIcon::supportsMessages() On Windows, the \a millisecondsTimeoutHint is usually ignored by the system when the application has focus. - On Mac OS X, the Growl notification system must be installed for this function to + On OS X, the Growl notification system must be installed for this function to display messages. Has been turned into a slot in Qt 5.2. diff --git a/src/widgets/util/qsystemtrayicon.h b/src/widgets/util/qsystemtrayicon.h index a4da0861e9cfc31df605091f74f50a3bb31b94a6..aba126b4fcfd76df93716539b6e8727fee1664b5 100644 --- a/src/widgets/util/qsystemtrayicon.h +++ b/src/widgets/util/qsystemtrayicon.h @@ -59,8 +59,8 @@ class Q_WIDGETS_EXPORT QSystemTrayIcon : public QObject Q_PROPERTY(bool visible READ isVisible WRITE setVisible DESIGNABLE false) public: - QSystemTrayIcon(QObject *parent = 0); - QSystemTrayIcon(const QIcon &icon, QObject *parent = 0); + QSystemTrayIcon(QObject *parent = Q_NULLPTR); + QSystemTrayIcon(const QIcon &icon, QObject *parent = Q_NULLPTR); ~QSystemTrayIcon(); enum ActivationReason { diff --git a/src/widgets/util/qundogroup.h b/src/widgets/util/qundogroup.h index ea4b226a188345ebc43d5a8bea90bbe799b3f0c3..ec6e67f4d32f27c699226ec65c0dd915ea306161 100644 --- a/src/widgets/util/qundogroup.h +++ b/src/widgets/util/qundogroup.h @@ -52,7 +52,7 @@ class Q_WIDGETS_EXPORT QUndoGroup : public QObject Q_DECLARE_PRIVATE(QUndoGroup) public: - explicit QUndoGroup(QObject *parent = 0); + explicit QUndoGroup(QObject *parent = Q_NULLPTR); ~QUndoGroup(); void addStack(QUndoStack *stack); diff --git a/src/widgets/util/qundostack.h b/src/widgets/util/qundostack.h index f6589da4ec382517ae03f154567aea5cfc1cc7ed..0b14a442c20d3112c95a6324bd9efb5186edb478 100644 --- a/src/widgets/util/qundostack.h +++ b/src/widgets/util/qundostack.h @@ -51,8 +51,8 @@ class Q_WIDGETS_EXPORT QUndoCommand QUndoCommandPrivate *d; public: - explicit QUndoCommand(QUndoCommand *parent = 0); - explicit QUndoCommand(const QString &text, QUndoCommand *parent = 0); + explicit QUndoCommand(QUndoCommand *parent = Q_NULLPTR); + explicit QUndoCommand(const QString &text, QUndoCommand *parent = Q_NULLPTR); virtual ~QUndoCommand(); virtual void undo(); @@ -85,7 +85,7 @@ class Q_WIDGETS_EXPORT QUndoStack : public QObject Q_PROPERTY(int undoLimit READ undoLimit WRITE setUndoLimit) public: - explicit QUndoStack(QObject *parent = 0); + explicit QUndoStack(QObject *parent = Q_NULLPTR); ~QUndoStack(); void clear(); diff --git a/src/widgets/util/qundoview.h b/src/widgets/util/qundoview.h index a239d9b38e71bf833dcc91c0f869e6650f3d9ce2..2a15207ca522213a8c90e3f1973b707d3e7d2efa 100644 --- a/src/widgets/util/qundoview.h +++ b/src/widgets/util/qundoview.h @@ -55,10 +55,10 @@ class Q_WIDGETS_EXPORT QUndoView : public QListView Q_PROPERTY(QIcon cleanIcon READ cleanIcon WRITE setCleanIcon) public: - explicit QUndoView(QWidget *parent = 0); - explicit QUndoView(QUndoStack *stack, QWidget *parent = 0); + explicit QUndoView(QWidget *parent = Q_NULLPTR); + explicit QUndoView(QUndoStack *stack, QWidget *parent = Q_NULLPTR); #ifndef QT_NO_UNDOGROUP - explicit QUndoView(QUndoGroup *group, QWidget *parent = 0); + explicit QUndoView(QUndoGroup *group, QWidget *parent = Q_NULLPTR); #endif ~QUndoView(); diff --git a/src/widgets/util/util.pri b/src/widgets/util/util.pri index b4bbc5fc30f8552aaebfc207b64a4b1e2ef192c2..9f43dc42f09c3c36a8e79421eded397b2d346352 100644 --- a/src/widgets/util/util.pri +++ b/src/widgets/util/util.pri @@ -27,7 +27,7 @@ SOURCES += \ util/qundostack.cpp \ util/qundoview.cpp -win32:!wince*:!winrt { +win32:!wince:!winrt { SOURCES += util/qsystemtrayicon_win.cpp } else:contains(QT_CONFIG, xcb) { SOURCES += util/qsystemtrayicon_x11.cpp diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro index d819436f662ca33145bddb684522e20547580f6c..ceb6f96f7cf8c46a3d67f67f08cde3dadc294db1 100644 --- a/src/widgets/widgets.pro +++ b/src/widgets/widgets.pro @@ -1,5 +1,5 @@ TARGET = QtWidgets -wince*:ORIG_TARGET = $$TARGET +wince: ORIG_TARGET = $$TARGET QT = core-private gui-private MODULE_CONFIG = uic diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp index e413b3b87ae1f5f6a5c919114db4e4e6d730ff7d..292bbc3325e3f8a72b7f89c8bf7d6048685baa31 100644 --- a/src/widgets/widgets/qabstractbutton.cpp +++ b/src/widgets/widgets/qabstractbutton.cpp @@ -221,13 +221,12 @@ void QButtonGroup::addButton(QAbstractButton *button, int id) button->d_func()->group = this; d->buttonList.append(button); if (id == -1) { - QList<int> ids = d->mapping.values(); - if (ids.isEmpty()) - d->mapping[button] = -2; - else { - std::sort(ids.begin(), ids.end()); - d->mapping[button] = ids.first()-1; - } + const QHash<QAbstractButton*, int>::const_iterator it + = std::min_element(d->mapping.cbegin(), d->mapping.cend()); + if (it == d->mapping.cend()) + d->mapping[button] = -2; + else + d->mapping[button] = *it - 1; } else { d->mapping[button] = id; } diff --git a/src/widgets/widgets/qabstractbutton.h b/src/widgets/widgets/qabstractbutton.h index 4b397e2396715ffbb54eb0de19e263fbc60b526d..5f3e82a2e6696122803cf4cb7b17270e9dcd3d4a 100644 --- a/src/widgets/widgets/qabstractbutton.h +++ b/src/widgets/widgets/qabstractbutton.h @@ -63,7 +63,7 @@ class Q_WIDGETS_EXPORT QAbstractButton : public QWidget Q_PROPERTY(bool down READ isDown WRITE setDown DESIGNABLE false) public: - explicit QAbstractButton(QWidget* parent=0); + explicit QAbstractButton(QWidget *parent = Q_NULLPTR); ~QAbstractButton(); void setText(const QString &text); @@ -135,7 +135,7 @@ protected: protected: - QAbstractButton(QAbstractButtonPrivate &dd, QWidget* parent = 0); + QAbstractButton(QAbstractButtonPrivate &dd, QWidget* parent = Q_NULLPTR); private: Q_DECLARE_PRIVATE(QAbstractButton) diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp index 5e45c66f3b145842272f6479fc939a6cc8a0ccd7..65d06eafc5b8816108536fbdc9dfae5e1881b746 100644 --- a/src/widgets/widgets/qabstractscrollarea.cpp +++ b/src/widgets/widgets/qabstractscrollarea.cpp @@ -210,10 +210,12 @@ QWidgetList QAbstractScrollAreaScrollBarContainer::widgets(LogicalPosition posit QWidgetList list; const int scrollBarIndex = scrollBarLayoutIndex(); if (position == LogicalLeft) { + list.reserve(scrollBarIndex); for (int i = 0; i < scrollBarIndex; ++i) list.append(layout->itemAt(i)->widget()); } else if (position == LogicalRight) { const int layoutItemCount = layout->count(); + list.reserve(layoutItemCount - (scrollBarIndex + 1)); for (int i = scrollBarIndex + 1; i < layoutItemCount; ++i) list.append(layout->itemAt(i)->widget()); } diff --git a/src/widgets/widgets/qabstractscrollarea.h b/src/widgets/widgets/qabstractscrollarea.h index 13dafd547b447d3003636dc46f53108dd2dfa1a3..8bc32b1c7827ccdc2893cb00f9237712ab83e554 100644 --- a/src/widgets/widgets/qabstractscrollarea.h +++ b/src/widgets/widgets/qabstractscrollarea.h @@ -54,7 +54,7 @@ class Q_WIDGETS_EXPORT QAbstractScrollArea : public QFrame Q_PROPERTY(SizeAdjustPolicy sizeAdjustPolicy READ sizeAdjustPolicy WRITE setSizeAdjustPolicy) public: - explicit QAbstractScrollArea(QWidget* parent=0); + explicit QAbstractScrollArea(QWidget *parent = Q_NULLPTR); ~QAbstractScrollArea(); enum SizeAdjustPolicy { @@ -94,7 +94,7 @@ public: void setSizeAdjustPolicy(SizeAdjustPolicy policy); protected: - QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent = 0); + QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent = Q_NULLPTR); void setViewportMargins(int left, int top, int right, int bottom); void setViewportMargins(const QMargins &margins); QMargins viewportMargins() const; diff --git a/src/widgets/widgets/qabstractslider.h b/src/widgets/widgets/qabstractslider.h index 2f649e3d3daa3c274da16f0d484228b3c2c63b38..6faca5ea3c940f9c5d506903217370108265ce49 100644 --- a/src/widgets/widgets/qabstractslider.h +++ b/src/widgets/widgets/qabstractslider.h @@ -58,7 +58,7 @@ class Q_WIDGETS_EXPORT QAbstractSlider : public QWidget Q_PROPERTY(bool sliderDown READ isSliderDown WRITE setSliderDown DESIGNABLE false) public: - explicit QAbstractSlider(QWidget *parent=0); + explicit QAbstractSlider(QWidget *parent = Q_NULLPTR); ~QAbstractSlider(); Qt::Orientation orientation() const; @@ -144,7 +144,7 @@ protected: protected: - QAbstractSlider(QAbstractSliderPrivate &dd, QWidget *parent=0); + QAbstractSlider(QAbstractSliderPrivate &dd, QWidget *parent = Q_NULLPTR); private: Q_DISABLE_COPY(QAbstractSlider) diff --git a/src/widgets/widgets/qabstractspinbox.h b/src/widgets/widgets/qabstractspinbox.h index a80a89c8948469b9f5c41539673a2b3fdc212861..046036b9a8f05593c7f2b66eaa173232d69430e2 100644 --- a/src/widgets/widgets/qabstractspinbox.h +++ b/src/widgets/widgets/qabstractspinbox.h @@ -64,7 +64,7 @@ class Q_WIDGETS_EXPORT QAbstractSpinBox : public QWidget Q_PROPERTY(bool keyboardTracking READ keyboardTracking WRITE setKeyboardTracking) Q_PROPERTY(bool showGroupSeparator READ isGroupSeparatorShown WRITE setGroupSeparatorShown) public: - explicit QAbstractSpinBox(QWidget *parent = 0); + explicit QAbstractSpinBox(QWidget *parent = Q_NULLPTR); ~QAbstractSpinBox(); enum StepEnabledFlag { StepNone = 0x00, StepUpEnabled = 0x01, @@ -154,7 +154,7 @@ protected: Q_SIGNALS: void editingFinished(); protected: - QAbstractSpinBox(QAbstractSpinBoxPrivate &dd, QWidget *parent = 0); + QAbstractSpinBox(QAbstractSpinBoxPrivate &dd, QWidget *parent = Q_NULLPTR); private: Q_PRIVATE_SLOT(d_func(), void _q_editorTextChanged(const QString &)) diff --git a/src/widgets/widgets/qbuttongroup.h b/src/widgets/widgets/qbuttongroup.h index 01de03ac848714d22e8008fcff25869f56b6bfac..ba4f8e26c127c50664dab6cf324091c5db2abdb0 100644 --- a/src/widgets/widgets/qbuttongroup.h +++ b/src/widgets/widgets/qbuttongroup.h @@ -51,7 +51,7 @@ class Q_WIDGETS_EXPORT QButtonGroup : public QObject Q_PROPERTY(bool exclusive READ exclusive WRITE setExclusive) public: - explicit QButtonGroup(QObject *parent = 0); + explicit QButtonGroup(QObject *parent = Q_NULLPTR); ~QButtonGroup(); void setExclusive(bool); diff --git a/src/widgets/widgets/qcalendarwidget.h b/src/widgets/widgets/qcalendarwidget.h index c456cc2161b6f81c623dd94c4a027a6246cc91b8..df54985351eda6b008169749d7318c7995976bc7 100644 --- a/src/widgets/widgets/qcalendarwidget.h +++ b/src/widgets/widgets/qcalendarwidget.h @@ -83,7 +83,7 @@ public: }; Q_ENUM(SelectionMode) - explicit QCalendarWidget(QWidget *parent = 0); + explicit QCalendarWidget(QWidget *parent = Q_NULLPTR); ~QCalendarWidget(); virtual QSize sizeHint() const Q_DECL_OVERRIDE; diff --git a/src/widgets/widgets/qcheckbox.h b/src/widgets/widgets/qcheckbox.h index b614659f02c6ce87b5cf7c81940494fb7ed6426c..61d03eb8e66aad1b32be84afb6f3a8556a8ea3db 100644 --- a/src/widgets/widgets/qcheckbox.h +++ b/src/widgets/widgets/qcheckbox.h @@ -49,8 +49,8 @@ class Q_WIDGETS_EXPORT QCheckBox : public QAbstractButton Q_PROPERTY(bool tristate READ isTristate WRITE setTristate) public: - explicit QCheckBox(QWidget *parent=0); - explicit QCheckBox(const QString &text, QWidget *parent=0); + explicit QCheckBox(QWidget *parent = Q_NULLPTR); + explicit QCheckBox(const QString &text, QWidget *parent = Q_NULLPTR); ~QCheckBox(); QSize sizeHint() const Q_DECL_OVERRIDE; diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index ef80e359df2780f0409b67e7287b8c8361c5c2de..2958d662c719240a2b6ac24137676fcee8fb9f00 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -546,7 +546,8 @@ void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView) disconnect(view, SIGNAL(destroyed()), this, SLOT(viewDestroyed())); - delete view; + if (isAncestorOf(view)) + delete view; view = 0; } @@ -2092,8 +2093,10 @@ void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi) const QString newText = itemText(normalized); if (lineEdit->text() != newText) { lineEdit->setText(newText); +#ifndef QT_NO_COMPLETER if (lineEdit->completer()) lineEdit->completer()->setCompletionPrefix(newText); +#endif } updateLineEditGeometry(); } @@ -2263,6 +2266,7 @@ void QComboBox::insertItems(int index, const QStringList &list) // construct a QStandardItem, reducing the number of expensive signals from the model if (QStandardItemModel *m = qobject_cast<QStandardItemModel*>(d->model)) { QList<QStandardItem *> items; + items.reserve(insertCount); QStandardItem *hiddenRoot = m->invisibleRootItem(); for (int i = 0; i < insertCount; ++i) items.append(new QStandardItem(list.at(i))); @@ -2699,7 +2703,7 @@ void QComboBox::showPopup() qScrollEffect(container, scrollDown ? QEffects::DownScroll : QEffects::UpScroll, 150); #endif -// Don't disable updates on Mac OS X. Windows are displayed immediately on this platform, +// Don't disable updates on OS X. Windows are displayed immediately on this platform, // which means that the window will be visible before the call to container->show() returns. // If updates are disabled at this point we'll miss our chance at painting the popup // menu before it's shown, causing flicker since the window then displays the standard gray diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h index ae35f7a89af80726c6e88a28ef2503eeac790c78..3182a0a3aa3ed02533d5615b521e648102dc46da 100644 --- a/src/widgets/widgets/qcombobox.h +++ b/src/widgets/widgets/qcombobox.h @@ -74,7 +74,7 @@ class Q_WIDGETS_EXPORT QComboBox : public QWidget Q_PROPERTY(int modelColumn READ modelColumn WRITE setModelColumn) public: - explicit QComboBox(QWidget *parent = 0); + explicit QComboBox(QWidget *parent = Q_NULLPTR); ~QComboBox(); int maxVisibleItems() const; diff --git a/src/widgets/widgets/qcommandlinkbutton.h b/src/widgets/widgets/qcommandlinkbutton.h index 486c48af5d91467c67f681eedda6fdca42c452c0..9ddb14270dfd21957b8b85da426fc87c18d2004a 100644 --- a/src/widgets/widgets/qcommandlinkbutton.h +++ b/src/widgets/widgets/qcommandlinkbutton.h @@ -49,9 +49,9 @@ class Q_WIDGETS_EXPORT QCommandLinkButton: public QPushButton Q_PROPERTY(bool flat READ isFlat WRITE setFlat DESIGNABLE false) public: - explicit QCommandLinkButton(QWidget *parent=0); - explicit QCommandLinkButton(const QString &text, QWidget *parent=0); - explicit QCommandLinkButton(const QString &text, const QString &description, QWidget *parent=0); + explicit QCommandLinkButton(QWidget *parent = Q_NULLPTR); + explicit QCommandLinkButton(const QString &text, QWidget *parent = Q_NULLPTR); + explicit QCommandLinkButton(const QString &text, const QString &description, QWidget *parent = Q_NULLPTR); ~QCommandLinkButton(); QString description() const; diff --git a/src/widgets/widgets/qdatetimeedit.h b/src/widgets/widgets/qdatetimeedit.h index 4e77713fd080c9530d0772fa8687b0e63f247260..829ce205be0628f164b2247ec2da68d0a190c306 100644 --- a/src/widgets/widgets/qdatetimeedit.h +++ b/src/widgets/widgets/qdatetimeedit.h @@ -86,10 +86,10 @@ public: Q_DECLARE_FLAGS(Sections, Section) - explicit QDateTimeEdit(QWidget *parent = 0); - explicit QDateTimeEdit(const QDateTime &dt, QWidget *parent = 0); - explicit QDateTimeEdit(const QDate &d, QWidget *parent = 0); - explicit QDateTimeEdit(const QTime &t, QWidget *parent = 0); + explicit QDateTimeEdit(QWidget *parent = Q_NULLPTR); + explicit QDateTimeEdit(const QDateTime &dt, QWidget *parent = Q_NULLPTR); + explicit QDateTimeEdit(const QDate &d, QWidget *parent = Q_NULLPTR); + explicit QDateTimeEdit(const QTime &t, QWidget *parent = Q_NULLPTR); ~QDateTimeEdit(); QDateTime dateTime() const; @@ -185,7 +185,7 @@ protected: virtual void paintEvent(QPaintEvent *event); void initStyleOption(QStyleOptionSpinBox *option) const; - QDateTimeEdit(const QVariant &val, QVariant::Type parserType, QWidget *parent = 0); + QDateTimeEdit(const QVariant &val, QVariant::Type parserType, QWidget *parent = Q_NULLPTR); private: Q_DECLARE_PRIVATE(QDateTimeEdit) Q_DISABLE_COPY(QDateTimeEdit) @@ -198,8 +198,8 @@ class Q_WIDGETS_EXPORT QTimeEdit : public QDateTimeEdit Q_OBJECT Q_PROPERTY(QTime time READ time WRITE setTime NOTIFY userTimeChanged USER true) public: - explicit QTimeEdit(QWidget *parent = 0); - explicit QTimeEdit(const QTime &time, QWidget *parent = 0); + explicit QTimeEdit(QWidget *parent = Q_NULLPTR); + explicit QTimeEdit(const QTime &time, QWidget *parent = Q_NULLPTR); ~QTimeEdit(); Q_SIGNALS: @@ -211,8 +211,8 @@ class Q_WIDGETS_EXPORT QDateEdit : public QDateTimeEdit Q_OBJECT Q_PROPERTY(QDate date READ date WRITE setDate NOTIFY userDateChanged USER true) public: - explicit QDateEdit(QWidget *parent = 0); - explicit QDateEdit(const QDate &date, QWidget *parent = 0); + explicit QDateEdit(QWidget *parent = Q_NULLPTR); + explicit QDateEdit(const QDate &date, QWidget *parent = Q_NULLPTR); ~QDateEdit(); Q_SIGNALS: diff --git a/src/widgets/widgets/qdial.cpp b/src/widgets/widgets/qdial.cpp index b6ec54997b66a40746a9049b3bd62be228669faf..3f081e3a83a996d6a7201dfdb94e7b9eb4b3bd5b 100644 --- a/src/widgets/widgets/qdial.cpp +++ b/src/widgets/widgets/qdial.cpp @@ -202,9 +202,8 @@ int QDialPrivate::valueFromPoint(const QPoint &p) const to draw every one, QDial will skip notches to try and draw a uniform set (e.g. by drawing every second or third notch). - Like the slider, the dial makes the QAbstractSlider functions - setValue(), addLine(), subtractLine(), addPage() and - subtractPage() available as slots. + Like the slider, the dial makes the QAbstractSlider function setValue() + available as a slot. The dial's keyboard interface is fairly simple: The \uicontrol{left}/\uicontrol{up} and \uicontrol{right}/\uicontrol{down} arrow keys adjust diff --git a/src/widgets/widgets/qdial.h b/src/widgets/widgets/qdial.h index 7e01aefce3752c798aaa0a8633addece42fa368a..cb69e02301891593cf3efe0145ba9125bc86f985 100644 --- a/src/widgets/widgets/qdial.h +++ b/src/widgets/widgets/qdial.h @@ -54,7 +54,7 @@ class Q_WIDGETS_EXPORT QDial: public QAbstractSlider Q_PROPERTY(qreal notchTarget READ notchTarget WRITE setNotchTarget) Q_PROPERTY(bool notchesVisible READ notchesVisible WRITE setNotchesVisible) public: - explicit QDial(QWidget *parent = 0); + explicit QDial(QWidget *parent = Q_NULLPTR); ~QDial(); diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp index 3e8c08f923c170886055ef2a5972993575f4cc2a..5b6bfb3b3c91b1a12ff515fde9263fe0d58ed18d 100644 --- a/src/widgets/widgets/qdialogbuttonbox.cpp +++ b/src/widgets/widgets/qdialogbuttonbox.cpp @@ -118,7 +118,7 @@ QT_BEGIN_NAMESPACE \endtable Additionally, button boxes that contain only buttons with ActionRole or - HelpRole can be considered modeless and have an alternate look on Mac OS X: + HelpRole can be considered modeless and have an alternate look on OS X: \table \row \li modeless horizontal MacLayout @@ -583,7 +583,7 @@ QDialogButtonBox::~QDialogButtonBox() contained in the button box. \value WinLayout Use a policy appropriate for applications on Windows. - \value MacLayout Use a policy appropriate for applications on Mac OS X. + \value MacLayout Use a policy appropriate for applications on OS X. \value KdeLayout Use a policy appropriate for applications on KDE. \value GnomeLayout Use a policy appropriate for applications on GNOME. diff --git a/src/widgets/widgets/qdialogbuttonbox.h b/src/widgets/widgets/qdialogbuttonbox.h index 02960b5b794ad7a1af039b64d1269540d1dca01e..83c1fd66fdce4287c93bee1d7ad81381f42a175e 100644 --- a/src/widgets/widgets/qdialogbuttonbox.h +++ b/src/widgets/widgets/qdialogbuttonbox.h @@ -106,11 +106,11 @@ public: GnomeLayout }; - QDialogButtonBox(QWidget *parent = 0); - QDialogButtonBox(Qt::Orientation orientation, QWidget *parent = 0); - explicit QDialogButtonBox(StandardButtons buttons, QWidget *parent = 0); + QDialogButtonBox(QWidget *parent = Q_NULLPTR); + QDialogButtonBox(Qt::Orientation orientation, QWidget *parent = Q_NULLPTR); + explicit QDialogButtonBox(StandardButtons buttons, QWidget *parent = Q_NULLPTR); QDialogButtonBox(StandardButtons buttons, Qt::Orientation orientation, - QWidget *parent = 0); + QWidget *parent = Q_NULLPTR); ~QDialogButtonBox(); void setOrientation(Qt::Orientation orientation); diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index bc2259ce909cf982bd575ea2669f68b271308763..c61984a457583f47b0c2fd9ecaab46d02bd207b6 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -1018,7 +1018,7 @@ QLayoutItem *QDockAreaLayoutInfo::plug(const QList<int> &path) index = -index - 1; if (path.count() > 1) { - const QDockAreaLayoutItem &item = item_list.at(index); + QDockAreaLayoutItem &item = item_list[index]; Q_ASSERT(item.subinfo != 0); return item.subinfo->plug(path.mid(1)); } @@ -1064,7 +1064,7 @@ QLayoutItem *QDockAreaLayoutInfo::unplug(const QList<int> &path) const int index = path.first(); if (path.count() > 1) { - const QDockAreaLayoutItem &item = item_list.at(index); + QDockAreaLayoutItem &item = item_list[index]; Q_ASSERT(item.subinfo != 0); return item.subinfo->unplug(path.mid(1)); } @@ -2211,8 +2211,10 @@ QSet<QTabBar*> QDockAreaLayoutInfo::usedTabBars() const QSet<QWidget*> QDockAreaLayoutInfo::usedSeparatorWidgets() const { QSet<QWidget*> result; + const int numSeparatorWidgets = separatorWidgets.count(); + result.reserve(numSeparatorWidgets); - for (int i = 0; i < separatorWidgets.count(); ++i) + for (int i = 0; i < numSeparatorWidgets; ++i) result << separatorWidgets.at(i); for (int i = 0; i < item_list.count(); ++i) { diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index 1b7473fbd72f0087c7544fe9752ffbc612a36206..6ea92e4c4d3c45878d6bdcdfdc95aaf9ea5f3343 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -760,7 +760,11 @@ void QDockWidgetPrivate::startDrag(bool group) QMainWindow::addDockWidget, so the QMainWindowLayout has no widget item for me. :( I have to create it myself, and then delete it if I don't get dropped into a dock area. */ - state->widgetItem = new QDockWidgetItem(q); + QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent); + if (floatingTab && !q->isFloating()) + state->widgetItem = new QDockWidgetGroupWindowItem(floatingTab); + else + state->widgetItem = new QDockWidgetItem(q); state->ownWidgetItem = true; } diff --git a/src/widgets/widgets/qdockwidget.h b/src/widgets/widgets/qdockwidget.h index af4a5521bf8996c690b1befc2d0ff46cac363b81..25e4d4d0a41aa79dcaf749d584ea3dca828089fe 100644 --- a/src/widgets/widgets/qdockwidget.h +++ b/src/widgets/widgets/qdockwidget.h @@ -58,8 +58,9 @@ class Q_WIDGETS_EXPORT QDockWidget : public QWidget Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle DESIGNABLE true) public: - explicit QDockWidget(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0); - explicit QDockWidget(QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit QDockWidget(const QString &title, QWidget *parent = Q_NULLPTR, + Qt::WindowFlags flags = Qt::WindowFlags()); + explicit QDockWidget(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); ~QDockWidget(); QWidget *widget() const; diff --git a/src/widgets/widgets/qfocusframe.h b/src/widgets/widgets/qfocusframe.h index f976ba9827e57d3f6372f57b827d9c3ce38e9225..bbd639c2f9f643d1b762b8606c79b38d5bf9d5a3 100644 --- a/src/widgets/widgets/qfocusframe.h +++ b/src/widgets/widgets/qfocusframe.h @@ -46,7 +46,7 @@ class Q_WIDGETS_EXPORT QFocusFrame : public QWidget { Q_OBJECT public: - QFocusFrame(QWidget *parent=0); + QFocusFrame(QWidget *parent = Q_NULLPTR); ~QFocusFrame(); void setWidget(QWidget *widget); diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp index faa2f41a5110e727bb8c99a39b0a38c93ec54f78..957d148c74016b0fca99eac55f157bdb55ce11d9 100644 --- a/src/widgets/widgets/qfontcombobox.cpp +++ b/src/widgets/widgets/qfontcombobox.cpp @@ -400,14 +400,6 @@ void QFontComboBoxPrivate::_q_currentChanged(const QString &text) \sa QComboBox, QFont, QFontInfo, QFontMetrics, QFontDatabase, {Character Map Example} */ -/*! - \fn void QFontComboBox::setWritingSystem(QFontDatabase::WritingSystem script) -*/ - -/*! - \fn void QFontComboBox::setCurrentFont(const QFont &font); -*/ - /*! Constructs a font combobox with the given \a parent. */ diff --git a/src/widgets/widgets/qfontcombobox.h b/src/widgets/widgets/qfontcombobox.h index 0c8cf5d58dd703a0bc4dbe0a3a3d7090525d897c..412acd041eb66ac3a8734bfd96f953c2e07dba05 100644 --- a/src/widgets/widgets/qfontcombobox.h +++ b/src/widgets/widgets/qfontcombobox.h @@ -53,7 +53,7 @@ class Q_WIDGETS_EXPORT QFontComboBox : public QComboBox Q_PROPERTY(QFont currentFont READ currentFont WRITE setCurrentFont NOTIFY currentFontChanged) public: - explicit QFontComboBox(QWidget *parent = 0); + explicit QFontComboBox(QWidget *parent = Q_NULLPTR); ~QFontComboBox(); void setWritingSystem(QFontDatabase::WritingSystem); diff --git a/src/widgets/widgets/qframe.h b/src/widgets/widgets/qframe.h index c32e38f311e769361f657ce2b13f6a2651b38306..eb4d74c72a42b7f648556c7bf7756244e8be0bff 100644 --- a/src/widgets/widgets/qframe.h +++ b/src/widgets/widgets/qframe.h @@ -54,7 +54,7 @@ class Q_WIDGETS_EXPORT QFrame : public QWidget Q_PROPERTY(QRect frameRect READ frameRect WRITE setFrameRect DESIGNABLE false) public: - explicit QFrame(QWidget* parent = 0, Qt::WindowFlags f = 0); + explicit QFrame(QWidget* parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); ~QFrame(); int frameStyle() const; @@ -108,7 +108,7 @@ protected: protected: - QFrame(QFramePrivate &dd, QWidget* parent = 0, Qt::WindowFlags f = 0); + QFrame(QFramePrivate &dd, QWidget* parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); void initStyleOption(QStyleOptionFrame *option) const; private: diff --git a/src/widgets/widgets/qgroupbox.h b/src/widgets/widgets/qgroupbox.h index 8100fadff4881f1bd6b07bf2702f6b11d0de629d..57ebdce8dd2405e11124a6535fb10b3160c8ed41 100644 --- a/src/widgets/widgets/qgroupbox.h +++ b/src/widgets/widgets/qgroupbox.h @@ -53,8 +53,8 @@ class Q_WIDGETS_EXPORT QGroupBox : public QWidget Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable) Q_PROPERTY(bool checked READ isChecked WRITE setChecked DESIGNABLE isCheckable NOTIFY toggled USER true) public: - explicit QGroupBox(QWidget* parent=0); - explicit QGroupBox(const QString &title, QWidget* parent=0); + explicit QGroupBox(QWidget *parent = Q_NULLPTR); + explicit QGroupBox(const QString &title, QWidget *parent = Q_NULLPTR); ~QGroupBox(); QString title() const; diff --git a/src/widgets/widgets/qkeysequenceedit.h b/src/widgets/widgets/qkeysequenceedit.h index 1887a40bfcbfe176b7e25612ff0d5d8b0a5ea60c..ad60bcc5138001d6bb9b09c7395c47239eb96527 100644 --- a/src/widgets/widgets/qkeysequenceedit.h +++ b/src/widgets/widgets/qkeysequenceedit.h @@ -48,8 +48,8 @@ class Q_WIDGETS_EXPORT QKeySequenceEdit : public QWidget Q_PROPERTY(QKeySequence keySequence READ keySequence WRITE setKeySequence NOTIFY keySequenceChanged USER true) public: - explicit QKeySequenceEdit(QWidget *parent = 0); - explicit QKeySequenceEdit(const QKeySequence &keySequence, QWidget *parent = 0); + explicit QKeySequenceEdit(QWidget *parent = Q_NULLPTR); + explicit QKeySequenceEdit(const QKeySequence &keySequence, QWidget *parent = Q_NULLPTR); ~QKeySequenceEdit(); QKeySequence keySequence() const; diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index 409e4a34f9af126439a87ae4ca206434cdf8048c..55e277026c66934e3f758e0e2c6c2ae005e4e3ff 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -53,6 +53,50 @@ QT_BEGIN_NAMESPACE +QLabelPrivate::QLabelPrivate() + : QFramePrivate(), + sh(), + msh(), + text(), + pixmap(Q_NULLPTR), + scaledpixmap(Q_NULLPTR), + cachedimage(Q_NULLPTR), +#ifndef QT_NO_PICTURE + picture(Q_NULLPTR), +#endif +#ifndef QT_NO_MOVIE + movie(), +#endif + control(Q_NULLPTR), + shortcutCursor(), +#ifndef QT_NO_CURSOR + cursor(), +#endif +#ifndef QT_NO_SHORTCUT + buddy(), + shortcutId(0), +#endif + textformat(Qt::AutoText), + textInteractionFlags(Qt::LinksAccessibleByMouse), + sizePolicy(), + margin(0), + align(Qt::AlignLeft | Qt::AlignVCenter | Qt::TextExpandTabs), + indent(-1), + valid_hints(false), + scaledcontents(false), + textLayoutDirty(false), + textDirty(false), + isRichText(false), + isTextLabel(false), + hasShortcut(/*???*/), +#ifndef QT_NO_CURSOR + validCursor(false), + onAnchor(false), +#endif + openExternalLinks(false) +{ +} + QLabelPrivate::~QLabelPrivate() { } @@ -206,41 +250,8 @@ void QLabelPrivate::init() { Q_Q(QLabel); - valid_hints = false; - margin = 0; -#ifndef QT_NO_MOVIE - movie = 0; -#endif -#ifndef QT_NO_SHORTCUT - shortcutId = 0; -#endif - pixmap = 0; - scaledpixmap = 0; - cachedimage = 0; -#ifndef QT_NO_PICTURE - picture = 0; -#endif - align = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextExpandTabs; - indent = -1; - scaledcontents = false; - textLayoutDirty = false; - textDirty = false; - textformat = Qt::AutoText; - control = 0; - textInteractionFlags = Qt::LinksAccessibleByMouse; - isRichText = false; - isTextLabel = false; - q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::Label)); - -#ifndef QT_NO_CURSOR - validCursor = false; - onAnchor = false; -#endif - - openExternalLinks = false; - setLayoutItemMargins(QStyle::SE_LabelLayoutItem); } @@ -1085,7 +1096,7 @@ void QLabel::paintEvent(QPaintEvent *) d->cachedimage = new QImage(d->pixmap->toImage()); delete d->scaledpixmap; QImage scaledImage = - d->cachedimage->scaled(cr.size() * devicePixelRatio(), + d->cachedimage->scaled(cr.size() * devicePixelRatioF(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); d->scaledpixmap = new QPixmap(QPixmap::fromImage(scaledImage)); } diff --git a/src/widgets/widgets/qlabel.h b/src/widgets/widgets/qlabel.h index 330626a9c5dd1147578579b59a05e000524baeca..1a3a68db603ba0c7728fd4e709908d72cf8ed442 100644 --- a/src/widgets/widgets/qlabel.h +++ b/src/widgets/widgets/qlabel.h @@ -58,8 +58,8 @@ class Q_WIDGETS_EXPORT QLabel : public QFrame Q_PROPERTY(QString selectedText READ selectedText) public: - explicit QLabel(QWidget *parent=0, Qt::WindowFlags f=0); - explicit QLabel(const QString &text, QWidget *parent=0, Qt::WindowFlags f=0); + explicit QLabel(QWidget *parent=Q_NULLPTR, Qt::WindowFlags f=Qt::WindowFlags()); + explicit QLabel(const QString &text, QWidget *parent=Q_NULLPTR, Qt::WindowFlags f=Qt::WindowFlags()); ~QLabel(); QString text() const; diff --git a/src/widgets/widgets/qlabel_p.h b/src/widgets/widgets/qlabel_p.h index 2eb4ff9fc6ac0d7b343d1dea7efa9fdfaf8ca4b8..bd7a9d1e8fa25cd7ec9563c9bda16a28c100cbf8 100644 --- a/src/widgets/widgets/qlabel_p.h +++ b/src/widgets/widgets/qlabel_p.h @@ -64,7 +64,7 @@ class QLabelPrivate : public QFramePrivate { Q_DECLARE_PUBLIC(QLabel) public: - QLabelPrivate() {} + QLabelPrivate(); ~QLabelPrivate(); void init(); @@ -72,43 +72,13 @@ public: void updateLabel(); QSize sizeForWidth(int w) const; - mutable QSize sh; - mutable QSize msh; - mutable bool valid_hints; - mutable QSizePolicy sizePolicy; - int margin; - QString text; - QPixmap *pixmap; - QPixmap *scaledpixmap; - QImage *cachedimage; -#ifndef QT_NO_PICTURE - QPicture *picture; -#endif #ifndef QT_NO_MOVIE - QPointer<QMovie> movie; void _q_movieUpdated(const QRect&); void _q_movieResized(const QSize&); #endif #ifndef QT_NO_SHORTCUT void updateShortcut(); #endif -#ifndef QT_NO_SHORTCUT - QPointer<QWidget> buddy; - int shortcutId; -#endif - ushort align; - short indent; - uint scaledcontents :1; - mutable uint textLayoutDirty : 1; - mutable uint textDirty : 1; - mutable uint isRichText : 1; - mutable uint isTextLabel : 1; - mutable uint hasShortcut : 1; - Qt::TextFormat textformat; - mutable QWidgetTextControl *control; - mutable QTextCursor shortcutCursor; - Qt::TextInteractionFlags textInteractionFlags; - inline bool needTextControl() const { return isTextLabel && (isRichText @@ -130,13 +100,46 @@ public: QMenu *createStandardContextMenu(const QPoint &pos); #endif - bool openExternalLinks; - + mutable QSize sh; + mutable QSize msh; + QString text; + QPixmap *pixmap; + QPixmap *scaledpixmap; + QImage *cachedimage; +#ifndef QT_NO_PICTURE + QPicture *picture; +#endif +#ifndef QT_NO_MOVIE + QPointer<QMovie> movie; +#endif + mutable QWidgetTextControl *control; + mutable QTextCursor shortcutCursor; +#ifndef QT_NO_CURSOR + QCursor cursor; +#endif +#ifndef QT_NO_SHORTCUT + QPointer<QWidget> buddy; + int shortcutId; +#endif + Qt::TextFormat textformat; + Qt::TextInteractionFlags textInteractionFlags; + mutable QSizePolicy sizePolicy; + int margin; + ushort align; + short indent; + mutable uint valid_hints : 1; + uint scaledcontents : 1; + mutable uint textLayoutDirty : 1; + mutable uint textDirty : 1; + mutable uint isRichText : 1; + mutable uint isTextLabel : 1; + mutable uint hasShortcut : 1; #ifndef QT_NO_CURSOR uint validCursor : 1; uint onAnchor : 1; - QCursor cursor; #endif + uint openExternalLinks : 1; + // <-- space for more bit field values here friend class QMessageBoxPrivate; }; diff --git a/src/widgets/widgets/qlcdnumber.h b/src/widgets/widgets/qlcdnumber.h index d93edc75ca306814fbef378d5ecf357c204719aa..9a7904a8bb93a93b283a7b19e78e9b6903cd7323 100644 --- a/src/widgets/widgets/qlcdnumber.h +++ b/src/widgets/widgets/qlcdnumber.h @@ -53,8 +53,8 @@ class Q_WIDGETS_EXPORT QLCDNumber : public QFrame // LCD number widget Q_PROPERTY(int intValue READ intValue WRITE display) public: - explicit QLCDNumber(QWidget* parent = 0); - explicit QLCDNumber(uint numDigits, QWidget* parent = 0); + explicit QLCDNumber(QWidget* parent = Q_NULLPTR); + explicit QLCDNumber(uint numDigits, QWidget* parent = Q_NULLPTR); ~QLCDNumber(); enum Mode { diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h index e006f1c0d8021bdc9f6b51c966eefc5762cb417b..ac192f0da83d1dfe0cec71ebb2c606865294c0bb 100644 --- a/src/widgets/widgets/qlineedit.h +++ b/src/widgets/widgets/qlineedit.h @@ -84,8 +84,8 @@ public: }; Q_ENUM(ActionPosition) - explicit QLineEdit(QWidget* parent=0); - explicit QLineEdit(const QString &, QWidget* parent=0); + explicit QLineEdit(QWidget *parent = Q_NULLPTR); + explicit QLineEdit(const QString &, QWidget *parent = Q_NULLPTR); ~QLineEdit(); QString text() const; diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index 4654262ea736ed3887d6bddb8ab916aa37d2e97e..57055757ebdea4f73f5b55190da685449feaf52c 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -111,7 +111,7 @@ public: QAction *action; int flags; }; - typedef QList<SideWidgetEntry> SideWidgetEntryList; + typedef QVector<SideWidgetEntry> SideWidgetEntryList; QLineEditPrivate() : control(0), frame(1), contextMenuEnabled(1), cursorVisible(0), @@ -225,6 +225,7 @@ private: int lastTextSize; mutable QSize m_iconSize; }; +Q_DECLARE_TYPEINFO(QLineEditPrivate::SideWidgetEntry, Q_PRIMITIVE_TYPE); inline int QLineEditPrivate::effectiveLeftTextMargin() const { diff --git a/src/widgets/widgets/qmaccocoaviewcontainer_mac.h b/src/widgets/widgets/qmaccocoaviewcontainer_mac.h index 5920c1f8bf0eb7a6b585f503bc4892f507f3fb20..a27d8f8690e523ee5d01f2ec4b38445748ea280d 100644 --- a/src/widgets/widgets/qmaccocoaviewcontainer_mac.h +++ b/src/widgets/widgets/qmaccocoaviewcontainer_mac.h @@ -45,7 +45,7 @@ class Q_WIDGETS_EXPORT QMacCocoaViewContainer : public QWidget { Q_OBJECT public: - QMacCocoaViewContainer(NSView *cocoaViewToWrap, QWidget *parent = 0); + QMacCocoaViewContainer(NSView *cocoaViewToWrap, QWidget *parent = Q_NULLPTR); virtual ~QMacCocoaViewContainer(); void setCocoaView(NSView *view); diff --git a/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm b/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm index 5a02be7ee18a4ef4be29e06e8763591571794a10..a384e41d1ba6ce357233ed59a64e101f1dcefdbc 100644 --- a/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm +++ b/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm @@ -43,7 +43,7 @@ \class QMacCocoaViewContainer \since 4.5 - \brief The QMacCocoaViewContainer class provides a widget for Mac OS X that can be used to wrap arbitrary + \brief The QMacCocoaViewContainer class provides a widget for OS X that can be used to wrap arbitrary Cocoa views (i.e., NSView subclasses) and insert them into Qt hierarchies. \ingroup advanced @@ -61,7 +61,7 @@ Cocoa. However, QCocoaContainerView requires Mac OS X 10.5 or better to be used with Carbon. - It should be also noted that at the low level on Mac OS X, there is a + It should be also noted that at the low level on OS X, there is a difference between windows (top-levels) and view (widgets that are inside a window). For this reason, make sure that the NSView that you are wrapping doesn't end up as a top-level. The best way to ensure this is to make sure diff --git a/src/widgets/widgets/qmacnativewidget_mac.h b/src/widgets/widgets/qmacnativewidget_mac.h index 761e55656b4cd8d159e1acf00b9e3f8ed625c26f..5e82872faa89e26686bf3709cb0678997a42c983 100644 --- a/src/widgets/widgets/qmacnativewidget_mac.h +++ b/src/widgets/widgets/qmacnativewidget_mac.h @@ -45,7 +45,7 @@ class Q_WIDGETS_EXPORT QMacNativeWidget : public QWidget { Q_OBJECT public: - QMacNativeWidget(NSView *parentView = 0); + QMacNativeWidget(NSView *parentView = Q_NULLPTR); ~QMacNativeWidget(); QSize sizeHint() const; diff --git a/src/widgets/widgets/qmacnativewidget_mac.mm b/src/widgets/widgets/qmacnativewidget_mac.mm index cfd66b8eac077539ab3699edc6dfdf08747a71ab..7a7492e717e98c21fa9d055d7dcb658390a1db9b 100644 --- a/src/widgets/widgets/qmacnativewidget_mac.mm +++ b/src/widgets/widgets/qmacnativewidget_mac.mm @@ -42,13 +42,13 @@ /*! \class QMacNativeWidget \since 4.5 - \brief The QMacNativeWidget class provides a widget for Mac OS X that provides + \brief The QMacNativeWidget class provides a widget for OS X that provides a way to put Qt widgets into Cocoa hierarchies. \ingroup advanced \inmodule QtWidgets - On Mac OS X, there is a difference between a window and view; + On OS X, there is a difference between a window and view; normally expressed as widgets in Qt. Qt makes assumptions about its parent-child hierarchy that make it complex to put an arbitrary Qt widget into a hierarchy of "normal" views from Apple frameworks. QMacNativeWidget diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp index f365ff7d1706a4a6679a7f72a113cfa1bd5714bf..5d53e7def458de857f0964d2365dce1fa85a0fd3 100644 --- a/src/widgets/widgets/qmainwindow.cpp +++ b/src/widgets/widgets/qmainwindow.cpp @@ -263,7 +263,14 @@ void QMainWindowPrivate::init() An example of how to create menus follows: - \snippet mainwindows/application/mainwindow.cpp 26 + \code + void MainWindow::createMenus() + { + fileMenu = menuBar()->addMenu(tr("&File")); + fileMenu->addAction(newAct); + fileMenu->addAction(openAct); + fileMenu->addAction(saveAct); + \endcode The \c createPopupMenu() function creates popup menus when the main window receives context menu events. The default @@ -290,7 +297,12 @@ void QMainWindowPrivate::init() An example of toolbar creation follows: - \snippet mainwindows/application/mainwindow.cpp 29 + \code + void MainWindow::createToolBars() + { + fileToolBar = addToolBar(tr("File")); + fileToolBar->addAction(newAct); + \endcode \section2 Creating Dock Widgets @@ -1506,7 +1518,7 @@ bool QMainWindow::event(QEvent *event) /*! \property QMainWindow::unifiedTitleAndToolBarOnMac - \brief whether the window uses the unified title and toolbar look on Mac OS X + \brief whether the window uses the unified title and toolbar look on OS X Note that the Qt 5 implementation has several limitations compared to Qt 4: \list diff --git a/src/widgets/widgets/qmainwindow.h b/src/widgets/widgets/qmainwindow.h index 0bd70c87a6cd68c72fdc8c93f09d2cd63e9646df..ab6ee22748b1ec9f7a6f4d9822a63d834fd54d40 100644 --- a/src/widgets/widgets/qmainwindow.h +++ b/src/widgets/widgets/qmainwindow.h @@ -83,7 +83,7 @@ public: Q_ENUM(DockOption) Q_DECLARE_FLAGS(DockOptions, DockOption) - explicit QMainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit QMainWindow(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); ~QMainWindow(); QSize iconSize() const; diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index ee76720a2768fb2a4b288142caf84d30974ab1d8..54e956c4cff199cfa3a8ea7632d5f86dd7fbfb8b 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -244,20 +244,6 @@ public: } }; -// This item will be used in the layout for the gap item. We cannot use QWidgetItem directly -// because QWidgetItem functions return an empty size for widgets are are floating. -class QDockWidgetGroupWindowItem : public QWidgetItem -{ -public: - QDockWidgetGroupWindowItem(QDockWidgetGroupWindow *parent) : QWidgetItem(parent) {} - QSize minimumSize() const Q_DECL_OVERRIDE { return lay()->minimumSize(); } - QSize maximumSize() const Q_DECL_OVERRIDE { return lay()->maximumSize(); } - QSize sizeHint() const Q_DECL_OVERRIDE { return lay()->sizeHint(); } - -private: - QLayout *lay() const { return const_cast<QDockWidgetGroupWindowItem *>(this)->widget()->layout(); } -}; - bool QDockWidgetGroupWindow::event(QEvent *e) { switch (e->type()) { @@ -1934,6 +1920,54 @@ void QMainWindowLayout::revert(QLayoutItem *widgetItem) bool QMainWindowLayout::plug(QLayoutItem *widgetItem) { +#ifndef QT_NO_DOCKWIDGET + if (currentHoveredFloat) { + QWidget *widget = widgetItem->widget(); + QList<int> previousPath = layoutState.indexOf(widget); + if (!previousPath.isEmpty()) + layoutState.remove(previousPath); + // Let's remove the widget from any possible group window + foreach (QDockWidgetGroupWindow *dwgw, + parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) { + QList<int> path = dwgw->layoutInfo()->indexOf(widget); + if (!path.isEmpty()) + dwgw->layoutInfo()->remove(path); + } + currentGapRect = QRect(); + + if (QDockWidget *dropTo = qobject_cast<QDockWidget*>(currentHoveredFloat)) { + //dropping to a normal widget, we mutate it in a QDockWidgetGroupWindow with two tabs + QDockWidgetGroupWindow *floatingTabs = createTabbedDockWindow(); + floatingTabs->setGeometry(dropTo->geometry()); + QDockAreaLayoutInfo *info = floatingTabs->layoutInfo(); + *info = QDockAreaLayoutInfo(&layoutState.dockAreaLayout.sep, QInternal::LeftDock, + Qt::Horizontal, QTabBar::RoundedSouth, + static_cast<QMainWindow*>(parentWidget())); + info->tabbed = true; + QLayout *parentLayout = currentHoveredFloat->parentWidget()->layout(); + info->item_list.append(parentLayout->takeAt(parentLayout->indexOf(currentHoveredFloat))); + + dropTo->setParent(floatingTabs); + dropTo->show(); + dropTo->d_func()->plug(QRect()); + currentHoveredFloat = floatingTabs; + } + + QDockWidgetGroupWindow *dwgw = qobject_cast<QDockWidgetGroupWindow *>(currentHoveredFloat); + Q_ASSERT(dwgw); + Q_ASSERT(dwgw->layoutInfo()->tabbed); // because floating group should always be tabbed + previousPath = dwgw->layoutInfo()->indexOf(widget); + if (!previousPath.isEmpty()) + dwgw->layoutInfo()->remove(previousPath); + dwgw->layoutInfo()->tab(0, widgetItem); + QRect globalRect = dwgw->layoutInfo()->tabContentRect(); + globalRect.moveTopLeft(dwgw->mapToGlobal(globalRect.topLeft())); + pluggingWidget = widget; + widgetAnimator.animate(widget, globalRect, dockOptions & QMainWindow::AnimatedDocks); + return true; + } +#endif + if (!parentWidget()->isVisible() || parentWidget()->isMinimized() || currentGapPos.isEmpty()) return false; @@ -1941,6 +1975,16 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) QWidget *widget = widgetItem->widget(); +#ifndef QT_NO_DOCKWIDGET + // Let's remove the widget from any possible group window + foreach (QDockWidgetGroupWindow *dwgw, + parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) { + QList<int> path = dwgw->layoutInfo()->indexOf(widget); + if (!path.isEmpty()) + dwgw->layoutInfo()->remove(path); + } +#endif + QList<int> previousPath = layoutState.indexOf(widget); const QLayoutItem *it = layoutState.plug(currentGapPos); @@ -1993,11 +2037,21 @@ void QMainWindowLayout::animationFinished(QWidget *widget) // embedded QDockWidget needs to be plugged back into the QMainWindow layout. savedState.clear(); QDockAreaLayoutInfo* info = dwgw->layoutInfo(); - QList<int> path = layoutState.dockAreaLayout.indexOf(widget); - Q_ASSERT(path.size() >= 2); + QDockAreaLayoutInfo* parentInfo; + QList<int> path; + + if (QDockWidgetGroupWindow *dropTo = qobject_cast<QDockWidgetGroupWindow *>(currentHoveredFloat)) { + parentInfo = dropTo->layoutInfo(); + Q_ASSERT(parentInfo->tabbed); + path = parentInfo->indexOf(widget); + Q_ASSERT(path.size() == 1); + } else { + path = layoutState.dockAreaLayout.indexOf(widget); + Q_ASSERT(path.size() >= 2); + parentInfo = layoutState.dockAreaLayout.info(path); + Q_ASSERT(parentInfo); + } - QDockAreaLayoutInfo* parentInfo = layoutState.dockAreaLayout.info(path); - Q_ASSERT(parentInfo); if (parentInfo->tabbed) { // merge the two tab widgets int idx = path.last(); @@ -2008,7 +2062,7 @@ void QMainWindowLayout::animationFinished(QWidget *widget) std::inserter(parentInfo->item_list, parentInfo->item_list.begin() + idx)); quintptr currentId = info->currentTabId(); *info = QDockAreaLayoutInfo(); - parentInfo->reparentWidgets(parentWidget()); + parentInfo->reparentWidgets(currentHoveredFloat ? currentHoveredFloat.data() : parentWidget()); parentInfo->updateTabBar(); parentInfo->setCurrentTabId(currentId); } else { @@ -2024,8 +2078,13 @@ void QMainWindowLayout::animationFinished(QWidget *widget) dwgw->destroyIfEmpty(); } - if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) + if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) { + if (currentHoveredFloat) { + dw->setParent(currentHoveredFloat); + dw->show(); + } dw->d_func()->plug(currentGapRect); + } #endif #ifndef QT_NO_TOOLBAR if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) @@ -2035,6 +2094,7 @@ void QMainWindowLayout::animationFinished(QWidget *widget) savedState.clear(); currentGapPos.clear(); pluggingWidget = 0; + currentHoveredFloat = Q_NULLPTR; //applying the state will make sure that the currentGap is updated correctly //and all the geometries (especially the one from the central widget) is correct layoutState.apply(false); @@ -2096,9 +2156,6 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow, QLayout *parentLay #endif // QT_NO_DOCKWIDGET , widgetAnimator(this) , pluggingWidget(0) -#ifndef QT_NO_RUBBERBAND - , gapIndicator(new QRubberBand(QRubberBand::Rectangle, mainwindow)) -#endif //QT_NO_RUBBERBAND #ifdef Q_DEAD_CODE_FROM_QT4_MAC , blockVisiblityCheck(false) #endif @@ -2116,12 +2173,6 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow, QLayout *parentLay tabPositions[i] = QTabWidget::South; #endif #endif // QT_NO_DOCKWIDGET - -#ifndef QT_NO_RUBBERBAND - // For accessibility to identify this special widget. - gapIndicator->setObjectName(QLatin1String("qt_rubberband")); - gapIndicator->hide(); -#endif pluggingWidget = 0; setObjectName(mainwindow->objectName() + QLatin1String("_layout")); @@ -2278,18 +2329,75 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group) void QMainWindowLayout::updateGapIndicator() { #ifndef QT_NO_RUBBERBAND - gapIndicator->setVisible(!widgetAnimator.animating() && !currentGapPos.isEmpty()); - gapIndicator->setGeometry(currentGapRect); -#endif + if ((!widgetAnimator.animating() && !currentGapPos.isEmpty()) || currentHoveredFloat) { + QWidget *expectedParent = currentHoveredFloat ? currentHoveredFloat.data() : parentWidget(); + if (!gapIndicator) { + gapIndicator = new QRubberBand(QRubberBand::Rectangle, expectedParent); + // For accessibility to identify this special widget. + gapIndicator->setObjectName(QLatin1String("qt_rubberband")); + } else if (gapIndicator->parent() != expectedParent) { + gapIndicator->setParent(expectedParent); + } + gapIndicator->setGeometry(currentHoveredFloat ? currentHoveredFloat->rect() : currentGapRect); + gapIndicator->show(); + gapIndicator->raise(); + } else if (gapIndicator) { + gapIndicator->hide(); + } +#endif //QT_NO_RUBBERBAND } -QList<int> QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos) +void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos) { if (!parentWidget()->isVisible() || parentWidget()->isMinimized() || pluggingWidget != 0 || widgetItem == 0) - return QList<int>(); + return; QWidget *widget = widgetItem->widget(); + +#ifndef QT_NO_DOCKWIDGET + if ((dockOptions & QMainWindow::GroupedDragging) && (qobject_cast<QDockWidget*>(widget) + || qobject_cast<QDockWidgetGroupWindow *>(widget))) { + + // Check if we are over another floating dock widget + QVarLengthArray<QWidget *, 10> candidates; + foreach (QObject *c, parentWidget()->children()) { + QWidget *w = qobject_cast<QWidget*>(c); + if (!w) + continue; + if (w == widget) + continue; + if (!w->isTopLevel() || !w->isVisible() || w->isMinimized()) + continue; + if (!qobject_cast<QDockWidget*>(w) && !qobject_cast<QDockWidgetGroupWindow *>(w)) + continue; + candidates << w; + if (QDockWidgetGroupWindow *group = qobject_cast<QDockWidgetGroupWindow *>(w)) { + // Sometimes, there are floating QDockWidget that have a QDockWidgetGroupWindow as a parent. + foreach (QObject *c, group->children()) { + if (QDockWidget *dw = qobject_cast<QDockWidget*>(c)) { + if (dw != widget && dw->isFloating() && dw->isVisible() && !dw->isMinimized()) + candidates << dw; + } + } + } + } + foreach (QWidget *w, candidates) { + QWindow *handle1 = widget->windowHandle(); + QWindow *handle2 = w->windowHandle(); + if (handle1 && handle2 && handle1->screen() != handle2->screen()) + continue; + if (!w->geometry().contains(mousePos)) + continue; + + currentHoveredFloat = w; + restore(true); + return; + } + } + currentHoveredFloat = Q_NULLPTR; +#endif //QT_NO_DOCKWIDGET + QPoint pos = parentWidget()->mapFromGlobal(mousePos); if (!savedState.isValid()) @@ -2317,13 +2425,13 @@ QList<int> QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mouse } if (path == currentGapPos) - return currentGapPos; // the gap is already there + return; // the gap is already there currentGapPos = path; if (path.isEmpty()) { fixToolBarOrientation(widgetItem, 2); // 2 = top dock, ie. horizontal restore(true); - return QList<int>(); + return; } fixToolBarOrientation(widgetItem, currentGapPos.at(1)); @@ -2332,7 +2440,7 @@ QList<int> QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mouse if (!newState.insertGap(path, widgetItem)) { restore(true); // not enough space - return QList<int>(); + return; } QSize min = newState.minimumSize(); @@ -2340,7 +2448,7 @@ QList<int> QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mouse if (min.width() > size.width() || min.height() > size.height()) { restore(true); - return QList<int>(); + return; } newState.fitLayout(); @@ -2354,8 +2462,6 @@ QList<int> QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mouse applyState(layoutState); updateGapIndicator(); - - return path; } QDockWidgetGroupWindow *QMainWindowLayout::createTabbedDockWindow() diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h index 9155c5fb23b0e302425f90541ee3a522adcf735f..9a13e5f5ce0039f759ae98a54b707ff01d394645 100644 --- a/src/widgets/widgets/qmainwindowlayout_p.h +++ b/src/widgets/widgets/qmainwindowlayout_p.h @@ -92,6 +92,20 @@ protected: bool event(QEvent *) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent*) Q_DECL_OVERRIDE; }; + +// This item will be used in the layout for the gap item. We cannot use QWidgetItem directly +// because QWidgetItem functions return an empty size for widgets that are are floating. +class QDockWidgetGroupWindowItem : public QWidgetItem +{ +public: + explicit QDockWidgetGroupWindowItem(QDockWidgetGroupWindow *parent) : QWidgetItem(parent) {} + QSize minimumSize() const Q_DECL_OVERRIDE { return lay()->minimumSize(); } + QSize maximumSize() const Q_DECL_OVERRIDE { return lay()->maximumSize(); } + QSize sizeHint() const Q_DECL_OVERRIDE { return lay()->sizeHint(); } + +private: + QLayout *lay() const { return const_cast<QDockWidgetGroupWindowItem *>(this)->widget()->layout(); } +}; #endif /* This data structure represents the state of all the tool-bars and dock-widgets. It's value based @@ -288,10 +302,13 @@ public: QRect currentGapRect; QWidget *pluggingWidget; #ifndef QT_NO_RUBBERBAND - QRubberBand *gapIndicator; + QPointer<QRubberBand> gapIndicator; +#endif +#ifndef QT_NO_DOCKWIDGET + QPointer<QWidget> currentHoveredFloat; // set when dragging over a floating dock widget #endif - QList<int> hover(QLayoutItem *widgetItem, const QPoint &mousePos); + void hover(QLayoutItem *widgetItem, const QPoint &mousePos); bool plug(QLayoutItem *widgetItem); QLayoutItem *unplug(QWidget *widget, bool group = false); void revert(QLayoutItem *widgetItem); diff --git a/src/widgets/widgets/qmdiarea.h b/src/widgets/widgets/qmdiarea.h index 461282f8a89e362f53441a7bc0514ae44c4fe558..e05535b2af3369aa48fdea90dcd3e4a353c2ca4d 100644 --- a/src/widgets/widgets/qmdiarea.h +++ b/src/widgets/widgets/qmdiarea.h @@ -79,7 +79,7 @@ public: }; Q_ENUM(ViewMode) - QMdiArea(QWidget *parent = 0); + QMdiArea(QWidget *parent = Q_NULLPTR); ~QMdiArea(); QSize sizeHint() const Q_DECL_OVERRIDE; @@ -89,7 +89,7 @@ public: QMdiSubWindow *activeSubWindow() const; QList<QMdiSubWindow *> subWindowList(WindowOrder order = CreationOrder) const; - QMdiSubWindow *addSubWindow(QWidget *widget, Qt::WindowFlags flags = 0); + QMdiSubWindow *addSubWindow(QWidget *widget, Qt::WindowFlags flags = Qt::WindowFlags()); void removeSubWindow(QWidget *widget); QBrush background() const; diff --git a/src/widgets/widgets/qmdiarea_p.h b/src/widgets/widgets/qmdiarea_p.h index 7f28879f8dde8a20577c11c1420d1c148a19496c..f6bdf6149238d82d4f93256a561a6299de7cb7ab 100644 --- a/src/widgets/widgets/qmdiarea_p.h +++ b/src/widgets/widgets/qmdiarea_p.h @@ -142,8 +142,8 @@ public: #endif QMdiAreaTabBar *tabBar; QList<QMdi::Rearranger *> pendingRearrangements; - QList< QPointer<QMdiSubWindow> > pendingPlacements; - QList< QPointer<QMdiSubWindow> > childWindows; + QVector< QPointer<QMdiSubWindow> > pendingPlacements; + QVector< QPointer<QMdiSubWindow> > childWindows; QList<int> indicesToActivatedChildren; QPointer<QMdiSubWindow> active; QPointer<QMdiSubWindow> aboutToBecomeActive; diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp index 1808030639b670f539d3d10d9b156555d5244ad6..c3b31ea5a4b84f2135d54c0cfb2d6629957e3cde 100644 --- a/src/widgets/widgets/qmdisubwindow.cpp +++ b/src/widgets/widgets/qmdisubwindow.cpp @@ -1091,8 +1091,8 @@ void QMdiSubWindowPrivate::updateDirtyRegions() if (!parent) return; - foreach (Operation operation, operationMap.keys()) - operationMap.find(operation).value().region = getRegion(operation); + for (OperationInfoMap::iterator it = operationMap.begin(), end = operationMap.end(); it != end; ++it) + it.value().region = getRegion(it.key()); } /*! diff --git a/src/widgets/widgets/qmdisubwindow.h b/src/widgets/widgets/qmdisubwindow.h index 693477c89425b1f5c763aa485dfd6e17b7d2321c..e7d0ca4e4492a006a1ec63874abf615e9ba99578 100644 --- a/src/widgets/widgets/qmdisubwindow.h +++ b/src/widgets/widgets/qmdisubwindow.h @@ -60,7 +60,7 @@ public: }; Q_DECLARE_FLAGS(SubWindowOptions, SubWindowOption) - QMdiSubWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0); + QMdiSubWindow(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); ~QMdiSubWindow(); QSize sizeHint() const Q_DECL_OVERRIDE; diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 4403deda8e671c1f5ac322d52819c26f74110ed0..a7c58ab332b08b012bcbe41f424ddf8c8401f75e 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -102,9 +102,9 @@ class QTornOffMenu : public QMenu causedPopup.action = ((QTornOffMenu*)p)->d_func()->causedPopup.action; causedStack = ((QTornOffMenu*)p)->d_func()->calcCausedStack(); } - QList<QPointer<QWidget> > calcCausedStack() const Q_DECL_OVERRIDE { return causedStack; } + QVector<QPointer<QWidget> > calcCausedStack() const Q_DECL_OVERRIDE { return causedStack; } QPointer<QMenu> causedMenu; - QList<QPointer<QWidget> > causedStack; + QVector<QPointer<QWidget> > causedStack; }; public: QTornOffMenu(QMenu *p) : QMenu(*(new QTornOffMenuPrivate(p))) @@ -236,9 +236,9 @@ QRect QMenuPrivate::popupGeometry(int screen) const } } -QList<QPointer<QWidget> > QMenuPrivate::calcCausedStack() const +QVector<QPointer<QWidget> > QMenuPrivate::calcCausedStack() const { - QList<QPointer<QWidget> > ret; + QVector<QPointer<QWidget> > ret; for(QWidget *widget = causedPopup.widget; widget; ) { ret.append(widget); if (QTornOffMenu *qtmenu = qobject_cast<QTornOffMenu*>(widget)) @@ -1122,7 +1122,7 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) return false; } -void QMenuPrivate::activateCausedStack(const QList<QPointer<QWidget> > &causedStack, QAction *action, QAction::ActionEvent action_e, bool self) +void QMenuPrivate::activateCausedStack(const QVector<QPointer<QWidget> > &causedStack, QAction *action, QAction::ActionEvent action_e, bool self) { QBoolBlocker guard(activationRecursionGuard); if(self) @@ -1170,7 +1170,7 @@ void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e /* I have to save the caused stack here because it will be undone after popup execution (ie in the hide). Then I iterate over the list to actually send the events. --Sam */ - const QList<QPointer<QWidget> > causedStack = calcCausedStack(); + const QVector<QPointer<QWidget> > causedStack = calcCausedStack(); if (action_e == QAction::Trigger) { #ifndef QT_NO_WHATSTHIS if (!inWhatsThisMode) @@ -1232,7 +1232,7 @@ void QMenuPrivate::_q_actionTriggered() if (!activationRecursionGuard && actionGuard) { //in case the action has not been activated by the mouse //we check the parent hierarchy - QList< QPointer<QWidget> > list; + QVector< QPointer<QWidget> > list; for(QWidget *widget = q->parentWidget(); widget; ) { if (qobject_cast<QMenu*>(widget) #ifndef QT_NO_MENUBAR @@ -1431,7 +1431,7 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) do not support the signals: aboutToHide (), aboutToShow () and hovered (). It is not possible to display an icon in a native menu on Windows Mobile. - \section1 QMenu on Mac OS X with Qt Build Against Cocoa + \section1 QMenu on OS X with Qt Build Against Cocoa QMenu can be inserted only once in a menu/menubar. Subsequent insertions will have no effect or will result in a disabled menu item. @@ -1571,6 +1571,100 @@ QAction *QMenu::addAction(const QString &text, const QObject *receiver, const ch return action; } +/*!\fn QAction *QMenu::addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0) + + \since 5.6 + + \overload + + This convenience function creates a new action with the text \a + text and an optional shortcut \a shortcut. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a method of the \a receiver. The function adds the newly created + action to the menu's list of actions and returns it. + + QMenu takes ownership of the returned QAction. +*/ + +/*!\fn QAction *QMenu::addAction(const QString &text, Functor functor, const QKeySequence &shortcut = 0) + + \since 5.6 + + \overload + + This convenience function creates a new action with the text \a + text and an optional shortcut \a shortcut. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. The function adds the newly created + action to the menu's list of actions and returns it. + + QMenu takes ownership of the returned QAction. +*/ + +/*!\fn QAction *QMenu::addAction(const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut = 0) + + \since 5.6 + + \overload + + This convenience function creates a new action with the text \a + text and an optional shortcut \a shortcut. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. The function adds the newly created + action to the menu's list of actions and returns it. + + If \a context is destroyed, the functor will not be called. + + QMenu takes ownership of the returned QAction. +*/ + +/*!\fn QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0) + + \since 5.6 + + \overload + + This convenience function creates a new action with an \a icon + and some \a text and an optional shortcut \a shortcut. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a method of the \a receiver. The function adds the newly created + action to the menu's list of actions and returns it. + + QMenu takes ownership of the returned QAction. +*/ + +/*!\fn QAction *QMenu::addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut = 0) + + \since 5.6 + + \overload + + This convenience function creates a new action with an \a icon + and some \a text and an optional shortcut \a shortcut. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. The function adds the newly created + action to the menu's list of actions and returns it. + + QMenu takes ownership of the returned QAction. +*/ + +/*!\fn QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut = 0) + + \since 5.6 + + \overload + + This convenience function creates a new action with an \a icon + and some \a text and an optional shortcut \a shortcut. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. The function adds the newly created + action to the menu's list of actions and returns it. + + If \a context is destroyed, the functor will not be called. + + QMenu takes ownership of the returned QAction. +*/ + /*! \overload diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h index 5dda8b237026c88bc1014ca6e46e807ab4fff1b6..6bbe54186e60e2459123c0d5bdac1866ef8589e4 100644 --- a/src/widgets/widgets/qmenu.h +++ b/src/widgets/widgets/qmenu.h @@ -68,8 +68,8 @@ private: Q_PROPERTY(bool toolTipsVisible READ toolTipsVisible WRITE setToolTipsVisible) public: - explicit QMenu(QWidget *parent = 0); - explicit QMenu(const QString &title, QWidget *parent = 0); + explicit QMenu(QWidget *parent = Q_NULLPTR); + explicit QMenu(const QString &title, QWidget *parent = Q_NULLPTR); ~QMenu(); using QWidget::addAction; @@ -78,6 +78,72 @@ public: QAction *addAction(const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0); QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0); +#ifdef Q_QDOC + QAction *addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0); + QAction *addAction(const QString &text, Functor functor, const QKeySequence &shortcut = 0); + QAction *addAction(const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut = 0); + QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0); + QAction *addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut = 0); + QAction *addAction(const QIcon &icon, const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut = 0); +#else + // addAction(QString): Connect to a QObject slot / functor or function pointer (with context) + template<class Obj, typename Func1> + inline typename QtPrivate::QEnableIf<!QtPrivate::is_same<const char*, Func1>::value + && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::Type + addAction(const QString &text, const Obj *object, Func1 slot, const QKeySequence &shortcut = 0) + { + QAction *result = addAction(text); +#ifdef QT_NO_SHORTCUT + Q_UNUSED(shortcut) +#else + result->setShortcut(shortcut); +#endif + connect(result, &QAction::triggered, object, slot); + return result; + } + // addAction(QString): Connect to a functor or function pointer (without context) + template <typename Func1> + inline QAction *addAction(const QString &text, Func1 slot, const QKeySequence &shortcut = 0) + { + QAction *result = addAction(text); +#ifdef QT_NO_SHORTCUT + Q_UNUSED(shortcut) +#else + result->setShortcut(shortcut); +#endif + connect(result, &QAction::triggered, slot); + return result; + } + // addAction(QIcon, QString): Connect to a QObject slot / functor or function pointer (with context) + template<class Obj, typename Func1> + inline typename QtPrivate::QEnableIf<!QtPrivate::is_same<const char*, Func1>::value + && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::Type + addAction(const QIcon &actionIcon, const QString &text, const Obj *object, Func1 slot, const QKeySequence &shortcut = 0) + { + QAction *result = addAction(actionIcon, text); +#ifdef QT_NO_SHORTCUT + Q_UNUSED(shortcut) +#else + result->setShortcut(shortcut); +#endif + connect(result, &QAction::triggered, object, slot); + return result; + } + // addAction(QIcon, QString): Connect to a functor or function pointer (without context) + template <typename Func1> + inline QAction *addAction(const QIcon &actionIcon, const QString &text, Func1 slot, const QKeySequence &shortcut = 0) + { + QAction *result = addAction(actionIcon, text); +#ifdef QT_NO_SHORTCUT + Q_UNUSED(shortcut) +#else + result->setShortcut(shortcut); +#endif + connect(result, &QAction::triggered, slot); + return result; + } +#endif // !Q_QDOC + QAction *addMenu(QMenu *menu); QMenu *addMenu(const QString &title); QMenu *addMenu(const QIcon &icon, const QString &title); @@ -107,14 +173,14 @@ public: void setActiveAction(QAction *act); QAction *activeAction() const; - void popup(const QPoint &pos, QAction *at=0); + void popup(const QPoint &pos, QAction *at = Q_NULLPTR); QAction *exec(); - QAction *exec(const QPoint &pos, QAction *at=0); + QAction *exec(const QPoint &pos, QAction *at = Q_NULLPTR); #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - static QAction *exec(const QList<QAction *> &actions, const QPoint &pos, QAction *at = 0, QWidget *parent = 0); + static QAction *exec(const QList<QAction *> &actions, const QPoint &pos, QAction *at = Q_NULLPTR, QWidget *parent = Q_NULLPTR); #else - static QAction *exec(QList<QAction*> actions, const QPoint &pos, QAction *at=0, QWidget *parent=0); + static QAction *exec(QList<QAction*> actions, const QPoint &pos, QAction *at = Q_NULLPTR, QWidget *parent = Q_NULLPTR); #endif QSize sizeHint() const Q_DECL_OVERRIDE; @@ -189,7 +255,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_platformMenuAboutToShow()) protected: - QMenu(QMenuPrivate &dd, QWidget* parent = 0); + QMenu(QMenuPrivate &dd, QWidget* parent = Q_NULLPTR); private: Q_DISABLE_COPY(QMenu) diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index ab6ca068fb9e05b0e9dc5805584a37f1153b2ffb..3acf73af90e4972e551244ef8a9eed7e7161dc59 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -422,7 +422,7 @@ public: QPointer<QWidget> widget; QPointer<QAction> action; }; - virtual QList<QPointer<QWidget> > calcCausedStack() const; + virtual QVector<QPointer<QWidget> > calcCausedStack() const; QMenuCaused causedPopup; void hideUpToMenuBar(); void hideMenu(QMenu *menu); @@ -450,7 +450,7 @@ public: //firing of events void activateAction(QAction *, QAction::ActionEvent, bool self=true); - void activateCausedStack(const QList<QPointer<QWidget> > &, QAction *, QAction::ActionEvent, bool); + void activateCausedStack(const QVector<QPointer<QWidget> > &, QAction *, QAction::ActionEvent, bool); void _q_actionTriggered(); void _q_actionHovered(); diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 1ad99bed9c0200084e104a84b958b30de2f2c680..9e76ff082cc8499e19894f59f5d0e0afe0530cb5 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -195,7 +195,9 @@ void QMenuBarPrivate::updateGeometries() for(int j = 0; j < shortcutIndexMap.size(); ++j) q->releaseShortcut(shortcutIndexMap.value(j)); shortcutIndexMap.resize(0); // faster than clear - for(int i = 0; i < actions.count(); i++) + const int actionsCount = actions.count(); + shortcutIndexMap.reserve(actionsCount); + for (int i = 0; i < actionsCount; i++) shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text()))); } #endif diff --git a/src/widgets/widgets/qmenubar.h b/src/widgets/widgets/qmenubar.h index 461dec8a94157024ff63c4a1cb7c606d5fbb04de..3b3980c8607595afb9dd1c9e18e8e44b33398a1e 100644 --- a/src/widgets/widgets/qmenubar.h +++ b/src/widgets/widgets/qmenubar.h @@ -54,7 +54,7 @@ class Q_WIDGETS_EXPORT QMenuBar : public QWidget Q_PROPERTY(bool nativeMenuBar READ isNativeMenuBar WRITE setNativeMenuBar) public: - explicit QMenuBar(QWidget *parent = 0); + explicit QMenuBar(QWidget *parent = Q_NULLPTR); ~QMenuBar(); using QWidget::addAction; diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp index 93c9ddc285f69ec3f9c0ef9db14fb9440cf02343..91788a338345c4da4ed80806b3e80ec3cc9fdb78 100644 --- a/src/widgets/widgets/qplaintextedit.cpp +++ b/src/widgets/widgets/qplaintextedit.cpp @@ -1615,7 +1615,7 @@ void QPlainTextEdit::timerEvent(QTimerEvent *e) Note that the undo/redo history is cleared by this function. - \sa toText() + \sa toPlainText() */ void QPlainTextEdit::setPlainText(const QString &text) diff --git a/src/widgets/widgets/qplaintextedit.h b/src/widgets/widgets/qplaintextedit.h index 69bd2ab6477c6d284257b8f5da3a874917db682a..60f1d6e984403f8d1fb89e6efcb2981e552be83e 100644 --- a/src/widgets/widgets/qplaintextedit.h +++ b/src/widgets/widgets/qplaintextedit.h @@ -82,8 +82,8 @@ public: }; Q_ENUM(LineWrapMode) - explicit QPlainTextEdit(QWidget *parent = 0); - explicit QPlainTextEdit(const QString &text, QWidget *parent = 0); + explicit QPlainTextEdit(QWidget *parent = Q_NULLPTR); + explicit QPlainTextEdit(const QString &text, QWidget *parent = Q_NULLPTR); virtual ~QPlainTextEdit(); void setDocument(QTextDocument *document); @@ -136,9 +136,9 @@ public: void setCenterOnScroll(bool enabled); bool centerOnScroll() const; - bool find(const QString &exp, QTextDocument::FindFlags options = 0); + bool find(const QString &exp, QTextDocument::FindFlags options = QTextDocument::FindFlags()); #ifndef QT_NO_REGEXP - bool find(const QRegExp &exp, QTextDocument::FindFlags options = 0); + bool find(const QRegExp &exp, QTextDocument::FindFlags options = QTextDocument::FindFlags()); #endif inline QString toPlainText() const diff --git a/src/widgets/widgets/qprogressbar.h b/src/widgets/widgets/qprogressbar.h index 0c3200f82c0a32e8f97e1386769e8bdd51a30021..e17e01c17b8a5cc516b557b70f7c4cd0ae541c18 100644 --- a/src/widgets/widgets/qprogressbar.h +++ b/src/widgets/widgets/qprogressbar.h @@ -62,7 +62,7 @@ public: enum Direction { TopToBottom, BottomToTop }; Q_ENUM(Direction) - explicit QProgressBar(QWidget *parent = 0); + explicit QProgressBar(QWidget *parent = Q_NULLPTR); ~QProgressBar(); int minimum() const; diff --git a/src/widgets/widgets/qpushbutton.h b/src/widgets/widgets/qpushbutton.h index 2521c0982e480779a884e21e31c2ac8bd9b87fd4..3db12be38058a861ab778be387e10f167746ba76 100644 --- a/src/widgets/widgets/qpushbutton.h +++ b/src/widgets/widgets/qpushbutton.h @@ -52,9 +52,9 @@ class Q_WIDGETS_EXPORT QPushButton : public QAbstractButton Q_PROPERTY(bool flat READ isFlat WRITE setFlat) public: - explicit QPushButton(QWidget *parent=0); - explicit QPushButton(const QString &text, QWidget *parent=0); - QPushButton(const QIcon& icon, const QString &text, QWidget *parent=0); + explicit QPushButton(QWidget *parent = Q_NULLPTR); + explicit QPushButton(const QString &text, QWidget *parent = Q_NULLPTR); + QPushButton(const QIcon& icon, const QString &text, QWidget *parent = Q_NULLPTR); ~QPushButton(); QSize sizeHint() const Q_DECL_OVERRIDE; @@ -88,7 +88,7 @@ protected: void focusInEvent(QFocusEvent *) Q_DECL_OVERRIDE; void focusOutEvent(QFocusEvent *) Q_DECL_OVERRIDE; void initStyleOption(QStyleOptionButton *option) const; - QPushButton(QPushButtonPrivate &dd, QWidget* parent = 0); + QPushButton(QPushButtonPrivate &dd, QWidget* parent = Q_NULLPTR); public: diff --git a/src/widgets/widgets/qradiobutton.h b/src/widgets/widgets/qradiobutton.h index f323f5af997252edcb5f7134264133dc2b539d1d..df0b1051bfe27eea28d758fd75e2c7b5e7f15205 100644 --- a/src/widgets/widgets/qradiobutton.h +++ b/src/widgets/widgets/qradiobutton.h @@ -47,8 +47,8 @@ class Q_WIDGETS_EXPORT QRadioButton : public QAbstractButton Q_OBJECT public: - explicit QRadioButton(QWidget *parent=0); - explicit QRadioButton(const QString &text, QWidget *parent=0); + explicit QRadioButton(QWidget *parent = Q_NULLPTR); + explicit QRadioButton(const QString &text, QWidget *parent = Q_NULLPTR); ~QRadioButton(); QSize sizeHint() const Q_DECL_OVERRIDE; diff --git a/src/widgets/widgets/qrubberband.cpp b/src/widgets/widgets/qrubberband.cpp index abddbcb64ac8bce768441446beb0bed90a289563..3315e2703ab88f1b2b3b634a0c18a0d96d24dbd0 100644 --- a/src/widgets/widgets/qrubberband.cpp +++ b/src/widgets/widgets/qrubberband.cpp @@ -126,7 +126,7 @@ void QRubberBand::initStyleOption(QStyleOptionRubberBand *option) const By default a rectangular rubber band (\a s is \c Rectangle) will use a mask, so that a small border of the rectangle is all - that is visible. Some styles (e.g., native Mac OS X) will + that is visible. Some styles (e.g., native OS X) will change this and call QWidget::setWindowOpacity() to make a semi-transparent filled selection rectangle. */ diff --git a/src/widgets/widgets/qrubberband.h b/src/widgets/widgets/qrubberband.h index 3ff6eb47fa682bf6002da52d8bc28a3e4cf0133c..b0dc14ed98a8248473c7fe631594846f903b7394 100644 --- a/src/widgets/widgets/qrubberband.h +++ b/src/widgets/widgets/qrubberband.h @@ -50,7 +50,7 @@ class Q_WIDGETS_EXPORT QRubberBand : public QWidget public: enum Shape { Line, Rectangle }; - explicit QRubberBand(Shape, QWidget * =0); + explicit QRubberBand(Shape, QWidget * = Q_NULLPTR); ~QRubberBand(); Shape shape() const; diff --git a/src/widgets/widgets/qscrollarea.h b/src/widgets/widgets/qscrollarea.h index cafb1ec6defc3ca02f4af4949c3b2bec2a3b48c8..1658236034ad226dad55a2aaaffcb277034cfc5e 100644 --- a/src/widgets/widgets/qscrollarea.h +++ b/src/widgets/widgets/qscrollarea.h @@ -50,7 +50,7 @@ class Q_WIDGETS_EXPORT QScrollArea : public QAbstractScrollArea Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment) public: - explicit QScrollArea(QWidget* parent=0); + explicit QScrollArea(QWidget *parent = Q_NULLPTR); ~QScrollArea(); QWidget *widget() const; @@ -71,7 +71,7 @@ public: void ensureWidgetVisible(QWidget *childWidget, int xmargin = 50, int ymargin = 50); protected: - QScrollArea(QScrollAreaPrivate &dd, QWidget *parent = 0); + QScrollArea(QScrollAreaPrivate &dd, QWidget *parent = Q_NULLPTR); bool event(QEvent *) Q_DECL_OVERRIDE; bool eventFilter(QObject *, QEvent *) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE; diff --git a/src/widgets/widgets/qscrollbar.h b/src/widgets/widgets/qscrollbar.h index 5934469045c371720ba9604e669c8cff8831c97e..4af5fb4a555757361df195fa1269a477c0df2661 100644 --- a/src/widgets/widgets/qscrollbar.h +++ b/src/widgets/widgets/qscrollbar.h @@ -49,8 +49,8 @@ class Q_WIDGETS_EXPORT QScrollBar : public QAbstractSlider { Q_OBJECT public: - explicit QScrollBar(QWidget *parent=0); - explicit QScrollBar(Qt::Orientation, QWidget *parent=0); + explicit QScrollBar(QWidget *parent = Q_NULLPTR); + explicit QScrollBar(Qt::Orientation, QWidget *parent = Q_NULLPTR); ~QScrollBar(); QSize sizeHint() const Q_DECL_OVERRIDE; diff --git a/src/widgets/widgets/qslider.h b/src/widgets/widgets/qslider.h index 3a528382a7b2113bf8bafdfbc904975f5f587c17..801a684fdfab8fe58be4c957af0c11a116a4cd14 100644 --- a/src/widgets/widgets/qslider.h +++ b/src/widgets/widgets/qslider.h @@ -61,8 +61,8 @@ public: }; Q_ENUM(TickPosition) - explicit QSlider(QWidget *parent = 0); - explicit QSlider(Qt::Orientation orientation, QWidget *parent = 0); + explicit QSlider(QWidget *parent = Q_NULLPTR); + explicit QSlider(Qt::Orientation orientation, QWidget *parent = Q_NULLPTR); ~QSlider(); diff --git a/src/widgets/widgets/qspinbox.h b/src/widgets/widgets/qspinbox.h index 606206d4f0bc4fc79d214c1772097b983a815533..066fe88562140306a610470bb7e9b6506c4246cf 100644 --- a/src/widgets/widgets/qspinbox.h +++ b/src/widgets/widgets/qspinbox.h @@ -56,7 +56,7 @@ class Q_WIDGETS_EXPORT QSpinBox : public QAbstractSpinBox Q_PROPERTY(int displayIntegerBase READ displayIntegerBase WRITE setDisplayIntegerBase) public: - explicit QSpinBox(QWidget *parent = 0); + explicit QSpinBox(QWidget *parent = Q_NULLPTR); ~QSpinBox(); int value() const; @@ -117,7 +117,7 @@ class Q_WIDGETS_EXPORT QDoubleSpinBox : public QAbstractSpinBox Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep) Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged USER true) public: - explicit QDoubleSpinBox(QWidget *parent = 0); + explicit QDoubleSpinBox(QWidget *parent = Q_NULLPTR); ~QDoubleSpinBox(); double value() const; diff --git a/src/widgets/widgets/qsplashscreen.h b/src/widgets/widgets/qsplashscreen.h index 58b8484f4c29af160eeda7f371d4275534076635..dec24a560833a34a3f49be6037548441c3757940 100644 --- a/src/widgets/widgets/qsplashscreen.h +++ b/src/widgets/widgets/qsplashscreen.h @@ -47,8 +47,8 @@ class Q_WIDGETS_EXPORT QSplashScreen : public QWidget { Q_OBJECT public: - explicit QSplashScreen(const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = 0); - QSplashScreen(QWidget *parent, const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = 0); + explicit QSplashScreen(const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags()); + QSplashScreen(QWidget *parent, const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags()); virtual ~QSplashScreen(); void setPixmap(const QPixmap &pixmap); diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp index 38773a4fbf2491558db14761d5ed1b5f6c16acb2..c2081c15f84a48bc8e51359eee447f83d2d4c9b9 100644 --- a/src/widgets/widgets/qsplitter.cpp +++ b/src/widgets/widgets/qsplitter.cpp @@ -1502,8 +1502,11 @@ QList<int> QSplitter::sizes() const Q_D(const QSplitter); ensurePolished(); + const int numSizes = d->list.size(); QList<int> list; - for (int i = 0; i < d->list.size(); ++i) { + list.reserve(numSizes); + + for (int i = 0; i < numSizes; ++i) { QSplitterLayoutStruct *s = d->list.at(i); list.append(d->pick(s->rect.size())); } @@ -1598,8 +1601,10 @@ QByteArray QSplitter::saveState() const stream << qint32(SplitterMagic); stream << qint32(version); + const int numSizes = d->list.size(); QList<int> list; - for (int i = 0; i < d->list.size(); ++i) { + list.reserve(numSizes); + for (int i = 0; i < numSizes; ++i) { QSplitterLayoutStruct *s = d->list.at(i); list.append(s->sizer); } diff --git a/src/widgets/widgets/qsplitter.h b/src/widgets/widgets/qsplitter.h index 4da92acd22f912e3d6e0d3214441e0e19be4b0a7..84010c236b5041f94f15fa57a4edd8dc60c98e6a 100644 --- a/src/widgets/widgets/qsplitter.h +++ b/src/widgets/widgets/qsplitter.h @@ -58,8 +58,8 @@ class Q_WIDGETS_EXPORT QSplitter : public QFrame Q_PROPERTY(bool childrenCollapsible READ childrenCollapsible WRITE setChildrenCollapsible) public: - explicit QSplitter(QWidget* parent = 0); - explicit QSplitter(Qt::Orientation, QWidget* parent = 0); + explicit QSplitter(QWidget* parent = Q_NULLPTR); + explicit QSplitter(Qt::Orientation, QWidget* parent = Q_NULLPTR); ~QSplitter(); void addWidget(QWidget *widget); diff --git a/src/widgets/widgets/qstackedwidget.h b/src/widgets/widgets/qstackedwidget.h index 4267d8241f699aac2ec33b42681bef65f416b916..9fcdf808338435d164d7140daa7798cc4391aaea 100644 --- a/src/widgets/widgets/qstackedwidget.h +++ b/src/widgets/widgets/qstackedwidget.h @@ -50,7 +50,7 @@ class Q_WIDGETS_EXPORT QStackedWidget : public QFrame Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged) Q_PROPERTY(int count READ count) public: - explicit QStackedWidget(QWidget *parent=0); + explicit QStackedWidget(QWidget *parent = Q_NULLPTR); ~QStackedWidget(); int addWidget(QWidget *w); diff --git a/src/widgets/widgets/qstatusbar.h b/src/widgets/widgets/qstatusbar.h index 42248d795893c08d6890e89f72c57d7fb355d364..92785aa4c43167a19f019af548e8f57ab6444ddc 100644 --- a/src/widgets/widgets/qstatusbar.h +++ b/src/widgets/widgets/qstatusbar.h @@ -50,7 +50,7 @@ class Q_WIDGETS_EXPORT QStatusBar: public QWidget Q_PROPERTY(bool sizeGripEnabled READ isSizeGripEnabled WRITE setSizeGripEnabled) public: - explicit QStatusBar(QWidget* parent=0); + explicit QStatusBar(QWidget *parent = Q_NULLPTR); virtual ~QStatusBar(); void addWidget(QWidget *widget, int stretch = 0); diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index b2973bd8b310677bb5f6f77ba84f9feee046eeed..f2e98474b34c942306db623f83e067fe7ff8c152 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -2299,7 +2299,7 @@ void QTabBar::setMovable(bool movable) \since 4.5 This property is used as a hint for styles to draw the tabs in a different - way then they would normally look in a tab widget. On Mac OS X this will + way then they would normally look in a tab widget. On OS X this will look similar to the tabs in Safari or Leopard's Terminal.app. \sa QTabWidget::documentMode diff --git a/src/widgets/widgets/qtabbar.h b/src/widgets/widgets/qtabbar.h index 6d8bdb0c86de42b3c3807588d08bb8b3b0df941b..94a83142b0da1a72848eb873351e954577dbc264 100644 --- a/src/widgets/widgets/qtabbar.h +++ b/src/widgets/widgets/qtabbar.h @@ -65,7 +65,7 @@ class Q_WIDGETS_EXPORT QTabBar: public QWidget Q_PROPERTY(bool changeCurrentOnDrag READ changeCurrentOnDrag WRITE setChangeCurrentOnDrag) public: - explicit QTabBar(QWidget* parent=0); + explicit QTabBar(QWidget *parent = Q_NULLPTR); ~QTabBar(); enum Shape { RoundedNorth, RoundedSouth, RoundedWest, RoundedEast, diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp index 8ca5f0dc0138588f2928e9db7f6bf737ce76351c..1edb5482063e7b2e3baac66e8cc76c5dd8124143 100644 --- a/src/widgets/widgets/qtabwidget.cpp +++ b/src/widgets/widgets/qtabwidget.cpp @@ -1318,7 +1318,7 @@ void QTabWidget::setUsesScrollButtons(bool useButtons) /*! \property QTabWidget::documentMode \brief Whether or not the tab widget is rendered in a mode suitable for document - pages. This is the same as document mode on Mac OS X. + pages. This is the same as document mode on OS X. \since 4.5 When this property is set the tab widget frame is not rendered. This mode is useful diff --git a/src/widgets/widgets/qtabwidget.h b/src/widgets/widgets/qtabwidget.h index 702563127d977c4457a8b3f7652701517bea7b35..f12d584475742a87303b02ae72fb4a4b788ac559 100644 --- a/src/widgets/widgets/qtabwidget.h +++ b/src/widgets/widgets/qtabwidget.h @@ -62,7 +62,7 @@ class Q_WIDGETS_EXPORT QTabWidget : public QWidget Q_PROPERTY(bool tabBarAutoHide READ tabBarAutoHide WRITE setTabBarAutoHide) public: - explicit QTabWidget(QWidget *parent = 0); + explicit QTabWidget(QWidget *parent = Q_NULLPTR); ~QTabWidget(); int addTab(QWidget *widget, const QString &); diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp index 9bf305a05507b554ab870ca601e9fea5e692e190..2c073342b085f22f6015473f47cbdfb16f3363b7 100644 --- a/src/widgets/widgets/qtextbrowser.cpp +++ b/src/widgets/widgets/qtextbrowser.cpp @@ -139,6 +139,7 @@ public: int lastKeypadScrollValue; #endif }; +Q_DECLARE_TYPEINFO(QTextBrowserPrivate::HistoryEntry, Q_MOVABLE_TYPE); QString QTextBrowserPrivate::findFile(const QUrl &name) const { diff --git a/src/widgets/widgets/qtextbrowser.h b/src/widgets/widgets/qtextbrowser.h index 4d4d9f4880f0626bd6eff38d1a5ebd40f0d200ad..339814e948ee586b09b96386c52a6ed4b9ba0dc1 100644 --- a/src/widgets/widgets/qtextbrowser.h +++ b/src/widgets/widgets/qtextbrowser.h @@ -57,7 +57,7 @@ class Q_WIDGETS_EXPORT QTextBrowser : public QTextEdit Q_PROPERTY(bool openLinks READ openLinks WRITE setOpenLinks) public: - explicit QTextBrowser(QWidget* parent = 0); + explicit QTextBrowser(QWidget* parent = Q_NULLPTR); virtual ~QTextBrowser(); QUrl source() const; diff --git a/src/widgets/widgets/qtextedit.h b/src/widgets/widgets/qtextedit.h index 689f45bea9eb5c07d1b274e57221b9dece54d26c..88b7444daa008e9b7d62ddb5836f553ac28c9f62 100644 --- a/src/widgets/widgets/qtextedit.h +++ b/src/widgets/widgets/qtextedit.h @@ -94,8 +94,8 @@ public: Q_DECLARE_FLAGS(AutoFormatting, AutoFormattingFlag) - explicit QTextEdit(QWidget *parent = 0); - explicit QTextEdit(const QString &text, QWidget *parent = 0); + explicit QTextEdit(QWidget *parent = Q_NULLPTR); + explicit QTextEdit(const QString &text, QWidget *parent = Q_NULLPTR); virtual ~QTextEdit(); void setDocument(QTextDocument *document); @@ -153,9 +153,9 @@ public: QTextOption::WrapMode wordWrapMode() const; void setWordWrapMode(QTextOption::WrapMode policy); - bool find(const QString &exp, QTextDocument::FindFlags options = 0); + bool find(const QString &exp, QTextDocument::FindFlags options = QTextDocument::FindFlags()); #ifndef QT_NO_REGEXP - bool find(const QRegExp &exp, QTextDocument::FindFlags options = 0); + bool find(const QRegExp &exp, QTextDocument::FindFlags options = QTextDocument::FindFlags()); #endif QString toPlainText() const; diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp index 08dea699e023c630c308d0f09f86b93c4ea77d28..1e4a39088c4ac486bc3137c946988bdfde1c688e 100644 --- a/src/widgets/widgets/qtoolbar.cpp +++ b/src/widgets/widgets/qtoolbar.cpp @@ -240,7 +240,7 @@ bool QToolBarPrivate::mousePressEvent(QMouseEvent *event) q->initStyleOption(&opt); if (q->style()->subElementRect(QStyle::SE_ToolBarHandle, &opt, q).contains(event->pos()) == false) { #ifdef Q_OS_OSX - // When using the unified toolbar on Mac OS X, the user can click and + // When using the unified toolbar on OS X, the user can click and // drag between toolbar contents to move the window. Make this work by // implementing the standard mouse-dragging code and then call // window->move() in mouseMoveEvent below. @@ -793,6 +793,82 @@ QAction *QToolBar::addAction(const QIcon &icon, const QString &text, return action; } +/*!\fn QAction *QToolBar::addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method) + + \since 5.6 + + \overload + + Creates a new action with the given \a text. This action is added to + the end of the toolbar. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a method of the \a receiver. +*/ + +/*!\fn QAction *QToolBar::addAction(const QString &text, Functor functor) + + \since 5.6 + + \overload + + Creates a new action with the given \a text. This action is added to + the end of the toolbar. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. +*/ + +/*!\fn QAction *QToolBar::addAction(const QString &text, const QObject *context, Functor functor) + + \since 5.6 + + \overload + + Creates a new action with the given \a text. This action is added to + the end of the toolbar. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. + + If \a context is destroyed, the functor will not be called. +*/ + +/*!\fn QAction *QToolBar::addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method) + + \since 5.6 + + \overload + + Creates a new action with the given \a icon and \a text. This + action is added to the end of the toolbar. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a method of the \a receiver. +*/ + +/*!\fn QAction *QToolBar::addAction(const QIcon &icon, const QString &text, Functor functor) + + \since 5.6 + + \overload + + Creates a new action with the given \a icon and \a text. This + action is added to the end of the toolbar. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. +*/ + +/*!\fn QAction *QToolBar::addAction(const QIcon &icon, const QString &text, const QObject *context, Functor functor) + + \since 5.6 + + \overload + + Creates a new action with the given \a icon and \a text. This + action is added to the end of the toolbar. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. + + If \a context is destroyed, the functor will not be called. +*/ + /*! Adds a separator to the end of the toolbar. diff --git a/src/widgets/widgets/qtoolbar.h b/src/widgets/widgets/qtoolbar.h index f9255776463e3bb1c20acdd174025090bdc46670..9eeb7ccd71f31ac3dff0a1d5d0b6d12e96fe9b48 100644 --- a/src/widgets/widgets/qtoolbar.h +++ b/src/widgets/widgets/qtoolbar.h @@ -34,6 +34,7 @@ #ifndef QDYNAMICTOOLBAR_H #define QDYNAMICTOOLBAR_H +#include <QtWidgets/qaction.h> #include <QtWidgets/qwidget.h> QT_BEGIN_NAMESPACE @@ -68,8 +69,8 @@ class Q_WIDGETS_EXPORT QToolBar : public QWidget Q_PROPERTY(bool floatable READ isFloatable WRITE setFloatable) public: - explicit QToolBar(const QString &title, QWidget *parent = 0); - explicit QToolBar(QWidget *parent = 0); + explicit QToolBar(const QString &title, QWidget *parent = Q_NULLPTR); + explicit QToolBar(QWidget *parent = Q_NULLPTR); ~QToolBar(); void setMovable(bool movable); @@ -92,6 +93,51 @@ public: QAction *addAction(const QString &text, const QObject *receiver, const char* member); QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member); +#ifdef Q_QDOC + QAction *addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method); + QAction *addAction(const QString &text, Functor functor); + QAction *addAction(const QString &text, const QObject *context, Functor functor); + QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method); + QAction *addAction(const QIcon &icon, const QString &text, Functor functor); + QAction *addAction(const QIcon &icon, const QString &text, const QObject *context, Functor functor); +#else + // addAction(QString): Connect to a QObject slot / functor or function pointer (with context) + template<class Obj, typename Func1> + inline typename QtPrivate::QEnableIf<!QtPrivate::is_same<const char*, Func1>::value + && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::Type + addAction(const QString &text, const Obj *object, Func1 slot) + { + QAction *result = addAction(text); + connect(result, &QAction::triggered, object, slot); + return result; + } + // addAction(QString): Connect to a functor or function pointer (without context) + template <typename Func1> + inline QAction *addAction(const QString &text, Func1 slot) + { + QAction *result = addAction(text); + connect(result, &QAction::triggered, slot); + return result; + } + // addAction(QString): Connect to a QObject slot / functor or function pointer (with context) + template<class Obj, typename Func1> + inline typename QtPrivate::QEnableIf<!QtPrivate::is_same<const char*, Func1>::value + && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::Type + addAction(const QIcon &actionIcon, const QString &text, const Obj *object, Func1 slot) + { + QAction *result = addAction(actionIcon, text); + connect(result, &QAction::triggered, object, slot); + return result; + } + // addAction(QIcon, QString): Connect to a functor or function pointer (without context) + template <typename Func1> + inline QAction *addAction(const QIcon &actionIcon, const QString &text, Func1 slot) + { + QAction *result = addAction(actionIcon, text); + connect(result, &QAction::triggered, slot); + return result; + } +#endif // !Q_QDOC QAction *addSeparator(); QAction *insertSeparator(QAction *before); diff --git a/src/widgets/widgets/qtoolbox.h b/src/widgets/widgets/qtoolbox.h index cff5ae09ae0dec9f6eae6ef376c359a512b226a7..42b06e205c7d3c64e3ad772a2d22823576cbf51f 100644 --- a/src/widgets/widgets/qtoolbox.h +++ b/src/widgets/widgets/qtoolbox.h @@ -51,7 +51,7 @@ class Q_WIDGETS_EXPORT QToolBox : public QFrame Q_PROPERTY(int count READ count) public: - explicit QToolBox(QWidget *parent = 0, Qt::WindowFlags f = 0); + explicit QToolBox(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); ~QToolBox(); int addItem(QWidget *widget, const QString &text); diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp index 8473b261fccb20e878ea294cc65f875005152ca0..93f0b6005834468c892f0b5a84610155bd7424de 100644 --- a/src/widgets/widgets/qtoolbutton.cpp +++ b/src/widgets/widgets/qtoolbutton.cpp @@ -863,7 +863,7 @@ QToolButton::ToolButtonPopupMode QToolButton::popupMode() const The default is disabled (i.e. false). - This property is currently ignored on Mac OS X when using QMacStyle. + This property is currently ignored on OS X when using QMacStyle. */ void QToolButton::setAutoRaise(bool enable) { diff --git a/src/widgets/widgets/qtoolbutton.h b/src/widgets/widgets/qtoolbutton.h index 69ad032324d23828a0b968a71fc1db145bc06629..c76f58577b6f55b0bd092eeb5aa88657dcbc1e41 100644 --- a/src/widgets/widgets/qtoolbutton.h +++ b/src/widgets/widgets/qtoolbutton.h @@ -64,7 +64,7 @@ public: }; Q_ENUM(ToolButtonPopupMode) - explicit QToolButton(QWidget * parent=0); + explicit QToolButton(QWidget *parent = Q_NULLPTR); ~QToolButton(); QSize sizeHint() const Q_DECL_OVERRIDE; diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index 22d199fc7471396ae549011f908cf1d23ad4fff4..deca002bf5eb1468207dac93286982a7bc9e259b 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -248,7 +248,7 @@ bool QWidgetTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e) return false; } -// Except for pageup and pagedown, Mac OS X has very different behavior, we don't do it all, but +// Except for pageup and pagedown, OS X has very different behavior, we don't do it all, but // here's the breakdown: // Shift still works as an anchor, but only one of the other keys can be down Ctrl (Command), // Alt (Option), or Meta (Control). @@ -2439,10 +2439,13 @@ QList<QTextEdit::ExtraSelection> QWidgetTextControl::extraSelections() const { Q_D(const QWidgetTextControl); QList<QTextEdit::ExtraSelection> selections; - for (int i = 0; i < d->extraSelections.count(); ++i) { + const int numExtraSelections = d->extraSelections.count(); + selections.reserve(numExtraSelections); + for (int i = 0; i < numExtraSelections; ++i) { QTextEdit::ExtraSelection sel; - sel.cursor = d->extraSelections.at(i).cursor; - sel.format = d->extraSelections.at(i).format; + const QAbstractTextDocumentLayout::Selection &sel2 = d->extraSelections.at(i); + sel.cursor = sel2.cursor; + sel.format = sel2.format; selections.append(sel); } return selections; diff --git a/src/widgets/widgets/widgets.pri b/src/widgets/widgets/widgets.pri index 342d2093dbd887d8b130220d0a474b8666a07762..c31a7f7682462c22c6fbb0db301bf25b890dd11f 100644 --- a/src/widgets/widgets/widgets.pri +++ b/src/widgets/widgets/widgets.pri @@ -154,7 +154,7 @@ macx { widgets/qmaccocoaviewcontainer_mac.mm } -wince*: { +wince { SOURCES += widgets/qmenu_wince.cpp HEADERS += widgets/qmenu_wince_resource_p.h RC_FILE = widgets/qmenu_wince.rc diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index e68da520e7780ecc9a5d4c9673ee73cb9df14b54..141e3ed135921cb92480aa646db38f948963986c 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -67,7 +67,6 @@ extern "C" { #include <qvector.h> #include <qdir.h> #include <qstandardpaths.h> -#include <qthread.h> #include <wrl.h> #include <Windows.ApplicationModel.core.h> @@ -276,9 +275,6 @@ int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int) if (FAILED(RoInitialize(RO_INIT_MULTITHREADED))) return 1; - // Mark the main thread - QThread::currentThread(); - Core::ICoreApplication *appFactory; if (FAILED(RoGetActivationFactory(qHString(CoreApplicationClass), IID_PPV_ARGS(&appFactory)))) return 2; diff --git a/src/winmain/winmain.pro b/src/winmain/winmain.pro index b891e4bce0dc442a0be4e0e9048f056da74361b7..e8c9ace03b0db9c863f264fc0ba22aea1c4f456f 100644 --- a/src/winmain/winmain.pro +++ b/src/winmain/winmain.pro @@ -32,4 +32,4 @@ load(qt_targets) load(qt_build_paths) load(qt_common) -wince*:QMAKE_POST_LINK = +wince: QMAKE_POST_LINK = diff --git a/src/xml/dom/qdom.h b/src/xml/dom/qdom.h index 5a83659e5ce726307359581e0a2217f1ef2a139f..f2bcf83e2b1c47bb0f85d81fe5b9108bfc40fe4e 100644 --- a/src/xml/dom/qdom.h +++ b/src/xml/dom/qdom.h @@ -329,14 +329,14 @@ public: inline QDomNode::NodeType nodeType() const { return DocumentNode; } // Qt extensions - bool setContent(const QByteArray& text, bool namespaceProcessing, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); - bool setContent(const QString& text, bool namespaceProcessing, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); - bool setContent(QIODevice* dev, bool namespaceProcessing, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); - bool setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); - bool setContent(const QByteArray& text, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); - bool setContent(const QString& text, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); - bool setContent(QIODevice* dev, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); - bool setContent(QXmlInputSource *source, QXmlReader *reader, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); + bool setContent(const QByteArray& text, bool namespaceProcessing, QString *errorMsg=Q_NULLPTR, int *errorLine=Q_NULLPTR, int *errorColumn=Q_NULLPTR ); + bool setContent(const QString& text, bool namespaceProcessing, QString *errorMsg=Q_NULLPTR, int *errorLine=Q_NULLPTR, int *errorColumn=Q_NULLPTR ); + bool setContent(QIODevice* dev, bool namespaceProcessing, QString *errorMsg=Q_NULLPTR, int *errorLine=Q_NULLPTR, int *errorColumn=Q_NULLPTR ); + bool setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg=Q_NULLPTR, int *errorLine=Q_NULLPTR, int *errorColumn=Q_NULLPTR ); + bool setContent(const QByteArray& text, QString *errorMsg=Q_NULLPTR, int *errorLine=Q_NULLPTR, int *errorColumn=Q_NULLPTR ); + bool setContent(const QString& text, QString *errorMsg=Q_NULLPTR, int *errorLine=Q_NULLPTR, int *errorColumn=Q_NULLPTR ); + bool setContent(QIODevice* dev, QString *errorMsg=Q_NULLPTR, int *errorLine=Q_NULLPTR, int *errorColumn=Q_NULLPTR ); + bool setContent(QXmlInputSource *source, QXmlReader *reader, QString *errorMsg=Q_NULLPTR, int *errorLine=Q_NULLPTR, int *errorColumn=Q_NULLPTR ); // Qt extensions QString toString(int = 1) const; diff --git a/src/xml/sax/qxml.h b/src/xml/sax/qxml.h index d7285fc2896d35930ee2871307542b94378c592d..6bb9bfbe9ca505a1da718220866fdde22beff1fe 100644 --- a/src/xml/sax/qxml.h +++ b/src/xml/sax/qxml.h @@ -201,10 +201,10 @@ class Q_XML_EXPORT QXmlReader { public: virtual ~QXmlReader() {} - virtual bool feature(const QString& name, bool *ok = 0) const = 0; + virtual bool feature(const QString& name, bool *ok = Q_NULLPTR) const = 0; virtual void setFeature(const QString& name, bool value) = 0; virtual bool hasFeature(const QString& name) const = 0; - virtual void* property(const QString& name, bool *ok = 0) const = 0; + virtual void* property(const QString& name, bool *ok = Q_NULLPTR) const = 0; virtual void setProperty(const QString& name, void* value) = 0; virtual bool hasProperty(const QString& name) const = 0; virtual void setEntityResolver(QXmlEntityResolver* handler) = 0; @@ -229,11 +229,11 @@ public: QXmlSimpleReader(); virtual ~QXmlSimpleReader(); - bool feature(const QString& name, bool *ok = 0) const Q_DECL_OVERRIDE; + bool feature(const QString& name, bool *ok = Q_NULLPTR) const Q_DECL_OVERRIDE; void setFeature(const QString& name, bool value) Q_DECL_OVERRIDE; bool hasFeature(const QString& name) const Q_DECL_OVERRIDE; - void* property(const QString& name, bool *ok = 0) const Q_DECL_OVERRIDE; + void* property(const QString& name, bool *ok = Q_NULLPTR) const Q_DECL_OVERRIDE; void setProperty(const QString& name, void* value) Q_DECL_OVERRIDE; bool hasProperty(const QString& name) const Q_DECL_OVERRIDE; diff --git a/src/xml/sax/qxml_p.h b/src/xml/sax/qxml_p.h index 7712b5760ceb6c7c15fe778d36a06e0dd411cce6..013c2618a3d0d25b6572758298fed81808b1839d 100644 --- a/src/xml/sax/qxml_p.h +++ b/src/xml/sax/qxml_p.h @@ -104,6 +104,7 @@ private: QString value; int index; }; + friend class QTypeInfo<XmlRef>; QStack<XmlRef> xmlRefStack; // used for standalone declaration @@ -166,6 +167,7 @@ private: ParseFunction function; int state; }; + friend class QTypeInfo<ParseState>; QStack<ParseState> *parseStack; // used in parseProlog() @@ -294,6 +296,8 @@ private: friend class QXmlSimpleReaderLocator; friend class QDomHandler; }; +Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::ParseState, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::XmlRef, Q_MOVABLE_TYPE); QT_END_NAMESPACE diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index a46b8af4fff7804b2c30ebdcd8a7d4815c0228c4..6f06ba591f80a40c9168ad3d0de9bd8ce10d2fa7 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -21,7 +21,7 @@ installed_cmake.depends = cmake ios: SUBDIRS = corelib gui -wince*: SUBDIRS -= printsupport +wince: SUBDIRS -= printsupport cross_compile: SUBDIRS -= tools !qtHaveModule(opengl): SUBDIRS -= opengl !qtHaveModule(gui): SUBDIRS -= gui cmake diff --git a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp index b5e3dee9a61a0df8c5463c6ea00c9e08ae73e4eb..cadd4e82cd66301a6ed50b1acce2b9fab3222470 100644 --- a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp +++ b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp @@ -1443,45 +1443,45 @@ void tst_QtConcurrentFilter::noDetach() QVERIFY(l.isDetached()); QList<int> ll = l; - QVERIFY(l.isDetached() == false); + QVERIFY(!l.isDetached()); QtConcurrent::filtered(l, waitFilterfn).waitForFinished(); - QVERIFY(l.isDetached() == false); - QVERIFY(ll.isDetached() == false); + QVERIFY(!l.isDetached()); + QVERIFY(!ll.isDetached()); QtConcurrent::blockingFiltered(l, waitFilterfn); - QVERIFY(l.isDetached() == false); - QVERIFY(ll.isDetached() == false); + QVERIFY(!l.isDetached()); + QVERIFY(!ll.isDetached()); QtConcurrent::filteredReduced(l, waitFilterfn, intSumReduce).waitForFinished(); - QVERIFY(l.isDetached() == false); - QVERIFY(ll.isDetached() == false); + QVERIFY(!l.isDetached()); + QVERIFY(!ll.isDetached()); QtConcurrent::filter(l, waitFilterfn).waitForFinished(); if (!l.isDetached()) QEXPECT_FAIL("", "QTBUG-20688: Known unstable failure", Abort); - QVERIFY(l.isDetached() == true); - QVERIFY(ll.isDetached() == true); + QVERIFY(l.isDetached()); + QVERIFY(ll.isDetached()); } { const QList<int> l = QList<int>() << 1; QVERIFY(l.isDetached()); const QList<int> ll = l; - QVERIFY(l.isDetached() == false); + QVERIFY(!l.isDetached()); QtConcurrent::filtered(l, waitFilterfn).waitForFinished(); - QVERIFY(l.isDetached() == false); - QVERIFY(ll.isDetached() == false); + QVERIFY(!l.isDetached()); + QVERIFY(!ll.isDetached()); QtConcurrent::filteredReduced(l, waitFilterfn, intSumReduce).waitForFinished(); - QVERIFY(l.isDetached() == false); - QVERIFY(ll.isDetached() == false); + QVERIFY(!l.isDetached()); + QVERIFY(!ll.isDetached()); } } diff --git a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp index 4e19124ca82a918a146e3d4a87b298b6242f103d..33941d8e902455b450ae1b7e95275fa553fe0559 100644 --- a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp +++ b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -2250,38 +2250,38 @@ void tst_QtConcurrentMap::noDetach() QVERIFY(l.isDetached()); QList<int> ll = l; - QVERIFY(l.isDetached() == false); + QVERIFY(!l.isDetached()); QtConcurrent::mapped(l, mapper).waitForFinished(); - QVERIFY(l.isDetached() == false); - QVERIFY(ll.isDetached() == false); + QVERIFY(!l.isDetached()); + QVERIFY(!ll.isDetached()); QtConcurrent::mappedReduced(l, mapper, intSumReduce).waitForFinished(); - QVERIFY(l.isDetached() == false); - QVERIFY(ll.isDetached() == false); + QVERIFY(!l.isDetached()); + QVERIFY(!ll.isDetached()); QtConcurrent::map(l, multiplyBy2Immutable).waitForFinished(); - QVERIFY(l.isDetached() == true); - QVERIFY(ll.isDetached() == true); + QVERIFY(l.isDetached()); + QVERIFY(ll.isDetached()); } { const QList<int> l = QList<int>() << 1; QVERIFY(l.isDetached()); const QList<int> ll = l; - QVERIFY(l.isDetached() == false); + QVERIFY(!l.isDetached()); QtConcurrent::mapped(l, mapper).waitForFinished(); - QVERIFY(l.isDetached() == false); - QVERIFY(ll.isDetached() == false); + QVERIFY(!l.isDetached()); + QVERIFY(!ll.isDetached()); QtConcurrent::mappedReduced(l, mapper, intSumReduce).waitForFinished(); - QVERIFY(l.isDetached() == false); - QVERIFY(ll.isDetached() == false); + QVERIFY(!l.isDetached()); + QVERIFY(!ll.isDetached()); } } diff --git a/tests/auto/corelib/animation/qpauseanimation/BLACKLIST b/tests/auto/corelib/animation/qpauseanimation/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..3b2cd847495e1397a6abfdc14796f01ac6576c62 --- /dev/null +++ b/tests/auto/corelib/animation/qpauseanimation/BLACKLIST @@ -0,0 +1,4 @@ +[multiplePauseAnimations] +osx-10.9 +[pauseAndPropertyAnimations] +* diff --git a/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST b/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..a7e95b1e9742ce5c061844249908e10391687a88 --- /dev/null +++ b/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST @@ -0,0 +1,4 @@ +[statesAndSignals:normal animation] +windows +[startBackwardWithoutEndValue] +windows diff --git a/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST b/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..e11e4ae6fbce70e16008f247fd47c40e5d54056f --- /dev/null +++ b/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST @@ -0,0 +1,4 @@ +[startGroupWithRunningChild] +windows +[finishWithUncontrolledAnimation] +windows diff --git a/tests/auto/corelib/codecs/qtextcodec/qtextcodec.pro b/tests/auto/corelib/codecs/qtextcodec/qtextcodec.pro index 0bcf067c4f3b1f479ec127512d92f1c53e71548b..9f2e4f9c925e6572e2ee6687e5201acb829348c3 100644 --- a/tests/auto/corelib/codecs/qtextcodec/qtextcodec.pro +++ b/tests/auto/corelib/codecs/qtextcodec/qtextcodec.pro @@ -1,4 +1,4 @@ TEMPLATE = subdirs SUBDIRS = test -!wince*:SUBDIRS += echo +!wince: SUBDIRS += echo diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp index 69bf7598fc2f6c2eee99127ecb8297885c6b2949..00f70f538096825db10184851f43db2d2a46c403 100644 --- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp +++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp @@ -457,7 +457,7 @@ void tst_QGlobal::isEnum() // fallback type traits implementation. Any compiler // supported by Qt that supports C++0x class enums // should also support the __is_enum intrinsic. - QVERIFY(Q_IS_ENUM(isEnum_G) == true); + QVERIFY(Q_IS_ENUM(isEnum_G)); #endif #undef IS_ENUM_TRUE diff --git a/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp b/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp index 68129f9081f4c6677252b36101df1f069874e013..e9fd999e9fb062c6e10d62178f3cd46060c8d9d0 100644 --- a/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp +++ b/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp @@ -57,7 +57,7 @@ private Q_SLOTS: void api(); void constVolatile(); void exception(); - void threadedException(); + void catchExceptionAndRetry(); void threadStressTest(); void afterDestruction(); }; @@ -163,7 +163,7 @@ void tst_QGlobalStatic::exception() QBasicAtomicInt exceptionControlVar = Q_BASIC_ATOMIC_INITIALIZER(1); Q_GLOBAL_STATIC_WITH_ARGS(ThrowingType, exceptionGS, (exceptionControlVar)) -void tst_QGlobalStatic::threadedException() +void tst_QGlobalStatic::catchExceptionAndRetry() { if (exceptionControlVar.load() != 1) QSKIP("This test cannot be run more than once"); diff --git a/tests/auto/corelib/global/qnumeric/qnumeric.pro b/tests/auto/corelib/global/qnumeric/qnumeric.pro index 4cfb3fa7ac38fc158137f4685fdbca34d38a66e1..00f3635be956d9770cfefac978d53d99248e27fe 100644 --- a/tests/auto/corelib/global/qnumeric/qnumeric.pro +++ b/tests/auto/corelib/global/qnumeric/qnumeric.pro @@ -3,3 +3,5 @@ TARGET = tst_qnumeric QT = core testlib SOURCES = tst_qnumeric.cpp DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 +intel_icc: QMAKE_CXXFLAGS += -fp-model strict +intel_icl: QMAKE_CXXFLAGS += /fp:strict diff --git a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp index 9a50df379cd599ad5391bf3c0347455d64d84730..fdc8bc6aabc7748ff14a0e09ec8d086ab86df9bc 100644 --- a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp +++ b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp @@ -107,13 +107,7 @@ void tst_QNumeric::qNan() QVERIFY(qIsInf(-inf)); QVERIFY(qIsInf(2*inf)); QCOMPARE(1/inf, 0.0); -#ifdef Q_CC_INTEL - QEXPECT_FAIL("", "ICC optimizes zero * anything to zero", Continue); -#endif QVERIFY(qIsNaN(0*nan)); -#ifdef Q_CC_INTEL - QEXPECT_FAIL("", "ICC optimizes zero * anything to zero", Continue); -#endif QVERIFY(qIsNaN(0*inf)); QVERIFY(qFuzzyCompare(1/inf, 0.0)); } diff --git a/tests/auto/corelib/io/largefile/largefile.pro b/tests/auto/corelib/io/largefile/largefile.pro index 55878196cdb577325ff0f0d41d63e33dc2d39c10..d9938d07d5a6c7275c9009df63d8836cfe884a76 100644 --- a/tests/auto/corelib/io/largefile/largefile.pro +++ b/tests/auto/corelib/io/largefile/largefile.pro @@ -3,5 +3,5 @@ TARGET = tst_largefile QT = core testlib SOURCES = tst_largefile.cpp -wince*: SOURCES += $$QT_SOURCE_TREE/src/corelib/kernel/qfunctions_wince.cpp +wince: SOURCES += $$QT_SOURCE_TREE/src/corelib/kernel/qfunctions_wince.cpp DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp index 9d29b5401ffad280b9b73d1f3f950184bf4df4af..2cf93e1c459624b00a3d5cfcab9d53097251d58b 100644 --- a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp @@ -1837,7 +1837,7 @@ static QRegion qRegionData(int index) case 12: return QRegion(0, 0, 3, 3, QRegion::Ellipse); #else case 7: - qWarning("Skipping streaming of elliptical regions on embedded, Mac OS X, and X11;" + qWarning("Skipping streaming of elliptical regions on embedded, OS X, and X11;" " our pointarray stuff is not that great at approximating."); #endif } diff --git a/tests/auto/corelib/io/qdir/qdir.pro b/tests/auto/corelib/io/qdir/qdir.pro index d3e954bd32f4ad06343a5edc41a89e98f2526c71..0adc7e045032804a6f621bb782f00fb256c53371 100644 --- a/tests/auto/corelib/io/qdir/qdir.pro +++ b/tests/auto/corelib/io/qdir/qdir.pro @@ -10,3 +10,5 @@ DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 android:!android-no-sdk { RESOURCES += android_testdata.qrc } + +win32: CONFIG += insignificant_test # Crashes on Windows in release builds diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index e8a7105f6ee984c476123c3647fe29e96d87461a..72d036c2aed230024a24cf8bb81196893135bd3f 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -470,21 +470,22 @@ void tst_QDir::removeRecursivelyFailure() #ifdef Q_OS_UNIX QFile dirAsFile(path); // yay, I have to use QFile to change a dir's permissions... QVERIFY(dirAsFile.setPermissions(QFile::Permissions(0))); // no permissions -#else - QVERIFY(file.setPermissions(QFile::ReadOwner)); -#endif + QVERIFY(!QDir().rmdir(path)); QDir dir(path); QVERIFY(!dir.removeRecursively()); // didn't work QVERIFY(dir.exists()); // still exists -#ifdef Q_OS_UNIX QVERIFY(dirAsFile.setPermissions(QFile::Permissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner))); -#else - QVERIFY(file.setPermissions(QFile::ReadOwner | QFile::WriteOwner)); -#endif QVERIFY(dir.removeRecursively()); QVERIFY(!dir.exists()); +#else // Q_OS_UNIX + QVERIFY(file.setPermissions(QFile::ReadOwner)); + QVERIFY(!QDir().rmdir(path)); + QDir dir(path); + QVERIFY(dir.removeRecursively()); + QVERIFY(!dir.exists()); +#endif // !Q_OS_UNIX } void tst_QDir::removeRecursivelySymlink() @@ -1366,6 +1367,9 @@ void tst_QDir::relativeFilePath_data() QTest::newRow("11") << "" << "" << ""; + QTest::newRow("same path 1") << "/tmp" << "/tmp" << "."; + QTest::newRow("same path 2") << "//tmp" << "/tmp/" << "."; + #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) QTest::newRow("12") << "C:/foo/bar" << "ding" << "ding"; QTest::newRow("13") << "C:/foo/bar" << "C:/ding/dong" << "../../ding/dong"; @@ -1373,10 +1377,10 @@ void tst_QDir::relativeFilePath_data() QTest::newRow("15") << "C:/foo/bar" << "D:/ding/dong" << "D:/ding/dong"; QTest::newRow("16") << "C:" << "C:/ding/dong" << "ding/dong"; QTest::newRow("17") << "C:/" << "C:/ding/dong" << "ding/dong"; - QTest::newRow("18") << "C:" << "C:" << ""; - QTest::newRow("19") << "C:/" << "C:" << ""; - QTest::newRow("20") << "C:" << "C:/" << ""; - QTest::newRow("21") << "C:/" << "C:/" << ""; + QTest::newRow("18") << "C:" << "C:" << "."; + QTest::newRow("19") << "C:/" << "C:" << "."; + QTest::newRow("20") << "C:" << "C:/" << "."; + QTest::newRow("21") << "C:/" << "C:/" << "."; QTest::newRow("22") << "C:" << "C:file.txt" << "file.txt"; QTest::newRow("23") << "C:/" << "C:file.txt" << "file.txt"; QTest::newRow("24") << "C:" << "C:/file.txt" << "file.txt"; diff --git a/tests/auto/corelib/io/qdiriterator/qdiriterator.pro b/tests/auto/corelib/io/qdiriterator/qdiriterator.pro index 3b5d2bd931bd1de2fd63e758e39a850fc19901d9..a2429bf2f0d95b6893e64280a64561c65e2412f5 100644 --- a/tests/auto/corelib/io/qdiriterator/qdiriterator.pro +++ b/tests/auto/corelib/io/qdiriterator/qdiriterator.pro @@ -8,3 +8,5 @@ TESTDATA += entrylist wince*mips*|wincewm50smart-msvc200*: DEFINES += WINCE_BROKEN_ITERATE=1 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +win32: CONFIG += insignificant_test # Crashes on Windows in release builds diff --git a/tests/auto/corelib/io/qfile/test/test.pro b/tests/auto/corelib/io/qfile/test/test.pro index 03863e994311c78517b1922ef8373c219ab73959..9aa4119795fbccdcc4219aa730bc303289386573 100644 --- a/tests/auto/corelib/io/qfile/test/test.pro +++ b/tests/auto/corelib/io/qfile/test/test.pro @@ -7,7 +7,7 @@ else: DEFINES += QT_NO_NETWORK TARGET = ../tst_qfile SOURCES = ../tst_qfile.cpp -wince*: SOURCES += $$QT_SOURCE_TREE/src/corelib/kernel/qfunctions_wince.cpp +wince: SOURCES += $$QT_SOURCE_TREE/src/corelib/kernel/qfunctions_wince.cpp RESOURCES += ../qfile.qrc ../rename-fallback.qrc ../copy-fallback.qrc diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 5025dd38db28f03b53f6690c8d21ff892e2ce21a..b423e857d073735a1f503eb5b9e732b021ae309d 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -2192,7 +2192,7 @@ void tst_QFile::removeOpenFile() bool opened = f.open(QIODevice::ReadOnly); QVERIFY(opened); f.readAll(); - // this used to only fail on FreeBSD (and Mac OS X) + // this used to only fail on FreeBSD (and OS X) QVERIFY(f.flush()); bool removed = f.remove(); // remove should both close and remove the file QVERIFY(removed); diff --git a/tests/auto/corelib/io/qfileinfo/qfileinfo.pro b/tests/auto/corelib/io/qfileinfo/qfileinfo.pro index aa5a9d92f1acc8dd6ea447811740170e20ae49bc..571637be373ec83297e208bea1289ef7dc5e1218 100644 --- a/tests/auto/corelib/io/qfileinfo/qfileinfo.pro +++ b/tests/auto/corelib/io/qfileinfo/qfileinfo.pro @@ -5,5 +5,7 @@ SOURCES = tst_qfileinfo.cpp RESOURCES += qfileinfo.qrc \ testdata.qrc -win32*:!wince*:!winrt:LIBS += -ladvapi32 -lnetapi32 +win32:!wince:!winrt:LIBS += -ladvapi32 -lnetapi32 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +win32: CONFIG += insignificant_test # Crashes on Windows in release builds diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index 62e183f61939ddb9a8e992ff83b63ac53fa292f2..bbee33ac7897241f634e7c485cf8a15371a36968 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -263,30 +263,32 @@ private slots: private: const QString m_currentDir; - QString m_dataPath; QString m_sourceFile; QString m_proFile; QString m_resourcesDir; QTemporaryDir m_dir; + QSharedPointer<QTemporaryDir> m_dataDir; }; void tst_QFileInfo::initTestCase() { - m_dataPath = QEXTRACTTESTDATA("/testdata"); - QVERIFY(!m_dataPath.isEmpty()); + m_dataDir = QEXTRACTTESTDATA("/testdata"); + QVERIFY(m_dataDir); + const QString dataPath = m_dataDir->path(); + QVERIFY(!dataPath.isEmpty()); - m_sourceFile = m_dataPath + QStringLiteral("/tst_qfileinfo.cpp"); - m_resourcesDir = m_dataPath + QStringLiteral("/resources"); - m_proFile = m_dataPath + QStringLiteral("/tst_qfileinfo.pro"); + m_sourceFile = dataPath + QLatin1String("/tst_qfileinfo.cpp"); + m_resourcesDir = dataPath + QLatin1String("/resources"); + m_proFile = dataPath + QLatin1String("/tst_qfileinfo.pro"); - QVERIFY(m_dir.isValid()); + QVERIFY2(m_dir.isValid(), + ("Failed to create temporary dir: " + m_dir.errorString()).toUtf8()); QVERIFY(QDir::setCurrent(m_dir.path())); } void tst_QFileInfo::cleanupTestCase() { QDir::setCurrent(m_currentDir); // Release temporary directory so that it can be deleted on Windows - QDir(m_dataPath).removeRecursively(); } // Testing get/set functions @@ -609,6 +611,16 @@ void tst_QFileInfo::canonicalPath() QCOMPARE(fi.canonicalPath(), QFileInfo(QDir::tempPath()).canonicalFilePath()); } +class FileDeleter { + Q_DISABLE_COPY(FileDeleter) +public: + explicit FileDeleter(const QString fileName) : m_fileName(fileName) {} + ~FileDeleter() { QFile::remove(m_fileName); } + +private: + const QString m_fileName; +}; + void tst_QFileInfo::canonicalFilePath() { const QString fileName("tmp.canon"); @@ -639,9 +651,13 @@ void tst_QFileInfo::canonicalFilePath() QCOMPARE(info1.canonicalFilePath(), info2.canonicalFilePath()); } } + + const QString dirSymLinkName = QLatin1String("tst_qfileinfo") + + QDateTime::currentDateTime().toString(QLatin1String("yyMMddhhmmss")); + const QString link(QDir::tempPath() + QLatin1Char('/') + dirSymLinkName); + FileDeleter dirSymLinkDeleter(link); + { - const QString link(QDir::tempPath() + QDir::separator() + "tst_qfileinfo"); - QFile::remove(link); QFile file(QDir::currentPath()); if (file.link(link)) { QFile tempfile("tempfile.txt"); @@ -666,12 +682,12 @@ void tst_QFileInfo::canonicalFilePath() } } { - QString link(QDir::tempPath() + QDir::separator() + "tst_qfileinfo" - + QDir::separator() + "link_to_tst_qfileinfo"); + QString link(QDir::tempPath() + QLatin1Char('/') + dirSymLinkName + + "/link_to_tst_qfileinfo"); QFile::remove(link); - QFile file(QDir::tempPath() + QDir::separator() + "tst_qfileinfo" - + QDir::separator() + "tst_qfileinfo.cpp"); + QFile file(QDir::tempPath() + QLatin1Char('/') + dirSymLinkName + + "tst_qfileinfo.cpp"); if (file.link(link)) { QFileInfo info1("tst_qfileinfo.cpp"); @@ -1266,7 +1282,7 @@ void tst_QFileInfo::isHidden_data() #endif #if defined(Q_OS_MAC) - // /bin has the hidden attribute on Mac OS X + // /bin has the hidden attribute on OS X QTest::newRow("/bin/") << QString::fromLatin1("/bin/") << true; #elif !defined(Q_OS_WIN) QTest::newRow("/bin/") << QString::fromLatin1("/bin/") << false; diff --git a/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST b/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST index 3ac0b9dff452688138bacf957f735b82644d6244..10a4ba069e32795bb1c68452f4afad655448a8e4 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST +++ b/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST @@ -6,3 +6,4 @@ windows 64bit msvc osx [watchFileAndItsDirectory:native backend-specialchars] osx +windows diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index 0ebfd2ae350a5c72d3b63cdcad091ecb82821f9f..a0434aa8eee11853aa3877058aab4f3c004fc43a 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -62,6 +62,7 @@ private slots: void removePath(); void addPaths(); void removePaths(); + void removePathsFilesInSameDirectory(); void watchFileAndItsDirectory_data() { basicTest_data(); } void watchFileAndItsDirectory(); @@ -460,6 +461,31 @@ void tst_QFileSystemWatcher::removePaths() watcher.removePaths(paths); } +void tst_QFileSystemWatcher::removePathsFilesInSameDirectory() +{ + // QTBUG-46449/Windows: Check the return values of removePaths(). + // When adding the 1st file, a thread is started to watch the temp path. + // After adding and removing the 2nd file, the thread is still running and + // success should be reported. + QTemporaryFile file1(m_tempDirPattern); + QTemporaryFile file2(m_tempDirPattern); + QVERIFY2(file1.open(), qPrintable(file1.errorString())); + QVERIFY2(file2.open(), qPrintable(file1.errorString())); + const QString path1 = file1.fileName(); + const QString path2 = file2.fileName(); + file1.close(); + file2.close(); + QFileSystemWatcher watcher; + QVERIFY(watcher.addPath(path1)); + QCOMPARE(watcher.files().size(), 1); + QVERIFY(watcher.addPath(path2)); + QCOMPARE(watcher.files().size(), 2); + QVERIFY(watcher.removePath(path1)); + QCOMPARE(watcher.files().size(), 1); + QVERIFY(watcher.removePath(path2)); + QCOMPARE(watcher.files().size(), 0); +} + static QByteArray msgFileOperationFailed(const char *what, const QFile &f) { return what + QByteArrayLiteral(" failed on \"") @@ -527,7 +553,7 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory() timer.start(3000); eventLoop.exec(); int fileChangedSpyCount = fileChangedSpy.count(); -#ifdef Q_OS_WIN64 +#ifdef Q_OS_WIN if (fileChangedSpyCount != 0) QEXPECT_FAIL("", "See QTBUG-30943", Continue); #endif diff --git a/tests/auto/corelib/io/qiodevice/BLACKLIST b/tests/auto/corelib/io/qiodevice/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..b8a61d3ca97edbecc61a04e489b5c0b80f3ee96d --- /dev/null +++ b/tests/auto/corelib/io/qiodevice/BLACKLIST @@ -0,0 +1,2 @@ +[unget] +redhatenterpriselinuxworkstation-6.6 diff --git a/tests/auto/corelib/io/qprocess/BLACKLIST b/tests/auto/corelib/io/qprocess/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..dcd913ca49dfcff36ee0c904452da22c1282e19f --- /dev/null +++ b/tests/auto/corelib/io/qprocess/BLACKLIST @@ -0,0 +1,2 @@ +[lockupsInStartDetached] +redhatenterpriselinuxworkstation-6.6 diff --git a/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro b/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro index 7f3b8ade3e91b139058fba59a535f7396f683c03..b59241851fd5580d10497284a40427bbc7cf9a70 100644 --- a/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro +++ b/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro @@ -1,6 +1,6 @@ win32 { SOURCES = main_win.cpp - !wince*:LIBS += -luser32 + !wince: LIBS += -luser32 } unix { SOURCES = main_unix.cpp diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index 399e9b9222aae14cc6d8cbb0f488998f698071ee..02501ca9d986a4becd08b3d86e76265a4d94760e 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -122,9 +122,8 @@ private slots: void removeFileWhileProcessIsRunning(); void fileWriterProcess(); void switchReadChannels(); -#ifdef Q_OS_WIN void setWorkingDirectory(); -#endif // Q_OS_WIN + void setNonExistentWorkingDirectory(); #endif // not Q_OS_WINCE void exitStatus_data(); @@ -355,11 +354,13 @@ void tst_QProcess::crashTest() qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus"); - QSignalSpy spy(process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); - QSignalSpy spy2(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)); + QSignalSpy spy(process, &QProcess::errorOccurred); + QSignalSpy spy2(process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); + QSignalSpy spy3(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)); QVERIFY(spy.isValid()); QVERIFY(spy2.isValid()); + QVERIFY(spy3.isValid()); QVERIFY(process->waitForFinished(30000)); @@ -367,7 +368,10 @@ void tst_QProcess::crashTest() QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed); QCOMPARE(spy2.count(), 1); - QCOMPARE(*static_cast<const QProcess::ExitStatus *>(spy2.at(0).at(1).constData()), QProcess::CrashExit); + QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy2.at(0).at(0).constData()), QProcess::Crashed); + + QCOMPARE(spy3.count(), 1); + QCOMPARE(*static_cast<const QProcess::ExitStatus *>(spy3.at(0).at(1).constData()), QProcess::CrashExit); QCOMPARE(process->exitStatus(), QProcess::CrashExit); @@ -390,7 +394,7 @@ void tst_QProcess::crashTest2() qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus"); - QSignalSpy spy(process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); + QSignalSpy spy(process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::errorOccurred)); QSignalSpy spy2(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)); QVERIFY(spy.isValid()); @@ -681,8 +685,10 @@ void tst_QProcess::readTimeoutAndThenCrash() QCOMPARE(process->error(), QProcess::Timedout); qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); - QSignalSpy spy(process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); + QSignalSpy spy(process, &QProcess::errorOccurred); + QSignalSpy spy2(process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); QVERIFY(spy.isValid()); + QVERIFY(spy2.isValid()); process->kill(); @@ -691,6 +697,8 @@ void tst_QProcess::readTimeoutAndThenCrash() QCOMPARE(spy.count(), 1); QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed); + QCOMPARE(spy2.count(), 1); + QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy2.at(0).at(0).constData()), QProcess::Crashed); delete process; process = 0; @@ -1549,16 +1557,18 @@ void tst_QProcess::failToStart() QProcess process; QSignalSpy stateSpy(&process, &QProcess::stateChanged); - QSignalSpy errorSpy(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); + QSignalSpy errorSpy(&process, &QProcess::errorOccurred); + QSignalSpy errorSpy2(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); QSignalSpy finishedSpy(&process, static_cast<void (QProcess::*)(int)>(&QProcess::finished)); QSignalSpy finishedSpy2(&process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)); QVERIFY(stateSpy.isValid()); QVERIFY(errorSpy.isValid()); + QVERIFY(errorSpy2.isValid()); QVERIFY(finishedSpy.isValid()); QVERIFY(finishedSpy2.isValid()); -// Mac OS X and HP-UX have a really low default process limit (~100), so spawning +// OS X and HP-UX have a really low default process limit (~100), so spawning // to many processes here will cause test failures later on. #if defined Q_OS_HPUX const int attempts = 15; @@ -1571,6 +1581,7 @@ void tst_QProcess::failToStart() for (int j = 0; j < 8; ++j) { for (int i = 0; i < attempts; ++i) { QCOMPARE(errorSpy.count(), j * attempts + i); + QCOMPARE(errorSpy2.count(), j * attempts + i); process.start("/blurp"); switch (j) { @@ -1595,6 +1606,7 @@ void tst_QProcess::failToStart() QCOMPARE(process.error(), QProcess::FailedToStart); QCOMPARE(errorSpy.count(), j * attempts + i + 1); + QCOMPARE(errorSpy2.count(), j * attempts + i + 1); QCOMPARE(finishedSpy.count(), 0); QCOMPARE(finishedSpy2.count(), 0); @@ -1618,11 +1630,13 @@ void tst_QProcess::failToStartWithWait() QProcess process; QEventLoop loop; - QSignalSpy errorSpy(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); + QSignalSpy errorSpy(&process, &QProcess::errorOccurred); + QSignalSpy errorSpy2(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); QSignalSpy finishedSpy(&process, static_cast<void (QProcess::*)(int)>(&QProcess::finished)); QSignalSpy finishedSpy2(&process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)); QVERIFY(errorSpy.isValid()); + QVERIFY(errorSpy2.isValid()); QVERIFY(finishedSpy.isValid()); QVERIFY(finishedSpy2.isValid()); @@ -1632,6 +1646,7 @@ void tst_QProcess::failToStartWithWait() QCOMPARE(process.error(), QProcess::FailedToStart); QCOMPARE(errorSpy.count(), i + 1); + QCOMPARE(errorSpy2.count(), i + 1); QCOMPARE(finishedSpy.count(), 0); QCOMPARE(finishedSpy2.count(), 0); } @@ -1648,16 +1663,18 @@ void tst_QProcess::failToStartWithEventLoop() QProcess process; QEventLoop loop; - QSignalSpy errorSpy(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); + QSignalSpy errorSpy(&process, &QProcess::errorOccurred); + QSignalSpy errorSpy2(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); QSignalSpy finishedSpy(&process, static_cast<void (QProcess::*)(int)>(&QProcess::finished)); QSignalSpy finishedSpy2(&process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)); QVERIFY(errorSpy.isValid()); + QVERIFY(errorSpy2.isValid()); QVERIFY(finishedSpy.isValid()); QVERIFY(finishedSpy2.isValid()); // The error signal may be emitted before start() returns - connect(&process, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit()), Qt::QueuedConnection); + connect(&process, &QProcess::errorOccurred, &loop, &QEventLoop::quit, Qt::QueuedConnection); for (int i = 0; i < 50; ++i) { @@ -1667,6 +1684,7 @@ void tst_QProcess::failToStartWithEventLoop() QCOMPARE(process.error(), QProcess::FailedToStart); QCOMPARE(errorSpy.count(), i + 1); + QCOMPARE(errorSpy2.count(), i + 1); QCOMPARE(finishedSpy.count(), 0); QCOMPARE(finishedSpy2.count(), 0); } @@ -1880,11 +1898,13 @@ void tst_QProcess::waitForReadyReadForNonexistantProcess() qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus"); QProcess process; - QSignalSpy errorSpy(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); + QSignalSpy errorSpy(&process, &QProcess::errorOccurred); + QSignalSpy errorSpy2(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); QSignalSpy finishedSpy1(&process, static_cast<void (QProcess::*)(int)>(&QProcess::finished)); QSignalSpy finishedSpy2(&process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)); QVERIFY(errorSpy.isValid()); + QVERIFY(errorSpy2.isValid()); QVERIFY(finishedSpy1.isValid()); QVERIFY(finishedSpy2.isValid()); @@ -1896,6 +1916,8 @@ void tst_QProcess::waitForReadyReadForNonexistantProcess() #endif QCOMPARE(errorSpy.count(), 1); QCOMPARE(errorSpy.at(0).at(0).toInt(), 0); + QCOMPARE(errorSpy2.count(), 1); + QCOMPARE(errorSpy2.at(0).at(0).toInt(), 0); QCOMPARE(finishedSpy1.count(), 0); QCOMPARE(finishedSpy2.count(), 0); } @@ -2169,15 +2191,19 @@ void tst_QProcess::switchReadChannels() #endif //----------------------------------------------------------------------------- -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#ifndef Q_OS_WINCE // Q_OS_WIN - setWorkingDirectory will chdir before starting the process on unices // Windows CE does not support working directory logic void tst_QProcess::setWorkingDirectory() { process = new QProcess; process->setWorkingDirectory("test"); - process->start("testSetWorkingDirectory/testSetWorkingDirectory"); - QVERIFY(process->waitForFinished()); + + // use absolute path because on Windows, the executable is relative to the parent's CWD + // while on Unix with fork it's relative to the child's (with posix_spawn, it could be either). + process->start(QFileInfo("testSetWorkingDirectory/testSetWorkingDirectory").absoluteFilePath()); + + QVERIFY2(process->waitForFinished(), process->errorString().toLocal8Bit()); QByteArray workingDir = process->readAllStandardOutput(); QCOMPARE(QDir("test").canonicalPath(), QDir(workingDir.constData()).canonicalPath()); @@ -2185,6 +2211,25 @@ void tst_QProcess::setWorkingDirectory() delete process; process = 0; } + +//----------------------------------------------------------------------------- +void tst_QProcess::setNonExistentWorkingDirectory() +{ + process = new QProcess; + process->setWorkingDirectory("this/directory/should/not/exist/for/sure"); + + // use absolute path because on Windows, the executable is relative to the parent's CWD + // while on Unix with fork it's relative to the child's (with posix_spawn, it could be either). + process->start(QFileInfo("testSetWorkingDirectory/testSetWorkingDirectory").absoluteFilePath()); + QVERIFY(!process->waitForFinished()); +#ifdef QPROCESS_USE_SPAWN + QEXPECT_FAIL("", "QProcess cannot detect failure to start when using posix_spawn()", Continue); +#endif + QCOMPARE(int(process->error()), int(QProcess::FailedToStart)); + + delete process; + process = 0; +} #endif //----------------------------------------------------------------------------- @@ -2221,12 +2266,15 @@ void tst_QProcess::invalidProgramString() QProcess process; qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); - QSignalSpy spy(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); + QSignalSpy spy(&process, &QProcess::errorOccurred); + QSignalSpy spy2(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); QVERIFY(spy.isValid()); + QVERIFY(spy2.isValid()); process.start(programString); QCOMPARE(process.error(), QProcess::FailedToStart); QCOMPARE(spy.count(), 1); + QCOMPARE(spy2.count(), 1); QVERIFY(!QProcess::startDetached(programString)); } diff --git a/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp b/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp index be9a38c499b3ac55d6db04543a730dd2170bd691..2099101a91a0eb64d0d5995b84ee6bcc14e9c4d4 100644 --- a/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp +++ b/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp @@ -66,11 +66,19 @@ void tst_QProcessEnvironment::operator_eq() QVERIFY(e1 == e2); e1.clear(); - QVERIFY(e1 != e2); + QVERIFY(e1 == e2); e2.clear(); + QVERIFY(e1 == e2); + + e1.insert("FOO", "bar"); + QVERIFY(e1 != e2); + e2.insert("FOO", "bar"); QVERIFY(e1 == e2); + + e2.insert("FOO", "baz"); + QVERIFY(e1 != e2); } void tst_QProcessEnvironment::clearAndIsEmpty() @@ -196,6 +204,15 @@ void tst_QProcessEnvironment::insertEnv() QCOMPARE(e.value("Hello"), QString("Another World")); QCOMPARE(e.value("FOO2"), QString("bar2")); QCOMPARE(e.value("A2"), QString("bc2")); + + QProcessEnvironment e3; + e3.insert("FOO2", "bar2"); + e3.insert("A2", "bc2"); + e3.insert("Hello", "Another World"); + + e3.insert(e3); // mustn't deadlock + + QVERIFY(e3 == e2); } void tst_QProcessEnvironment::caseSensitivity() diff --git a/tests/auto/corelib/io/qsettings/BLACKLIST b/tests/auto/corelib/io/qsettings/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..1cba99b66ce90c11b0aff5f4da6a5f0d62e84277 --- /dev/null +++ b/tests/auto/corelib/io/qsettings/BLACKLIST @@ -0,0 +1,2 @@ +[isWritable:native] +osx-10.10 diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index bc33d5991bdb3107a90292a1c08c87ffb4af5b01..e2e1d996575a0dd7fd1e50cfbfdff6ae00601eaf 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -1476,7 +1476,7 @@ void tst_QSettings::remove() void tst_QSettings::contains() { QSettings settings1(QSettings::UserScope, "software.org", "KillerAPP"); - int initialNumKeys = settings1.allKeys().size(); // 0 on all platforms but Mac OS X. + int initialNumKeys = settings1.allKeys().size(); // 0 on all platforms but OS X. settings1.setValue("alpha/beta/geometry", -7); settings1.setValue("alpha/beta/geometry/x", 1); settings1.setValue("alpha/beta/geometry/y", 2); diff --git a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp index 2190c32c017a02772467f26660ea2b089410526b..a7a0cf4ddb9759258b53f1aa6019412ef52db33b 100644 --- a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp +++ b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp @@ -61,9 +61,9 @@ void tst_QStorageInfo::defaultValues() QVERIFY(!storage.isRoot()); QVERIFY(storage.device().isEmpty()); QVERIFY(storage.fileSystemType().isEmpty()); - QVERIFY(storage.bytesTotal() == 0); - QVERIFY(storage.bytesFree() == 0); - QVERIFY(storage.bytesAvailable() == 0); + QVERIFY(storage.bytesTotal() == -1); + QVERIFY(storage.bytesFree() == -1); + QVERIFY(storage.bytesAvailable() == -1); } void tst_QStorageInfo::operatorEqual() @@ -106,9 +106,9 @@ void tst_QStorageInfo::root() QVERIFY(!storage.device().isEmpty()); QVERIFY(!storage.fileSystemType().isEmpty()); #ifndef Q_OS_HAIKU - QVERIFY(storage.bytesTotal() > 0); - QVERIFY(storage.bytesFree() > 0); - QVERIFY(storage.bytesAvailable() > 0); + QVERIFY(storage.bytesTotal() >= 0); + QVERIFY(storage.bytesFree() >= 0); + QVERIFY(storage.bytesAvailable() >= 0); #endif } @@ -121,9 +121,9 @@ void tst_QStorageInfo::currentStorage() QVERIFY(appPath.startsWith(storage.rootPath(), Qt::CaseInsensitive)); QVERIFY(!storage.device().isEmpty()); QVERIFY(!storage.fileSystemType().isEmpty()); - QVERIFY(storage.bytesTotal() > 0); - QVERIFY(storage.bytesFree() > 0); - QVERIFY(storage.bytesAvailable() > 0); + QVERIFY(storage.bytesTotal() >= 0); + QVERIFY(storage.bytesFree() >= 0); + QVERIFY(storage.bytesAvailable() >= 0); } void tst_QStorageInfo::storageList() diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp index e144e32c778987161f5ab684f0b400b44aef4797..58a3db9615ce7c596e7dce88fe367040a34d8134 100644 --- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp +++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp @@ -93,6 +93,7 @@ void tst_QTemporaryDir::construction() QCOMPARE(dir.path().left(tmp.size()), tmp); QVERIFY(dir.path().contains("tst_qtemporarydir")); QVERIFY(QFileInfo(dir.path()).isDir()); + QCOMPARE(dir.errorString(), QString()); } // Testing get/set functions @@ -215,6 +216,8 @@ void tst_QTemporaryDir::autoRemove() QFile file(dirName + "/dir1/file"); QVERIFY(file.open(QIODevice::WriteOnly)); QCOMPARE(file.write("Hello"), 5LL); + file.close(); + QVERIFY(file.setPermissions(QFile::ReadUser)); } #ifdef Q_OS_WIN QTRY_VERIFY(!QDir(dirName).exists()); @@ -249,6 +252,7 @@ void tst_QTemporaryDir::nonWritableCurrentDir() QTemporaryDir dir("tempXXXXXX"); dir.setAutoRemove(true); QVERIFY(!dir.isValid()); + QVERIFY(!dir.errorString().isEmpty()); QVERIFY(dir.path().isEmpty()); #endif } @@ -285,7 +289,11 @@ void tst_QTemporaryDir::stressTest() for (int i = 0; i < iterations; ++i) { QTemporaryDir dir(pattern); dir.setAutoRemove(false); - QVERIFY2(dir.isValid(), qPrintable(QString::fromLatin1("Failed to create #%1 under %2.").arg(i).arg(QDir::toNativeSeparators(pattern)))); + QVERIFY2(dir.isValid(), + qPrintable(QString::fromLatin1("Failed to create #%1 under %2: %3.") + .arg(i) + .arg(QDir::toNativeSeparators(pattern)) + .arg(dir.errorString()))); QVERIFY(!names.contains(dir.path())); names.insert(dir.path()); } diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp index e7325d2b8e2169a0d8c4d31a213fa414b4e8a932..94e6bbaade2014bd0925399e9931731ca0fd068a 100644 --- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp @@ -353,6 +353,7 @@ void tst_QTemporaryFile::removeAndReOpen() QVERIFY(!QFile::exists(fileName)); QVERIFY(file.open()); + QCOMPARE(QFileInfo(file.fileName()).path(), QFileInfo(fileName).path()); fileName = file.fileName(); QVERIFY(QFile::exists(fileName)); } diff --git a/tests/auto/corelib/io/qtextstream/BLACKLIST b/tests/auto/corelib/io/qtextstream/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..bc3f118b3375d325334b61b87cdb612eb6659051 --- /dev/null +++ b/tests/auto/corelib/io/qtextstream/BLACKLIST @@ -0,0 +1,2 @@ +[stillOpenWhenAtEnd] +windows diff --git a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp index aa7a3762ce58682edeb79cbf796febec275587cb..36da3b877041ac458769ca0f2f2076ecfaacde15 100644 --- a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp +++ b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp @@ -81,7 +81,7 @@ private slots: void readLineMaxlen_data(); void readLineMaxlen(); void readLinesFromBufferCRCR(); - void readLineOverload(); + void readLineInto(); // all void readAllFromDevice_data(); @@ -612,22 +612,22 @@ protected: } }; -void tst_QTextStream::readLineOverload() +void tst_QTextStream::readLineInto() { QByteArray data = "1\n2\n3"; QTextStream ts(&data); QString line; - ts.readLine(&line); + ts.readLineInto(&line); QCOMPARE(line, QStringLiteral("1")); - ts.readLine(Q_NULLPTR, 0); // read the second line, but don't store it + ts.readLineInto(Q_NULLPTR, 0); // read the second line, but don't store it - ts.readLine(&line); + ts.readLineInto(&line); QCOMPARE(line, QStringLiteral("3")); - QVERIFY(!ts.readLine(&line)); + QVERIFY(!ts.readLineInto(&line)); QVERIFY(line.isEmpty()); QFile file(m_rfc3261FilePath); @@ -637,7 +637,7 @@ void tst_QTextStream::readLineOverload() line.reserve(1); int maxLineCapacity = line.capacity(); - while (ts.readLine(&line)) { + while (ts.readLineInto(&line)) { QVERIFY(line.capacity() >= maxLineCapacity); maxLineCapacity = line.capacity(); } @@ -647,7 +647,7 @@ void tst_QTextStream::readLineOverload() QVERIFY(errorDevice.open(QIODevice::ReadOnly)); ts.setDevice(&errorDevice); - QVERIFY(!ts.readLine(&line)); + QVERIFY(!ts.readLineInto(&line)); QVERIFY(line.isEmpty()); } @@ -1025,7 +1025,7 @@ void tst_QTextStream::performance() QTextStream stream2(&file3); QString line; - while (stream2.readLine(&line)) + while (stream2.readLineInto(&line)) ++nlines3; elapsed[2] = stopWatch.elapsed(); diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp index 64170b15dd99c6ef109b3ebb6d10d660d1efcdd6..c4d2df7c3e43d0673c0e4d0ffccf2bf295b4179d 100644 --- a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp +++ b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp @@ -379,7 +379,7 @@ void tst_QAbstractItemModel::hasChildren() { QtTestModel model(1, 1); QModelIndex idx = model.index(0, 0, QModelIndex()); - QVERIFY(model.hasChildren(idx) == false); + QVERIFY(!model.hasChildren(idx)); } void tst_QAbstractItemModel::data() diff --git a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp index 8d331389f5e55274b259f17f6219d86ecff443be..23cd25447724dffd92e2f0da543e5d2b93995889 100644 --- a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -1530,7 +1530,7 @@ void tst_QItemSelectionModel::resetModel() model.reset(); QVERIFY(selectionModel->selection().isEmpty()); - QVERIFY(selectionModel->hasSelection() == false); + QVERIFY(!selectionModel->hasSelection()); selectionModel->select(QItemSelection(model.index(0, 0), model.index(5, 5)), QItemSelectionModel::Select); diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 01c10886c56212599c5663fc3569a931ab1e2ad4..0302ae5cbf50eb76ce3c14d6f55e4aaa89f716d0 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -87,6 +87,7 @@ private slots: void filter_qtbug30662(); void changeSourceLayout(); + void changeSourceLayoutFilteredOut(); void removeSourceRows_data(); void removeSourceRows(); void insertSourceRows_data(); @@ -1533,6 +1534,32 @@ void tst_QSortFilterProxyModel::changeSourceLayout() } } +void tst_QSortFilterProxyModel::changeSourceLayoutFilteredOut() +{ + QStandardItemModel model(2, 1); + model.setData(model.index(0, 0), QString("b")); + model.setData(model.index(1, 0), QString("a")); + QSortFilterProxyModel proxy; + proxy.setSourceModel(&model); + + int beforeSortFilter = proxy.rowCount(); + + QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved); + // Filter everything out + proxy.setFilterRegExp(QRegExp("c")); + QCOMPARE(removeSpy.count(), 1); + QCOMPARE(0, proxy.rowCount()); + + // change layout of source model + model.sort(0, Qt::AscendingOrder); + + QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted); + // Remove filter; we expect an insert + proxy.setFilterRegExp(QRegExp("")); + QCOMPARE(insertSpy.count(), 1); + QCOMPARE(beforeSortFilter, proxy.rowCount()); +} + void tst_QSortFilterProxyModel::removeSourceRows_data() { QTest::addColumn<QStringList>("sourceItems"); @@ -2502,16 +2529,16 @@ void tst_QSortFilterProxyModel::sortColumnTracking2() proxyModel.sort(0); QCOMPARE(proxyModel.sortColumn(), 0); - QList<QStandardItem *> items; - QStringList strings; - strings << "foo" << "bar" << "some" << "others" << "item" << "aa" << "zz"; - foreach (QString s, strings) - items << new QStandardItem(s); + QList<QStandardItem *> items; // Stable sorting: Items with invalid data should move to the end + items << new QStandardItem << new QStandardItem("foo") << new QStandardItem("bar") + << new QStandardItem("some") << new QStandardItem("others") << new QStandardItem("item") + << new QStandardItem("aa") << new QStandardItem("zz") << new QStandardItem; model.insertColumn(0,items); QCOMPARE(proxyModel.sortColumn(), 0); QCOMPARE(proxyModel.data(proxyModel.index(0,0)).toString(),QString::fromLatin1("aa")); - QCOMPARE(proxyModel.data(proxyModel.index(strings.count()-1,0)).toString(),QString::fromLatin1("zz")); + const int zzIndex = items.count() - 3; // 2 invalid at end. + QCOMPARE(proxyModel.data(proxyModel.index(zzIndex,0)).toString(),QString::fromLatin1("zz")); } void tst_QSortFilterProxyModel::sortStable() diff --git a/tests/auto/corelib/kernel/qcoreapplication/qcoreapplication.pro b/tests/auto/corelib/kernel/qcoreapplication/qcoreapplication.pro index 0602b9fc38f75dca0ec4f8836d5f4eaaff2c9cf2..1039f2c08dcd9319344bb9538fcbb56d911afe66 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/qcoreapplication.pro +++ b/tests/auto/corelib/kernel/qcoreapplication/qcoreapplication.pro @@ -3,3 +3,4 @@ TARGET = tst_qcoreapplication QT = core testlib core-private SOURCES = tst_qcoreapplication.cpp HEADERS = tst_qcoreapplication.h +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index 924db17c04552daf32b6989861f47eb8392f884c..060ef99d6575ea6c6e510d2b439316291f0f715b 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Intel Corporation. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -60,6 +61,38 @@ public: } }; +class ThreadedEventReceiver : public QObject +{ + Q_OBJECT +public: + QList<int> recordedEvents; + bool event(QEvent *event) Q_DECL_OVERRIDE + { + if (event->type() != QEvent::Type(QEvent::User + 1)) + return QObject::event(event); + recordedEvents.append(event->type()); + QThread::currentThread()->quit(); + QCoreApplication::quit(); + moveToThread(0); + return true; + } +}; + +class Thread : public QDaemonThread +{ + void run() Q_DECL_OVERRIDE + { + QThreadData *data = QThreadData::current(); + QVERIFY(!data->requiresCoreApplication); // daemon thread + data->requiresCoreApplication = requiresCoreApplication; + QThread::run(); + } + +public: + Thread() : requiresCoreApplication(true) {} + bool requiresCoreApplication; +}; + void tst_QCoreApplication::sendEventsOnProcessEvents() { int argc = 1; @@ -797,6 +830,105 @@ void tst_QCoreApplication::QTBUG31606_QEventDestructorDeadLock() QVERIFY(spy.recordedEvents.contains(QEvent::User + 2)); } +// this is almost identical to sendEventsOnProcessEvents +void tst_QCoreApplication::applicationEventFilters_mainThread() +{ + int argc = 1; + char *argv[] = { const_cast<char*>(QTest::currentAppName()) }; + TestApplication app(argc, argv); + + EventSpy spy; + app.installEventFilter(&spy); + + QCoreApplication::postEvent(&app, new QEvent(QEvent::Type(QEvent::User + 1))); + QTimer::singleShot(10, &app, SLOT(quit())); + app.exec(); + QVERIFY(spy.recordedEvents.contains(QEvent::User + 1)); +} + +void tst_QCoreApplication::applicationEventFilters_auxThread() +{ + int argc = 1; + char *argv[] = { const_cast<char*>(QTest::currentAppName()) }; + TestApplication app(argc, argv); + QThread thread; + ThreadedEventReceiver receiver; + receiver.moveToThread(&thread); + + EventSpy spy; + app.installEventFilter(&spy); + + // this is very similar to sendEventsOnProcessEvents + QCoreApplication::postEvent(&receiver, new QEvent(QEvent::Type(QEvent::User + 1))); + QTimer::singleShot(1000, &app, SLOT(quit())); + thread.start(); + app.exec(); + QVERIFY(thread.wait(1000)); + QVERIFY(receiver.recordedEvents.contains(QEvent::User + 1)); + QVERIFY(!spy.recordedEvents.contains(QEvent::User + 1)); +} + +void tst_QCoreApplication::threadedEventDelivery_data() +{ + QTest::addColumn<bool>("requiresCoreApplication"); + QTest::addColumn<bool>("createCoreApplication"); + QTest::addColumn<bool>("eventsReceived"); + + // invalid combination: + //QTest::newRow("default-without-coreapp") << true << false << false; + QTest::newRow("default") << true << true << true; + QTest::newRow("independent-without-coreapp") << false << false << true; + QTest::newRow("independent-with-coreapp") << false << true << true; +} + +// posts the event before the QCoreApplication is destroyed, starts thread after +void tst_QCoreApplication::threadedEventDelivery() +{ + QFETCH(bool, requiresCoreApplication); + QFETCH(bool, createCoreApplication); + QFETCH(bool, eventsReceived); + + int argc = 1; + char *argv[] = { const_cast<char*>(QTest::currentAppName()) }; + QScopedPointer<TestApplication> app(createCoreApplication ? new TestApplication(argc, argv) : 0); + + Thread thread; + thread.requiresCoreApplication = requiresCoreApplication; + ThreadedEventReceiver receiver; + receiver.moveToThread(&thread); + QCoreApplication::postEvent(&receiver, new QEvent(QEvent::Type(QEvent::User + 1))); + + thread.start(); + QVERIFY(thread.wait(1000)); + QCOMPARE(receiver.recordedEvents.contains(QEvent::User + 1), eventsReceived); +} + +void tst_QCoreApplication::addRemoveLibPaths() +{ + QStringList paths = QCoreApplication::libraryPaths(); + if (paths.isEmpty()) + QSKIP("Cannot add/remove library paths if there are none."); + + QString currentDir = QDir().absolutePath(); + QCoreApplication::addLibraryPath(currentDir); + QVERIFY(QCoreApplication::libraryPaths().contains(currentDir)); + + QCoreApplication::removeLibraryPath(paths[0]); + QVERIFY(!QCoreApplication::libraryPaths().contains(paths[0])); + + int argc = 1; + char *argv[] = { const_cast<char*>(QTest::currentAppName()) }; + TestApplication app(argc, argv); + + // Check that modifications stay alive across the creation of an application. + QVERIFY(QCoreApplication::libraryPaths().contains(currentDir)); + QVERIFY(!QCoreApplication::libraryPaths().contains(paths[0])); + + QStringList replace; + replace << currentDir << paths[0]; + QCoreApplication::setLibraryPaths(replace); + QVERIFY(QCoreApplication::libraryPaths() == replace); +} static void createQObjectOnDestruction() { diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h index 3dd84482d7d0811eccf369c1e7d981f3c66dd7a2..d9296b3846a433690edf58ab1207b1b74e79898c 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Intel Corporation. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -58,6 +59,11 @@ private slots: void customEventDispatcher(); void testQuitLock(); void QTBUG31606_QEventDestructorDeadLock(); + void applicationEventFilters_mainThread(); + void applicationEventFilters_auxThread(); + void threadedEventDelivery_data(); + void threadedEventDelivery(); + void addRemoveLibPaths(); }; #endif // TST_QCOREAPPLICATION_H diff --git a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST b/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..00be65751bbc5d6e55d82567a6c742b5fb1e6902 --- /dev/null +++ b/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST @@ -0,0 +1,4 @@ +[sendPostedEvents] +windows +[registerTimer] +windows diff --git a/tests/auto/corelib/kernel/qeventloop/BLACKLIST b/tests/auto/corelib/kernel/qeventloop/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..6ea6314b0a55154e5875b4b3cf779426275b3cbc --- /dev/null +++ b/tests/auto/corelib/kernel/qeventloop/BLACKLIST @@ -0,0 +1,2 @@ +[testQuitLock] +windows diff --git a/tests/auto/corelib/kernel/qeventloop/qeventloop.pro b/tests/auto/corelib/kernel/qeventloop/qeventloop.pro index 5593aa24305429dd49194f6af837da065c2da034..ea4792fc1cad23405f1f43dcbbbefc64faf35c6d 100644 --- a/tests/auto/corelib/kernel/qeventloop/qeventloop.pro +++ b/tests/auto/corelib/kernel/qeventloop/qeventloop.pro @@ -4,7 +4,7 @@ TARGET = tst_qeventloop QT = core network testlib core-private SOURCES = $$PWD/tst_qeventloop.cpp -win32:!wince*:!winrt:LIBS += -luser32 +win32:!wince:!winrt: LIBS += -luser32 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 contains(QT_CONFIG, glib): DEFINES += HAVE_GLIB diff --git a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp index a18c9eb3701b933364a2c8b0115742b5bd96b254..4d54aa4dc81323616d36ef593d9eb54057827f37 100644 --- a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp +++ b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp @@ -46,6 +46,7 @@ class tst_QMetaProperty : public QObject Q_PROPERTY(int value8 READ value8) Q_PROPERTY(int value9 READ value9 CONSTANT) Q_PROPERTY(int value10 READ value10 FINAL) + Q_PROPERTY(QMap<int, int> map MEMBER map) private slots: void hasStdCppSet(); @@ -53,6 +54,7 @@ private slots: void isFinal(); void gadget(); void readAndWriteWithLazyRegistration(); + void mapProperty(); public: enum EnumType { EnumType1 }; @@ -65,6 +67,8 @@ public: int value8() const { return 1; } int value9() const { return 1; } int value10() const { return 1; } + + QMap<int, int> map; }; void tst_QMetaProperty::hasStdCppSet() @@ -182,6 +186,14 @@ void tst_QMetaProperty::readAndWriteWithLazyRegistration() QCOMPARE(o.property("write").value<CustomWriteObjectChild*>(), &data); } +void tst_QMetaProperty::mapProperty() +{ + map.insert(5, 9); + QVariant v1 = QVariant::fromValue(map); + QVariant v = property("map"); + QVERIFY(v.isValid()); + QCOMPARE(map, (v.value<QMap<int,int> >())); +} QTEST_MAIN(tst_QMetaProperty) #include "tst_qmetaproperty.moc" diff --git a/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp b/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp index 01bf16c295078cd06e87126ec57018940b611b87..d368d9961b6144c19ec9450394bc53ae8e4d780f 100644 --- a/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp +++ b/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp @@ -70,7 +70,7 @@ void tst_QMimeData::clear() const mimeData.setData("text/plain", "pirates"); QVERIFY(mimeData.hasText()); mimeData.clear(); - QVERIFY(mimeData.hasText() == false); + QVERIFY(!mimeData.hasText()); // repopulate, verify not empty mimeData.setData("text/plain", "pirates"); @@ -136,7 +136,7 @@ void tst_QMimeData::hasColor() const QMimeData mimeData; // initial state - QVERIFY(mimeData.hasColor() == false); + QVERIFY(!mimeData.hasColor()); // set, verify mimeData.setColorData(QColor(Qt::red)); @@ -144,11 +144,11 @@ void tst_QMimeData::hasColor() const // clear, verify mimeData.clear(); - QVERIFY(mimeData.hasColor() == false); + QVERIFY(!mimeData.hasColor()); // set something else, verify mimeData.setData("text/plain", "pirates"); - QVERIFY(mimeData.hasColor() == false); + QVERIFY(!mimeData.hasColor()); } void tst_QMimeData::hasFormat() const @@ -156,17 +156,17 @@ void tst_QMimeData::hasFormat() const QMimeData mimeData; // initial state - QVERIFY(mimeData.hasFormat("text/plain") == false); + QVERIFY(!mimeData.hasFormat("text/plain")); // add, verify mimeData.setData("text/plain", "pirates"); QVERIFY(mimeData.hasFormat("text/plain")); - QVERIFY(mimeData.hasFormat("text/html") == false); + QVERIFY(!mimeData.hasFormat("text/html")); // clear, verify mimeData.clear(); - QVERIFY(mimeData.hasFormat("text/plain") == false); - QVERIFY(mimeData.hasFormat("text/html") == false); + QVERIFY(!mimeData.hasFormat("text/plain")); + QVERIFY(!mimeData.hasFormat("text/html")); } void tst_QMimeData::hasHtml() const @@ -174,11 +174,11 @@ void tst_QMimeData::hasHtml() const QMimeData mimeData; // initial state - QVERIFY(mimeData.hasHtml() == false); + QVERIFY(!mimeData.hasHtml()); // add plain, verify false mimeData.setData("text/plain", "pirates"); - QVERIFY(mimeData.hasHtml() == false); + QVERIFY(!mimeData.hasHtml()); // add html, verify mimeData.setData("text/html", "ninjas"); @@ -186,7 +186,7 @@ void tst_QMimeData::hasHtml() const // clear, verify mimeData.clear(); - QVERIFY(mimeData.hasHtml() == false); + QVERIFY(!mimeData.hasHtml()); // readd, verify mimeData.setData("text/html", "ninjas"); @@ -198,11 +198,11 @@ void tst_QMimeData::hasImage() const QMimeData mimeData; // initial state - QVERIFY(mimeData.hasImage() == false); + QVERIFY(!mimeData.hasImage()); // add text, verify false mimeData.setData("text/plain", "pirates"); - QVERIFY(mimeData.hasImage() == false); + QVERIFY(!mimeData.hasImage()); // add image mimeData.setImageData(QImage()); @@ -210,7 +210,7 @@ void tst_QMimeData::hasImage() const // clear, verify mimeData.clear(); - QVERIFY(mimeData.hasImage() == false); + QVERIFY(!mimeData.hasImage()); } void tst_QMimeData::imageData() const @@ -244,13 +244,13 @@ void tst_QMimeData::removeFormat() const // remove, verify mimeData.removeFormat("text/plain"); - QVERIFY(mimeData.hasFormat("text/plain") == false); + QVERIFY(!mimeData.hasFormat("text/plain")); QVERIFY(mimeData.hasFormat("text/html")); // remove, verify mimeData.removeFormat("text/html"); - QVERIFY(mimeData.hasFormat("text/plain") == false); - QVERIFY(mimeData.hasFormat("text/html") == false); + QVERIFY(!mimeData.hasFormat("text/plain")); + QVERIFY(!mimeData.hasFormat("text/html")); } void tst_QMimeData::setHtml() const @@ -258,7 +258,7 @@ void tst_QMimeData::setHtml() const QMimeData mimeData; // initial state - QVERIFY(mimeData.hasHtml() == false); + QVERIFY(!mimeData.hasHtml()); // add html, verify mimeData.setHtml("ninjas"); @@ -277,7 +277,7 @@ void tst_QMimeData::setText() const // verify initial state QCOMPARE(mimeData.text(), QLatin1String("")); - QVERIFY(mimeData.hasText() == false); + QVERIFY(!mimeData.hasText()); // set, verify mimeData.setText("pirates"); @@ -294,7 +294,7 @@ void tst_QMimeData::setText() const // clear, verify mimeData.clear(); QCOMPARE(mimeData.text(), QLatin1String("")); - QVERIFY(mimeData.hasText() == false); + QVERIFY(!mimeData.hasText()); } // Publish retrieveData for verifying content validity diff --git a/tests/auto/corelib/kernel/qobject/BLACKLIST b/tests/auto/corelib/kernel/qobject/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..0887a73b4c956a9323c04de0ad8d54ab4ef1af2f --- /dev/null +++ b/tests/auto/corelib/kernel/qobject/BLACKLIST @@ -0,0 +1,2 @@ +[moveToThread] +windows diff --git a/tests/auto/corelib/kernel/qobject/signalbug/signalbug.pro b/tests/auto/corelib/kernel/qobject/signalbug/signalbug.pro index 8823d54590ffd4bc9d69a359109bbf266314e5f2..b08dfb183839256068d499a1977c409b7ab499f7 100644 --- a/tests/auto/corelib/kernel/qobject/signalbug/signalbug.pro +++ b/tests/auto/corelib/kernel/qobject/signalbug/signalbug.pro @@ -2,7 +2,7 @@ CONFIG -= app_bundle debug_and_release CONFIG += console DESTDIR = ./ QT = core -wince*: { +wince { LIBS += coredll.lib } diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 3ec84b5198c4bc352b4bd5b5a2a301ca2e868f9d..4617ce5e74b2f366ad116416e17a8f97132baaa7 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -918,6 +918,8 @@ void tst_QObject::connectDisconnectNotifyPMF() QMetaObject::Connection conn = connect((SenderObject*)s, &SenderObject::signal1, (ReceiverObject*)r, &ReceiverObject::slot1); + QVERIFY(conn); + // Test disconnectNotify when disconnecting by QMetaObject::Connection QVERIFY(QObject::disconnect(conn)); // disconnectNotify() is not called, but it probably should be. @@ -5751,7 +5753,6 @@ void tst_QObject::connectFunctorWithContext() { int status = 1; SenderObject obj; - QMetaObject::Connection handle; ContextObject *context = new ContextObject; QEventLoop e; @@ -6058,8 +6059,12 @@ void tst_QObject::disconnectDoesNotLeakFunctor() QVERIFY(c2); QCOMPARE(countedStructObjectsCount, 2); QVERIFY(QObject::disconnect(c1)); + QVERIFY(!c1); + QVERIFY(!c2); // functor object has been destroyed QCOMPARE(countedStructObjectsCount, 1); + QVERIFY(!QObject::disconnect(c2)); + QCOMPARE(countedStructObjectsCount, 1); } QCOMPARE(countedStructObjectsCount, 0); } diff --git a/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp b/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp index 814c4bb691d20d814f990e1ef84b9cbe7d9ef52f..d7cce4ada447af6c5e825b6aa318efb46709510c 100644 --- a/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp +++ b/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp @@ -50,6 +50,7 @@ private slots: void destructor(); void assignment_operators(); void equality_operators(); + void swap(); void isNull(); void dereference_operators(); void disconnect(); @@ -169,6 +170,22 @@ void tst_QPointer::equality_operators() #endif } +void tst_QPointer::swap() +{ + QPointer<QObject> c1, c2; + { + QObject o; + c1 = &o; + QVERIFY(c2.isNull()); + QCOMPARE(c1.data(), &o); + c1.swap(c2); + QVERIFY(c1.isNull()); + QCOMPARE(c2.data(), &o); + } + QVERIFY(c1.isNull()); + QVERIFY(c2.isNull()); +} + void tst_QPointer::isNull() { QPointer<QObject> p1; diff --git a/tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST b/tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..e68bf84268a3027612cf865afe1a317de1944cb9 --- /dev/null +++ b/tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST @@ -0,0 +1,3 @@ +[unexpectedDisconnection] +windows +osx diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp index c7011dbc0444b0aeadcd10dd0a4ad73fb4df2b6c..1dc358bd972042e7e57b28bb9ee37fa9245c9549 100644 --- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp +++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp @@ -54,6 +54,8 @@ private slots: void singleShotTimeout(); void timeout(); void remainingTime(); + void remainingTimeDuringActivation_data(); + void remainingTimeDuringActivation(); void livelock_data(); void livelock(); void timerInfiniteRecursion_data(); @@ -79,14 +81,16 @@ class TimerHelper : public QObject { Q_OBJECT public: - TimerHelper() : QObject(), count(0) + TimerHelper() : QObject(), count(0), remainingTime(-1) { } int count; + int remainingTime; public slots: void timeout(); + void fetchRemainingTime(); }; void TimerHelper::timeout() @@ -94,6 +98,12 @@ void TimerHelper::timeout() ++count; } +void TimerHelper::fetchRemainingTime() +{ + QTimer *timer = static_cast<QTimer *>(sender()); + remainingTime = timer->remainingTime(); +} + void tst_QTimer::zeroTimer() { TimerHelper helper; @@ -158,6 +168,53 @@ void tst_QTimer::remainingTime() int remainingTime = timer.remainingTime(); QVERIFY2(qAbs(remainingTime - 150) < 50, qPrintable(QString::number(remainingTime))); + + // wait for the timer to actually fire now + connect(&timer, SIGNAL(timeout()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + QCOMPARE(helper.count, 1); + + // the timer is still active, so it should have a non-zero remaining time + remainingTime = timer.remainingTime(); + QVERIFY2(remainingTime > 150, qPrintable(QString::number(remainingTime))); +} + +void tst_QTimer::remainingTimeDuringActivation_data() +{ + QTest::addColumn<bool>("singleShot"); + QTest::newRow("repeating") << true; + QTest::newRow("single-shot") << true; +} + +void tst_QTimer::remainingTimeDuringActivation() +{ + QFETCH(bool, singleShot); + + TimerHelper helper; + QTimer timer; + + const int timeout = 20; // 20 ms is short enough and should not round down to 0 in any timer mode + + connect(&timer, SIGNAL(timeout()), &helper, SLOT(fetchRemainingTime())); + connect(&timer, SIGNAL(timeout()), &QTestEventLoop::instance(), SLOT(exitLoop())); + timer.start(timeout); + timer.setSingleShot(singleShot); + + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + if (singleShot) + QCOMPARE(helper.remainingTime, -1); // timer not running + else + QCOMPARE(helper.remainingTime, timeout); + + if (!singleShot) { + // do it again - see QTBUG-46940 + helper.remainingTime = -1; + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + QCOMPARE(helper.remainingTime, timeout); + } } void tst_QTimer::livelock_data() @@ -383,6 +440,9 @@ void tst_QTimer::deleteLaterOnQTimer() void tst_QTimer::moveToThread() { +#if defined(Q_OS_WIN32) + QSKIP("Does not work reliably on Windows :("); +#endif QTimer ti1; QTimer ti2; ti1.start(MOVETOTHREAD_TIMEOUT); diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index a0edf29607ea9f0327c10d850f906d071b7b98b2..7c32f2cc124c773a48eff7a75fa94a80a6883267 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -35,6 +35,7 @@ #include "qstandardpaths.h" +#include <QtCore/QElapsedTimer> #include <QtCore/QFile> #include <QtCore/QFileInfo> #include <QtCore/QTextStream> @@ -81,7 +82,8 @@ tst_QMimeDatabase::tst_QMimeDatabase() void tst_QMimeDatabase::initTestCase() { - QVERIFY(m_temporaryDir.isValid()); + QVERIFY2(m_temporaryDir.isValid(), + ("Could not create temporary subdir: " + m_temporaryDir.errorString()).toUtf8()); // Create a "global" and a "local" XDG data dir, right here. // The local dir will be empty initially, while the global dir will contain a copy of freedesktop.org.xml @@ -765,16 +767,20 @@ static bool runUpdateMimeDatabase(const QString &path) // TODO make it a QMimeDa return false; } + QElapsedTimer timer; QProcess proc; proc.setProcessChannelMode(QProcess::MergedChannels); // silence output + qDebug().noquote() << "runUpdateMimeDatabase: running" << umd << path << "..."; + timer.start(); proc.start(umd, QStringList(path)); if (!proc.waitForStarted()) { qWarning("Cannot start %s: %s", qPrintable(umd), qPrintable(proc.errorString())); return false; } - proc.waitForFinished(); - //qDebug() << "runUpdateMimeDatabase" << path; + const bool success = proc.waitForFinished(); + qDebug().noquote() << "runUpdateMimeDatabase: done," + << success << timer.elapsed() << "ms"; return true; } diff --git a/tests/auto/corelib/plugin/qlibrary/lib/lib.pro b/tests/auto/corelib/plugin/qlibrary/lib/lib.pro index a92b4faca5500c574def5baee249ac1e5241ce05..195e48da93b6ea7258352e764e259f5bd7f85cd3 100644 --- a/tests/auto/corelib/plugin/qlibrary/lib/lib.pro +++ b/tests/auto/corelib/plugin/qlibrary/lib/lib.pro @@ -6,7 +6,7 @@ TARGET = mylib DESTDIR = ../ QT = core -wince*: DEFINES += WIN32_MSVC +wince: DEFINES += WIN32_MSVC win32-msvc: DEFINES += WIN32_MSVC # This project is testdata for tst_qlibrary diff --git a/tests/auto/corelib/plugin/qlibrary/lib2/lib2.pro b/tests/auto/corelib/plugin/qlibrary/lib2/lib2.pro index dc6a660c0a3ad3b62ee304ce8f744a860a7d6a08..52dd8b967962ef633f4fa840cde33bbf15352e3b 100644 --- a/tests/auto/corelib/plugin/qlibrary/lib2/lib2.pro +++ b/tests/auto/corelib/plugin/qlibrary/lib2/lib2.pro @@ -7,7 +7,7 @@ DESTDIR = ../ VERSION = 2 QT = core -wince*: DEFINES += WIN32_MSVC +wince: DEFINES += WIN32_MSVC win32-msvc: DEFINES += WIN32_MSVC # Force a copy of the library to have an extension that is non-standard. diff --git a/tests/auto/corelib/statemachine/qstate/tst_qstate.cpp b/tests/auto/corelib/statemachine/qstate/tst_qstate.cpp index ac3374b6a3280d5ad13cd0b60d82176231ab1c9a..c64d55671a814cde752671c1ebb1ba2fa49b6b4d 100644 --- a/tests/auto/corelib/statemachine/qstate/tst_qstate.cpp +++ b/tests/auto/corelib/statemachine/qstate/tst_qstate.cpp @@ -47,6 +47,7 @@ private slots: void historyInitialState(); void transitions(); void privateSignals(); + void parallelStateAndInitialState(); }; class TestClass: public QObject @@ -344,5 +345,35 @@ void tst_QState::privateSignals() } +void tst_QState::parallelStateAndInitialState() +{ + QStateMachine machine; + + { // setting an initial state on a parallel state: + QState a(QState::ParallelStates, &machine); + QState b(&a); + QVERIFY(!a.initialState()); + const QString warning + = QString::asprintf("QState::setInitialState: ignoring attempt to set initial state of parallel state group %p", &a); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + a.setInitialState(&b); // should produce a warning and do nothing. + QVERIFY(!a.initialState()); + } + + { // setting the child-mode from ExclusiveStates to ParallelStates should remove the initial state: + QState a(QState::ExclusiveStates, &machine); + QState b(&a); + a.setInitialState(&b); + QCOMPARE(a.initialState(), &b); + const QString warning + = QString::asprintf("QState::setChildMode: setting the child-mode of state %p to " + "parallel removes the initial state", &a); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + a.setChildMode(QState::ParallelStates); // should produce a warning and remove the initial state + QVERIFY(!a.initialState()); + QCOMPARE(a.childMode(), QState::ParallelStates); + } +} + QTEST_MAIN(tst_QState) #include "tst_qstate.moc" diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp index 1292c3b98f145a06ed0143def0247a962831bca8..28df7cce7be9eb1bb5f6b68700a2143f50f74757 100644 --- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp @@ -250,6 +250,7 @@ private slots: void internalTransition(); void conflictingTransition(); void qtbug_46059(); + void qtbug_46703(); }; class TestState : public QState @@ -265,7 +266,7 @@ public: TestState(ChildMode mode, const QString &objectName = QString()) : QState(mode) { setObjectName(objectName); } - QList<QPair<int, Event> > events; + QVector<QPair<int, Event> > events; protected: virtual void onEntry(QEvent *) { events.append(qMakePair(globalTick++, Entry)); @@ -281,7 +282,7 @@ public: TestTransition(QAbstractState *target, const QString &objectName = QString()) : QAbstractTransition() { setTargetState(target); setObjectName(objectName); } - QList<int> triggers; + QVector<int> triggers; protected: virtual bool eventTest(QEvent *) { return true; @@ -4860,7 +4861,7 @@ public: signalList.append(signal); } - QList<QMetaMethod> signalList; + QVector<QMetaMethod> signalList; }; void tst_QStateMachine::testIncrementReceivers() @@ -6485,5 +6486,59 @@ void tst_QStateMachine::qtbug_46059() QVERIFY(machine.isRunning()); } +void tst_QStateMachine::qtbug_46703() +{ + QStateMachine machine; + QState root(&machine); + QHistoryState h(&root); + QState p(QState::ParallelStates, &root); + QState a(&p); + QState a1(&a); + QState a2(&a); + QState a3(&a); + QState b(&p); + QState b1(&b); + QState b2(&b); + + machine.setObjectName("machine"); + root.setObjectName("root"); + h.setObjectName("h"); + p.setObjectName("p"); + a.setObjectName("a"); + a1.setObjectName("a1"); + a2.setObjectName("a2"); + a3.setObjectName("a3"); + b.setObjectName("b"); + b1.setObjectName("b1"); + b2.setObjectName("b2"); + + machine.setInitialState(&root); + root.setInitialState(&h); + a.setInitialState(&a3); + b.setInitialState(&b1); + struct : public QAbstractTransition { + virtual bool eventTest(QEvent *) { return false; } + virtual void onTransition(QEvent *) {} + } defaultTransition; + defaultTransition.setTargetStates(QList<QAbstractState*>() << &a2 << &b2); + h.setDefaultTransition(&defaultTransition); + + machine.start(); + QCoreApplication::processEvents(); + + QTRY_COMPARE(machine.configuration().contains(&root), true); + QTRY_COMPARE(machine.configuration().contains(&h), false); + QTRY_COMPARE(machine.configuration().contains(&p), true); + QTRY_COMPARE(machine.configuration().contains(&a), true); + QTRY_COMPARE(machine.configuration().contains(&a1), false); + QTRY_COMPARE(machine.configuration().contains(&a2), true); + QTRY_COMPARE(machine.configuration().contains(&a3), false); + QTRY_COMPARE(machine.configuration().contains(&b), true); + QTRY_COMPARE(machine.configuration().contains(&b1), false); + QTRY_COMPARE(machine.configuration().contains(&b2), true); + + QVERIFY(machine.isRunning()); +} + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" diff --git a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp index e8c58a9fa5962336e5c9574d8dee4416fbb7bea2..72ae68f81a41eb8ab8926f6bf2ee892f1b01a182 100644 --- a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp +++ b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp @@ -479,34 +479,34 @@ void tst_QAtomicInt::testAndSet_data() QTest::addColumn<int>("value"); QTest::addColumn<int>("expected"); QTest::addColumn<int>("newval"); - QTest::addColumn<int>("result"); + QTest::addColumn<bool>("result"); // these should succeed - QTest::newRow("success0") << 0 << 0 << 0 << 1; - QTest::newRow("success1") << 0 << 0 << 1 << 1; - QTest::newRow("success2") << 0 << 0 << -1 << 1; - QTest::newRow("success3") << 1 << 1 << 0 << 1; - QTest::newRow("success4") << 1 << 1 << 1 << 1; - QTest::newRow("success5") << 1 << 1 << -1 << 1; - QTest::newRow("success6") << -1 << -1 << 0 << 1; - QTest::newRow("success7") << -1 << -1 << 1 << 1; - QTest::newRow("success8") << -1 << -1 << -1 << 1; - QTest::newRow("success9") << INT_MIN+1 << INT_MIN+1 << INT_MIN+1 << 1; - QTest::newRow("successA") << INT_MIN+1 << INT_MIN+1 << 1 << 1; - QTest::newRow("successB") << INT_MIN+1 << INT_MIN+1 << -1 << 1; - QTest::newRow("successC") << INT_MAX << INT_MAX << INT_MAX << 1; - QTest::newRow("successD") << INT_MAX << INT_MAX << 1 << 1; - QTest::newRow("successE") << INT_MAX << INT_MAX << -1 << 1; + QTest::newRow("success0") << 0 << 0 << 0 << true; + QTest::newRow("success1") << 0 << 0 << 1 << true; + QTest::newRow("success2") << 0 << 0 << -1 << true; + QTest::newRow("success3") << 1 << 1 << 0 << true; + QTest::newRow("success4") << 1 << 1 << 1 << true; + QTest::newRow("success5") << 1 << 1 << -1 << true; + QTest::newRow("success6") << -1 << -1 << 0 << true; + QTest::newRow("success7") << -1 << -1 << 1 << true; + QTest::newRow("success8") << -1 << -1 << -1 << true; + QTest::newRow("success9") << INT_MIN+1 << INT_MIN+1 << INT_MIN+1 << true; + QTest::newRow("successA") << INT_MIN+1 << INT_MIN+1 << 1 << true; + QTest::newRow("successB") << INT_MIN+1 << INT_MIN+1 << -1 << true; + QTest::newRow("successC") << INT_MAX << INT_MAX << INT_MAX << true; + QTest::newRow("successD") << INT_MAX << INT_MAX << 1 << true; + QTest::newRow("successE") << INT_MAX << INT_MAX << -1 << true; // these should fail - QTest::newRow("failure0") << 0 << 1 << ~0 << 0; - QTest::newRow("failure1") << 0 << -1 << ~0 << 0; - QTest::newRow("failure2") << 1 << 0 << ~0 << 0; - QTest::newRow("failure3") << -1 << 0 << ~0 << 0; - QTest::newRow("failure4") << 1 << -1 << ~0 << 0; - QTest::newRow("failure5") << -1 << 1 << ~0 << 0; - QTest::newRow("failure6") << INT_MIN+1 << INT_MAX << ~0 << 0; - QTest::newRow("failure7") << INT_MAX << INT_MIN+1 << ~0 << 0; + QTest::newRow("failure0") << 0 << 1 << ~0 << false; + QTest::newRow("failure1") << 0 << -1 << ~0 << false; + QTest::newRow("failure2") << 1 << 0 << ~0 << false; + QTest::newRow("failure3") << -1 << 0 << ~0 << false; + QTest::newRow("failure4") << 1 << -1 << ~0 << false; + QTest::newRow("failure5") << -1 << 1 << ~0 << false; + QTest::newRow("failure6") << INT_MIN+1 << INT_MAX << ~0 << false; + QTest::newRow("failure7") << INT_MAX << INT_MIN+1 << ~0 << false; } void tst_QAtomicInt::testAndSet() @@ -517,26 +517,26 @@ void tst_QAtomicInt::testAndSet() { QAtomicInt atomic = value; - QTEST(atomic.testAndSetRelaxed(expected, newval) ? 1 : 0, "result"); + QTEST(atomic.testAndSetRelaxed(expected, newval), "result"); } { QAtomicInt atomic = value; - QTEST(atomic.testAndSetAcquire(expected, newval) ? 1 : 0, "result"); + QTEST(atomic.testAndSetAcquire(expected, newval), "result"); } { QAtomicInt atomic = value; - QTEST(atomic.testAndSetRelease(expected, newval) ? 1 : 0, "result"); + QTEST(atomic.testAndSetRelease(expected, newval), "result"); } { QAtomicInt atomic = value; - QTEST(atomic.testAndSetOrdered(expected, newval) ? 1 : 0, "result"); + QTEST(atomic.testAndSetOrdered(expected, newval), "result"); } #ifdef Q_ATOMIC_INT32_IS_SUPPORTED - QFETCH(int, result); + QFETCH(bool, result); // the new implementation has the version that loads the current value { diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp index 99978a9923ff1a5ac006e498f3d925ed9b5ad677..ad690a094bce190119dcde8422a2de5b0115c878 100644 --- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp +++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp @@ -648,7 +648,7 @@ void tst_QFuture::cancel() result.reportStarted(); f = result.future(); - QVERIFY(f.isCanceled() == false); + QVERIFY(!f.isCanceled()); result.reportCanceled(); QVERIFY(f.isCanceled()); result.reportFinished(); @@ -663,14 +663,14 @@ void tst_QFuture::cancel() QFutureInterface<void> result; QFuture<void> f; - QVERIFY(f.isStarted() == true); + QVERIFY(f.isStarted()); result.reportStarted(); f = result.future(); - QVERIFY(f.isStarted() == true); + QVERIFY(f.isStarted()); - QVERIFY(result.isCanceled() == false); + QVERIFY(!result.isCanceled()); f.cancel(); QVERIFY(result.isCanceled()); @@ -683,12 +683,12 @@ void tst_QFuture::cancel() QFutureInterface<void> result; QFuture<void> f; - QVERIFY(f.isStarted() == true); + QVERIFY(f.isStarted()); result.reportStarted(); f = result.future(); - QVERIFY(f.isStarted() == true); + QVERIFY(f.isStarted()); result.reportFinished(); @@ -805,12 +805,12 @@ void tst_QFuture::indexedResults() { QFutureInterface<QChar> Interface; QFuture<QChar> f; - QVERIFY(f.isStarted() == true); + QVERIFY(f.isStarted()); Interface.reportStarted(); f = Interface.future(); - QVERIFY(f.isStarted() == true); + QVERIFY(f.isStarted()); QChar result; @@ -1126,14 +1126,14 @@ void tst_QFuture::iterators() QVERIFY(it.hasNext()); QCOMPARE(it.peekNext(), resultCount - 1); QCOMPARE(it.next(), resultCount - 1); - QVERIFY(it.hasNext() == false); + QVERIFY(!it.hasNext()); } { QFutureIterator<int> it(f); QVERIFY(it.hasNext()); it.toBack(); - QVERIFY(it.hasNext() == false); + QVERIFY(!it.hasNext()); it.toFront(); QVERIFY(it.hasNext()); } @@ -1192,15 +1192,15 @@ void tst_QFuture::pause() Interface.reportStarted(); QFuture<void> f = Interface.future(); - QVERIFY(Interface.isPaused() == false); + QVERIFY(!Interface.isPaused()); f.pause(); - QVERIFY(Interface.isPaused() == true); + QVERIFY(Interface.isPaused()); f.resume(); - QVERIFY(Interface.isPaused() == false); + QVERIFY(!Interface.isPaused()); f.togglePaused(); - QVERIFY(Interface.isPaused() == true); + QVERIFY(Interface.isPaused()); f.togglePaused(); - QVERIFY(Interface.isPaused() == false); + QVERIFY(!Interface.isPaused()); Interface.reportFinished(); } @@ -1228,13 +1228,13 @@ void tst_QFuture::throttling() i.reportStarted(); QFuture<void> f = i.future(); - QVERIFY(i.isThrottled() == false); + QVERIFY(!i.isThrottled()); i.setThrottled(true); QVERIFY(i.isThrottled()); i.setThrottled(false); - QVERIFY(i.isThrottled() == false); + QVERIFY(!i.isThrottled()); i.setThrottled(true); QVERIFY(i.isThrottled()); diff --git a/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp b/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp index 8831345ad72c20214b23e4a6299bed423c337c02..60a4d749c937709534faf7d406b69ab30784d9c7 100644 --- a/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp +++ b/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp @@ -743,7 +743,7 @@ void tst_QFutureWatcher::finishedState() iface.reportFinished(); QVERIFY(future.isFinished()); - QVERIFY(watcher.isFinished() == false); + QVERIFY(!watcher.isFinished()); QTest::qWait(10); QVERIFY(watcher.isFinished()); @@ -761,18 +761,18 @@ void tst_QFutureWatcher::throttling() QFutureWatcher<int> watcher; watcher.setFuture(future); - QVERIFY(iface.isThrottled() == false); + QVERIFY(!iface.isThrottled()); for (int i = 0; i < 1000; ++i) { int result = 0; iface.reportResult(result); } - QVERIFY(iface.isThrottled() == true); + QVERIFY(iface.isThrottled()); QTest::qWait(100); // process events. - QVERIFY(iface.isThrottled() == false); + QVERIFY(!iface.isThrottled()); iface.reportFinished(); } diff --git a/tests/auto/corelib/thread/qsemaphore/BLACKLIST b/tests/auto/corelib/thread/qsemaphore/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..9f6f6e3ba608e0deb823eada7f245d8d1c0869b6 --- /dev/null +++ b/tests/auto/corelib/thread/qsemaphore/BLACKLIST @@ -0,0 +1,3 @@ +# Times out randomly on linux, windows, osx +[tryAcquireWithTimeout] +* diff --git a/tests/auto/corelib/thread/qthread/BLACKLIST b/tests/auto/corelib/thread/qthread/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..d75249454f8111d8c2726d4461ea441e96650212 --- /dev/null +++ b/tests/auto/corelib/thread/qthread/BLACKLIST @@ -0,0 +1,2 @@ +[wait3_slowDestructor] +windows diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp index 3bc4bb80b83089353ae84cdf7b0235468def4dbb..3230472d5b2356c75d1b5754be8fb25ab98ce56a 100644 --- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp +++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp @@ -669,9 +669,7 @@ void NativeThreadWrapper::start(FunctionPointer functionPointer, void *data) #if defined Q_OS_UNIX const int state = pthread_create(&nativeThreadHandle, 0, NativeThreadWrapper::runUnix, this); Q_UNUSED(state); -#elif defined(Q_OS_WINRT) - // creating a new worker from within the GUI thread is not supported -#elif defined(Q_OS_WINCE) +#elif defined(Q_OS_WINCE) || defined(Q_OS_WINRT) nativeThreadHandle = CreateThread(NULL, 0 , (LPTHREAD_START_ROUTINE)NativeThreadWrapper::runWin , this, 0, NULL); #elif defined Q_OS_WIN unsigned thrdid = 0; @@ -690,10 +688,12 @@ void NativeThreadWrapper::join() { #if defined Q_OS_UNIX pthread_join(nativeThreadHandle, 0); -#elif defined Q_OS_WINRT - // not supported #elif defined Q_OS_WIN +#ifndef Q_OS_WINCE + WaitForSingleObjectEx(nativeThreadHandle, INFINITE, FALSE); +#else WaitForSingleObject(nativeThreadHandle, INFINITE); +#endif CloseHandle(nativeThreadHandle); #endif } @@ -747,9 +747,6 @@ void testNativeThreadAdoption(void *) } void tst_QThread::nativeThreadAdoption() { -#ifdef Q_OS_WINRT - QSKIP("Native thread adoption is not supported on WinRT."); -#endif threadAdoptedOk = false; mainThread = QThread::currentThread(); NativeThreadWrapper nativeThread; @@ -773,9 +770,6 @@ void adoptedThreadAffinityFunction(void *arg) void tst_QThread::adoptedThreadAffinity() { -#ifdef Q_OS_WINRT - QSKIP("Native thread adoption is not supported on WinRT."); -#endif QThread *affinity[2] = { 0, 0 }; NativeThreadWrapper thread; @@ -788,9 +782,6 @@ void tst_QThread::adoptedThreadAffinity() void tst_QThread::adoptedThreadSetPriority() { -#ifdef Q_OS_WINRT - QSKIP("Native thread adoption is not supported on WinRT."); -#endif NativeThreadWrapper nativeThread; nativeThread.setWaitForStop(); nativeThread.startAndWait(); @@ -818,9 +809,6 @@ void tst_QThread::adoptedThreadSetPriority() void tst_QThread::adoptedThreadExit() { -#ifdef Q_OS_WINRT - QSKIP("Native thread adoption is not supported on WinRT."); -#endif NativeThreadWrapper nativeThread; nativeThread.setWaitForStop(); @@ -850,9 +838,6 @@ void adoptedThreadExecFunction(void *) void tst_QThread::adoptedThreadExec() { -#ifdef Q_OS_WINRT - QSKIP("Native thread adoption is not supported on WinRT."); -#endif NativeThreadWrapper nativeThread; nativeThread.start(adoptedThreadExecFunction); nativeThread.join(); @@ -863,9 +848,6 @@ void tst_QThread::adoptedThreadExec() */ void tst_QThread::adoptedThreadFinished() { -#ifdef Q_OS_WINRT - QSKIP("Native thread adoption is not supported on WinRT."); -#endif NativeThreadWrapper nativeThread; nativeThread.setWaitForStop(); nativeThread.startAndWait(); @@ -876,17 +858,11 @@ void tst_QThread::adoptedThreadFinished() nativeThread.join(); QTestEventLoop::instance().enterLoop(5); -#if defined(Q_OS_WINRT) - QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort); -#endif QVERIFY(!QTestEventLoop::instance().timeout()); } void tst_QThread::adoptedThreadExecFinished() { -#ifdef Q_OS_WINRT - QSKIP("Native thread adoption is not supported on WinRT."); -#endif NativeThreadWrapper nativeThread; nativeThread.setWaitForStop(); nativeThread.startAndWait(adoptedThreadExecFunction); @@ -902,9 +878,6 @@ void tst_QThread::adoptedThreadExecFinished() void tst_QThread::adoptMultipleThreads() { -#ifdef Q_OS_WINRT - QSKIP("Native thread adoption is not supported on WinRT."); -#endif #if defined(Q_OS_WIN) // Windows CE is not capable of handling that many threads. On the emulator it is dead with 26 threads already. # if defined(Q_OS_WINCE) @@ -936,18 +909,12 @@ void tst_QThread::adoptMultipleThreads() } QTestEventLoop::instance().enterLoop(5); -#if defined(Q_OS_WINRT) - QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort); -#endif QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(recorder.activationCount.load(), numThreads); } void tst_QThread::adoptMultipleThreadsOverlap() { -#ifdef Q_OS_WINRT - QSKIP("Native thread adoption is not supported on WinRT."); -#endif #if defined(Q_OS_WIN) // Windows CE is not capable of handling that many threads. On the emulator it is dead with 26 threads already. # if defined(Q_OS_WINCE) @@ -984,9 +951,6 @@ void tst_QThread::adoptMultipleThreadsOverlap() } QTestEventLoop::instance().enterLoop(5); -#if defined(Q_OS_WINRT) - QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort); -#endif QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(recorder.activationCount.load(), numThreads); } diff --git a/tests/auto/corelib/thread/qthreadpool/BLACKLIST b/tests/auto/corelib/thread/qthreadpool/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..684f650a720384452e27ac526c9de620e309f261 --- /dev/null +++ b/tests/auto/corelib/thread/qthreadpool/BLACKLIST @@ -0,0 +1,5 @@ +[expiryTimeoutRace] +osx +[tryStartCount] +windows msvc-2012 +linux diff --git a/tests/auto/corelib/tools/collections/tst_collections.cpp b/tests/auto/corelib/tools/collections/tst_collections.cpp index 7eedd5bcf7d0b365a7e30dff06a611725db36513..ae8ffe48be79f4c0ef7a3f6258e73c4909af09e2 100644 --- a/tests/auto/corelib/tools/collections/tst_collections.cpp +++ b/tests/auto/corelib/tools/collections/tst_collections.cpp @@ -2235,7 +2235,7 @@ void tst_Collections::qstring() void tst_Collections::bitArray() { QBitArray ba(20); - QVERIFY(ba.testBit(17) == false); + QVERIFY(!ba.testBit(17)); ba.setBit(17); QVERIFY(ba.size() == 20); QVERIFY(ba.testBit(17)==true); diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 410b34e8948b34a432ba66ba61663209c7a6bd87..f942eab800eebf771ec2d5bf0a0ea3983f7bdfbb 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -67,6 +67,7 @@ private slots: void endsWith_data(); void endsWith(); void endsWith_char(); + void reverseIterators(); void split_data(); void split(); void base64_data(); @@ -540,6 +541,20 @@ void tst_QByteArray::endsWith_char() QVERIFY(!QByteArray().endsWith('\0')); } +void tst_QByteArray::reverseIterators() +{ + QByteArray s = "1234"; + QByteArray sr = s; + std::reverse(sr.begin(), sr.end()); + const QByteArray &csr = sr; + QVERIFY(std::equal(s.begin(), s.end(), sr.rbegin())); + QVERIFY(std::equal(s.begin(), s.end(), sr.crbegin())); + QVERIFY(std::equal(s.begin(), s.end(), csr.rbegin())); + QVERIFY(std::equal(sr.rbegin(), sr.rend(), s.begin())); + QVERIFY(std::equal(sr.crbegin(), sr.crend(), s.begin())); + QVERIFY(std::equal(csr.rbegin(), csr.rend(), s.begin())); +} + void tst_QByteArray::split_data() { QTest::addColumn<QByteArray>("sample"); diff --git a/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp b/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp index e5675397f5da68f6e37277aab7d707a460ed1962..b0135ab6afbadd1db583e9f0d0a3e4cad4435f1f 100644 --- a/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp +++ b/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp @@ -103,7 +103,7 @@ void tst_QCollator::compare_data() It's hard to test English, because it's treated differently on different platforms. For example, on Linux, it uses the iso14651_t1 template file, which happens to provide good - defaults for Swedish. Mac OS X seems to do a pure bytewise + defaults for Swedish. OS X seems to do a pure bytewise comparison of Latin-1 values, although I'm not sure. So I just test digits to make sure that it's not totally broken. */ diff --git a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp index 9c4ded69de7944f0793f281d937ae321ac75b534..fb0b971602f6de8831da262e38494f19bd1cfc91 100644 --- a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp +++ b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp @@ -133,7 +133,7 @@ void tst_QCommandLineParser::testBooleanOption() QFETCH(bool, expectedIsSet); QCoreApplication app(empty_argc, empty_argv); QCommandLineParser parser; - QVERIFY(parser.addOption(QCommandLineOption(QStringLiteral("b"), QStringLiteral("a boolean option")))); + QVERIFY(parser.addOption(QCommandLineOption(QStringLiteral("b")))); QVERIFY(parser.parse(args)); QCOMPARE(parser.optionNames(), expectedOptionNames); QCOMPARE(parser.isSet("b"), expectedIsSet); diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 6ea33fb37f86932af6daca8f29c56636628a6bc2..6a5c6b5670643e1acd34e311f9f459e8353d40f6 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -62,6 +62,7 @@ private slots: void compare(); void compare2(); void iterators(); // sligthly modified from tst_QMap + void keyIterator(); void keys_values_uniqueKeys(); // slightly modified from tst_QMap void noNeedlessRehashes(); @@ -965,6 +966,34 @@ void tst_QHash::iterators() } } +void tst_QHash::keyIterator() +{ + QHash<int, int> hash; + + for (int i = 0; i < 100; ++i) + hash.insert(i, i*100); + + QHash<int, int>::key_iterator key_it = hash.keyBegin(); + QHash<int, int>::const_iterator it = hash.cbegin(); + for (int i = 0; i < 100; ++i) { + QCOMPARE(*key_it, it.key()); + key_it++; + it++; + } + + key_it = std::find(hash.keyBegin(), hash.keyEnd(), 50); + it = std::find(hash.cbegin(), hash.cend(), 50 * 100); + + QVERIFY(key_it != hash.keyEnd()); + QCOMPARE(*key_it, it.key()); + QCOMPARE(*(key_it++), (it++).key()); + QCOMPARE(*(key_it--), (it--).key()); + QCOMPARE(*(++key_it), (++it).key()); + QCOMPARE(*(--key_it), (--it).key()); + + QCOMPARE(std::count(hash.keyBegin(), hash.keyEnd(), 99), 1); +} + void tst_QHash::rehash_isnt_quadratic() { // this test should be incredibly slow if rehash() is quadratic diff --git a/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp b/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp index 82303b4f729ea4f8fce51c7d29f88140f80bc762..2e829bb05ecfbaabba54c9050061d7fc060862ab 100644 --- a/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp +++ b/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp @@ -527,12 +527,12 @@ void tst_QLinkedList::contains() const QLinkedList<T> list; list << T_FOO << T_BAR << T_BAZ; - QVERIFY(list.contains(T_FOO) == true); + QVERIFY(list.contains(T_FOO)); QVERIFY(list.contains(T_BLAH) != true); // add it and make sure it matches list.append(T_BLAH); - QVERIFY(list.contains(T_BLAH) == true); + QVERIFY(list.contains(T_BLAH)); } void tst_QLinkedList::containsInt() const diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp index dd9371fbe141ced78ae9bdce410b94cbf891ffad..1bb31afa9cde3d226cc09f26667c9d978863ae2c 100644 --- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp +++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp @@ -313,6 +313,8 @@ private slots: void lastOptimal() const; void lastMovable() const; void lastComplex() const; + void constFirst() const; + void constLast() const; void beginOptimal() const; void beginMovable() const; void beginComplex() const; @@ -729,6 +731,140 @@ void tst_QList::firstComplex() const QCOMPARE(liveCount, Complex::getLiveCount()); } +void tst_QList::constFirst() const +{ + // Based on tst_QVector::constFirst() + QList<int> list; + list << 69 << 42 << 3; + + // test it starts ok + QCOMPARE(list.constFirst(), 69); + QVERIFY(list.isDetached()); + + QList<int> listCopy = list; + QVERIFY(!list.isDetached()); + QVERIFY(!listCopy.isDetached()); + QVERIFY(list.isSharedWith(listCopy)); + QVERIFY(listCopy.isSharedWith(list)); + + QCOMPARE(list.constFirst(), 69); + QCOMPARE(listCopy.constFirst(), 69); + + QVERIFY(!list.isDetached()); + QVERIFY(!listCopy.isDetached()); + QVERIFY(list.isSharedWith(listCopy)); + QVERIFY(listCopy.isSharedWith(list)); + + // test removal changes + list.removeAt(0); + QVERIFY(list.isDetached()); + QVERIFY(!list.isSharedWith(listCopy)); + QCOMPARE(list.constFirst(), 42); + QCOMPARE(listCopy.constFirst(), 69); + + listCopy = list; + QVERIFY(!list.isDetached()); + QVERIFY(!listCopy.isDetached()); + QVERIFY(list.isSharedWith(listCopy)); + QVERIFY(listCopy.isSharedWith(list)); + + QCOMPARE(list.constFirst(), 42); + QCOMPARE(listCopy.constFirst(), 42); + + QVERIFY(!list.isDetached()); + QVERIFY(!listCopy.isDetached()); + QVERIFY(list.isSharedWith(listCopy)); + QVERIFY(listCopy.isSharedWith(list)); + + // test prepend changes + list.prepend(23); + QVERIFY(list.isDetached()); + QVERIFY(!list.isSharedWith(listCopy)); + QCOMPARE(list.constFirst(), 23); + QCOMPARE(listCopy.constFirst(), 42); + + listCopy = list; + QVERIFY(!list.isDetached()); + QVERIFY(!listCopy.isDetached()); + QVERIFY(list.isSharedWith(listCopy)); + QVERIFY(listCopy.isSharedWith(list)); + + QCOMPARE(list.constFirst(), 23); + QCOMPARE(listCopy.constFirst(), 23); + + QVERIFY(!list.isDetached()); + QVERIFY(!listCopy.isDetached()); + QVERIFY(list.isSharedWith(listCopy)); + QVERIFY(listCopy.isSharedWith(list)); +} + +void tst_QList::constLast() const +{ + // Based on tst_QVector::constLast() + QList<int> list; + list << 69 << 42 << 3; + + // test it starts ok + QCOMPARE(list.constLast(), 3); + QVERIFY(list.isDetached()); + + QList<int> listCopy = list; + QVERIFY(!list.isDetached()); + QVERIFY(!listCopy.isDetached()); + QVERIFY(list.isSharedWith(listCopy)); + QVERIFY(listCopy.isSharedWith(list)); + + QCOMPARE(list.constLast(), 3); + QCOMPARE(listCopy.constLast(), 3); + + QVERIFY(!list.isDetached()); + QVERIFY(!listCopy.isDetached()); + QVERIFY(list.isSharedWith(listCopy)); + QVERIFY(listCopy.isSharedWith(list)); + + // test removal changes + list.removeLast(); + QVERIFY(list.isDetached()); + QVERIFY(!list.isSharedWith(listCopy)); + QCOMPARE(list.constLast(), 42); + QCOMPARE(listCopy.constLast(), 3); + + listCopy = list; + QVERIFY(!list.isDetached()); + QVERIFY(!listCopy.isDetached()); + QVERIFY(list.isSharedWith(listCopy)); + QVERIFY(listCopy.isSharedWith(list)); + + QCOMPARE(list.constLast(), 42); + QCOMPARE(listCopy.constLast(), 42); + + QVERIFY(!list.isDetached()); + QVERIFY(!listCopy.isDetached()); + QVERIFY(list.isSharedWith(listCopy)); + QVERIFY(listCopy.isSharedWith(list)); + + // test prepend changes + list.append(23); + QVERIFY(list.isDetached()); + QVERIFY(!list.isSharedWith(listCopy)); + QCOMPARE(list.constLast(), 23); + QCOMPARE(listCopy.constLast(), 42); + + listCopy = list; + QVERIFY(!list.isDetached()); + QVERIFY(!listCopy.isDetached()); + QVERIFY(list.isSharedWith(listCopy)); + QVERIFY(listCopy.isSharedWith(list)); + + QCOMPARE(list.constLast(), 23); + QCOMPARE(listCopy.constLast(), 23); + + QVERIFY(!list.isDetached()); + QVERIFY(!listCopy.isDetached()); + QVERIFY(list.isSharedWith(listCopy)); + QVERIFY(listCopy.isSharedWith(list)); +} + template<typename T> void tst_QList::last() const { @@ -840,12 +976,12 @@ void tst_QList::contains() const QList<T> list; list << T_FOO << T_BAR << T_BAZ; - QVERIFY(list.contains(T_FOO) == true); + QVERIFY(list.contains(T_FOO)); QVERIFY(list.contains(T_BLAH) != true); // add it and make sure it matches list.append(T_BLAH); - QVERIFY(list.contains(T_BLAH) == true); + QVERIFY(list.contains(T_BLAH)); } void tst_QList::containsOptimal() const diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index b1e13a0384e95e49e1627773dbae16f1c0c93474..11b6922278d6bdac422778ba6b35992ed728e1ae 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -371,6 +371,8 @@ void tst_QLocale::ctor() QString("requested: \"" + QString(req_lc) + "\", got: " \ + QLocale::languageToString(l.language()) \ + "/" + QLocale::countryToString(l.country())).toLatin1().constData()); \ + QCOMPARE(l, QLocale(QLocale::exp_lang, QLocale::exp_country)); \ + QCOMPARE(qHash(l), qHash(QLocale(QLocale::exp_lang, QLocale::exp_country))); \ } QLocale::setDefault(QLocale(QLocale::C)); diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index 8560a2f18c7ab64f03285a931791dad2b8c2c660..bb6535b6350c2865df6af147ab76ab60d920b792 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -65,6 +65,7 @@ private slots: void take(); void iterators(); + void keyIterator(); void keys_values_uniqueKeys(); void qmultimap_specific(); @@ -835,6 +836,34 @@ void tst_QMap::iterators() } } +void tst_QMap::keyIterator() +{ + QMap<int, int> map; + + for (int i = 0; i < 100; ++i) + map.insert(i, i*100); + + QMap<int, int>::key_iterator key_it = map.keyBegin(); + QMap<int, int>::const_iterator it = map.cbegin(); + for (int i = 0; i < 100; ++i) { + QCOMPARE(*key_it, it.key()); + ++key_it; + ++it; + } + + key_it = std::find(map.keyBegin(), map.keyEnd(), 50); + it = std::find(map.cbegin(), map.cend(), 50 * 100); + + QVERIFY(key_it != map.keyEnd()); + QCOMPARE(*key_it, it.key()); + QCOMPARE(*(key_it++), (it++).key()); + QCOMPARE(*(key_it--), (it--).key()); + QCOMPARE(*(++key_it), (++it).key()); + QCOMPARE(*(--key_it), (--it).key()); + + QCOMPARE(std::count(map.keyBegin(), map.keyEnd(), 99), 1); +} + void tst_QMap::keys_values_uniqueKeys() { QMap<QString, int> map; @@ -996,11 +1025,16 @@ void tst_QMap::const_shared_null() void tst_QMap::equal_range() { QMap<int, QString> map; + const QMap<int, QString> &cmap = map; QPair<QMap<int, QString>::iterator, QMap<int, QString>::iterator> result = map.equal_range(0); QCOMPARE(result.first, map.end()); QCOMPARE(result.second, map.end()); + QPair<QMap<int, QString>::const_iterator, QMap<int, QString>::const_iterator> cresult = cmap.equal_range(0); + QCOMPARE(cresult.first, cmap.cend()); + QCOMPARE(cresult.second, cmap.cend()); + map.insert(1, "one"); result = map.equal_range(0); @@ -1015,6 +1049,18 @@ void tst_QMap::equal_range() QCOMPARE(result.first, map.end()); QCOMPARE(result.second, map.end()); + cresult = cmap.equal_range(0); + QCOMPARE(cresult.first, cmap.find(1)); + QCOMPARE(cresult.second, cmap.find(1)); + + cresult = cmap.equal_range(1); + QCOMPARE(cresult.first, cmap.find(1)); + QCOMPARE(cresult.second, cmap.cend()); + + cresult = cmap.equal_range(2); + QCOMPARE(cresult.first, cmap.cend()); + QCOMPARE(cresult.second, cmap.cend()); + for (int i = -10; i < 10; i += 2) map.insert(i, QString("%1").arg(i)); @@ -1030,11 +1076,28 @@ void tst_QMap::equal_range() QCOMPARE(result.first, map.find(2)); QCOMPARE(result.second, map.find(4)); + cresult = cmap.equal_range(0); + QCOMPARE(cresult.first, cmap.find(0)); + QCOMPARE(cresult.second, cmap.find(1)); + + cresult = cmap.equal_range(1); + QCOMPARE(cresult.first, cmap.find(1)); + QCOMPARE(cresult.second, cmap.find(2)); + + cresult = cmap.equal_range(2); + QCOMPARE(cresult.first, cmap.find(2)); + QCOMPARE(cresult.second, cmap.find(4)); + map.insertMulti(1, "another one"); + result = map.equal_range(1); QCOMPARE(result.first, map.find(1)); QCOMPARE(result.second, map.find(2)); + cresult = cmap.equal_range(1); + QCOMPARE(cresult.first, cmap.find(1)); + QCOMPARE(cresult.second, cmap.find(2)); + QCOMPARE(map.count(1), 2); } diff --git a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp index f9bca77ed3b2a4f8d1ad237f36e0f6cfcd36f62d..77fc6ad6ae0d6a4185c945a41a3d277a17409dd9 100644 --- a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp +++ b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp @@ -88,7 +88,7 @@ void tst_QRingBuffer::readPointerAtPositionReadTooMuch() qint64 length; const char *buf = ringBuffer.readPointerAtPosition(42, length); QVERIFY(buf == 0); - QVERIFY(length == 0); + QCOMPARE(length, Q_INT64_C(0)); } void tst_QRingBuffer::readPointerAtPositionWithHead() @@ -104,8 +104,8 @@ void tst_QRingBuffer::readPointerAtPositionWithHead() const char* buf2 = ringBuffer.readPointerAtPosition(0, length); QCOMPARE(length, Q_INT64_C(2)); - QVERIFY(*buf2 == '2'); - QVERIFY(*(buf2+1) == '3'); + QCOMPARE(*buf2, '2'); + QCOMPARE(*(buf2 + 1), '3'); // advance 2 more, ringBuffer should be empty then ringBuffer.free(2); @@ -128,7 +128,7 @@ void tst_QRingBuffer::readPointerAtPositionEmptyRead() qint64 length; const char *buf = ringBuffer.readPointerAtPosition(0, length); QVERIFY(buf == 0); - QVERIFY(length == 0); + QCOMPARE(length, Q_INT64_C(0)); } void tst_QRingBuffer::readPointerAtPositionWriteRead() @@ -215,9 +215,9 @@ void tst_QRingBuffer::reserveAndRead() ba.resize(i); qint64 thisRead = ringBuffer.read(ba.data(), i); QCOMPARE(thisRead, qint64(i)); - QVERIFY(ba.count(char(i)) == i); + QCOMPARE(ba.count(char(i)), i); } - QVERIFY(ringBuffer.size() == 0); + QCOMPARE(ringBuffer.size(), Q_INT64_C(0)); } void tst_QRingBuffer::reserveFrontAndRead() @@ -237,9 +237,9 @@ void tst_QRingBuffer::reserveFrontAndRead() ba.resize(i); qint64 thisRead = ringBuffer.read(ba.data(), i); QCOMPARE(thisRead, qint64(i)); - QVERIFY(ba.count(char(i)) == i); + QCOMPARE(ba.count(char(i)), i); } - QVERIFY(ringBuffer.size() == 0); + QCOMPARE(ringBuffer.size(), Q_INT64_C(0)); } void tst_QRingBuffer::chop() @@ -268,7 +268,7 @@ void tst_QRingBuffer::ungetChar() for (int i = 1; i < 31; ++i) { int c = ringBuffer.getChar(); - QVERIFY(c == 1); + QCOMPARE(c, 1); ringBuffer.getChar(); ringBuffer.ungetChar(char(c)); // unget first char } @@ -283,9 +283,9 @@ void tst_QRingBuffer::indexOf() for (int i = 1; i < 256; ++i) { qint64 index = ringBuffer.indexOf(char(i)); - QCOMPARE(qint64(i - 1), index); - QCOMPARE(index, ringBuffer.indexOf(char(i), i)); - QVERIFY(ringBuffer.indexOf(char(i), i - 1) == -1); // test for absent char + QCOMPARE(index, qint64(i - 1)); + QCOMPARE(ringBuffer.indexOf(char(i), i), index); + QCOMPARE(ringBuffer.indexOf(char(i), i - 1), -1); // test for absent char } } @@ -299,9 +299,9 @@ void tst_QRingBuffer::appendAndRead() ringBuffer.append(ba2); ringBuffer.append(ba3); - QVERIFY(ringBuffer.read() == ba1); - QVERIFY(ringBuffer.read() == ba2); - QVERIFY(ringBuffer.read() == ba3); + QCOMPARE(ringBuffer.read(), ba1); + QCOMPARE(ringBuffer.read(), ba2); + QCOMPARE(ringBuffer.read(), ba3); } void tst_QRingBuffer::peek() @@ -326,7 +326,7 @@ void tst_QRingBuffer::peek() QCOMPARE(thisPeek, qint64(i)); resultBuffer.prepend(ba); } - QCOMPARE(testBuffer, resultBuffer); + QCOMPARE(resultBuffer, testBuffer); } void tst_QRingBuffer::readLine() @@ -342,18 +342,18 @@ void tst_QRingBuffer::readLine() char stringBuf[102]; stringBuf[101] = 0; // non-crash terminator - QVERIFY(ringBuffer.readLine(stringBuf, sizeof(stringBuf) - 2) == ba1.size()); - QVERIFY(QByteArray(stringBuf, int(strlen(stringBuf))) == ba1); + QCOMPARE(ringBuffer.readLine(stringBuf, sizeof(stringBuf) - 2), qint64(ba1.size())); + QCOMPARE(QByteArray(stringBuf, int(strlen(stringBuf))), ba1); // check first empty string reading stringBuf[0] = char(0xFF); QCOMPARE(ringBuffer.readLine(stringBuf, int(sizeof(stringBuf)) - 2), qint64(ba2.size())); - QVERIFY(stringBuf[0] == ba2[0]); + QCOMPARE(stringBuf[0], ba2.at(0)); - QVERIFY(ringBuffer.readLine(stringBuf, int(sizeof(stringBuf)) - 2) == (ba3.size() + ba4.size() - + ba2.size())); - QVERIFY(QByteArray(stringBuf, int(strlen(stringBuf))) == (ba3 + ba4 + ba2)); - QVERIFY(ringBuffer.size() == 0); + QCOMPARE(ringBuffer.readLine(stringBuf, int(sizeof(stringBuf)) - 2), + qint64(ba3.size() + ba4.size() + ba2.size())); + QCOMPARE(QByteArray(stringBuf, int(strlen(stringBuf))), ba3 + ba4 + ba2); + QCOMPARE(ringBuffer.size(), Q_INT64_C(0)); } QTEST_APPLESS_MAIN(tst_QRingBuffer) diff --git a/tests/auto/corelib/tools/qsharedpointer/externaltests.pri b/tests/auto/corelib/tools/qsharedpointer/externaltests.pri index b3a01f799070cce5bfdb53b606238da78ba05220..cac94bb5228e09d9b6c24a618ba6cc127152519d 100644 --- a/tests/auto/corelib/tools/qsharedpointer/externaltests.pri +++ b/tests/auto/corelib/tools/qsharedpointer/externaltests.pri @@ -4,4 +4,4 @@ cleanedQMAKESPEC = $$replace(QMAKESPEC, \\\\, /) DEFINES += DEFAULT_MAKESPEC=\\\"$$cleanedQMAKESPEC\\\" cross_compile:DEFINES += QTEST_NO_RTTI QTEST_CROSS_COMPILED -wince*:DEFINES += QTEST_CROSS_COMPILED QTEST_NO_RTTI +wince: DEFINES += QTEST_CROSS_COMPILED QTEST_NO_RTTI diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index d4b3ba7f15badc46479b9434387a12dddbba2ce3..745cbbfad3fe3335cd86b39b9613cc47c0e9ff21 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -534,6 +534,7 @@ private slots: void localeAwareCompare_data(); void localeAwareCompare(); #endif + void reverseIterators(); void split_data(); void split(); void split_regexp_data(); @@ -5246,7 +5247,7 @@ void tst_QString::localeAwareCompare_data() It's hard to test English, because it's treated differently on different platforms. For example, on Linux, it uses the iso14651_t1 template file, which happens to provide good - defaults for Swedish. Mac OS X seems to do a pure bytewise + defaults for Swedish. OS X seems to do a pure bytewise comparison of Latin-1 values, although I'm not sure. So I just test digits to make sure that it's not totally broken. */ @@ -5399,6 +5400,20 @@ void tst_QString::localeAwareCompare() } #endif //!defined(Q_OS_WIN) || defined(Q_OS_WIN_AND_WINCE) +void tst_QString::reverseIterators() +{ + QString s = "1234"; + QString sr = s; + std::reverse(sr.begin(), sr.end()); + const QString &csr = sr; + QVERIFY(std::equal(s.begin(), s.end(), sr.rbegin())); + QVERIFY(std::equal(s.begin(), s.end(), sr.crbegin())); + QVERIFY(std::equal(s.begin(), s.end(), csr.rbegin())); + QVERIFY(std::equal(sr.rbegin(), sr.rend(), s.begin())); + QVERIFY(std::equal(sr.crbegin(), sr.crend(), s.begin())); + QVERIFY(std::equal(csr.rbegin(), csr.rend(), s.begin())); +} + void tst_QString::split_data() { QTest::addColumn<QString>("str"); diff --git a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp b/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp index 7fc855a35901057f547763dd422ba813778992cc..82d103c4607e2dc70f459e2303115b6dbe5f558d 100644 --- a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp +++ b/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp @@ -82,6 +82,7 @@ private slots: void integer_conversion_data(); void integer_conversion(); void trimmed(); + void truncate(); void left(); void right(); void mid(); @@ -1839,6 +1840,30 @@ void tst_QStringRef::trimmed() QCOMPARE(b.trimmed().compare(QStringLiteral("a")), 0); } +void tst_QStringRef::truncate() +{ + const QString str = "OriginalString~"; + const QStringRef cref = str.midRef(0); + { + QStringRef ref = cref; + ref.truncate(1000); + QCOMPARE(ref, cref); + for (int i = str.size(); i >= 0; --i) { + ref.truncate(i); + QCOMPARE(ref.size(), i); + QCOMPARE(ref, cref.left(i)); + } + QVERIFY(ref.isEmpty()); + } + + { + QStringRef ref = cref; + QVERIFY(!ref.isEmpty()); + ref.truncate(-1); + QVERIFY(ref.isEmpty()); + } +} + void tst_QStringRef::left() { QString originalString = "OrginalString~"; diff --git a/tests/auto/corelib/tools/qtimeline/BLACKLIST b/tests/auto/corelib/tools/qtimeline/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..b5861756d831cab5a871b0d92977b26b5a791096 --- /dev/null +++ b/tests/auto/corelib/tools/qtimeline/BLACKLIST @@ -0,0 +1,4 @@ +[interpolation] +windows +[duration] +windows diff --git a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp index 975ed129fcd777d459b4e36269aadac632e171e2..507f7e3992a7b0a81676b62b1ecc42132f523c12 100644 --- a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp +++ b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp @@ -208,7 +208,7 @@ void tst_QTimeLine::frameRate() timeLine.start(); QTest::qWait(timeLine.duration()*2); QCOMPARE(timeLine.state(), QTimeLine::NotRunning); - QVERIFY(slowCount < spy.count()); + QVERIFY2(slowCount < spy.count(), QByteArray::number(spy.count())); } void tst_QTimeLine::value() diff --git a/tests/auto/corelib/tools/qtimezone/BLACKLIST b/tests/auto/corelib/tools/qtimezone/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..665e78bc087f4b368b786a57de6dcfd89b76c005 --- /dev/null +++ b/tests/auto/corelib/tools/qtimezone/BLACKLIST @@ -0,0 +1,2 @@ +[tzTest] +opensuse-13.1 diff --git a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp index 719daad3b6d2964336af7d1ffe479ef6b1b6dcd4..82f78b2b0bc5ca482bd940814f504518bcdd6e5c 100644 --- a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp +++ b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp @@ -56,6 +56,7 @@ private slots: void indexOf(); void lastIndexOf(); void contains(); + void clear(); void initializeListInt(); void initializeListMovable(); void initializeListComplex(); @@ -812,6 +813,21 @@ void tst_QVarLengthArray::contains() QVERIFY(myvec.contains(QLatin1String("I don't exist"))); } +void tst_QVarLengthArray::clear() +{ + QVarLengthArray<QString, 5> myvec; + + for (int i = 0; i < 10; ++i) + myvec << "aaa"; + + QCOMPARE(myvec.size(), 10); + QVERIFY(myvec.capacity() >= myvec.size()); + const int oldCapacity = myvec.capacity(); + myvec.clear(); + QCOMPARE(myvec.size(), 0); + QCOMPARE(myvec.capacity(), oldCapacity); +} + void tst_QVarLengthArray::initializeListInt() { initializeList<int>(); diff --git a/tests/auto/corelib/tools/qvector/qvector.pro b/tests/auto/corelib/tools/qvector/qvector.pro index 22edde3412bb346c909b01382a738ecfa1b7e5d6..c1e0564915eb748046852b295f288b7cb754d81a 100644 --- a/tests/auto/corelib/tools/qvector/qvector.pro +++ b/tests/auto/corelib/tools/qvector/qvector.pro @@ -1,4 +1,5 @@ CONFIG += testcase parallel_test +contains(QT_CONFIG, c++11):CONFIG += c++11 TARGET = tst_qvector QT = core testlib SOURCES = $$PWD/tst_qvector.cpp diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index f9f9ac472ae486fdb691c166919002e213ad1f08..87822bca6f853bed7a946bbb9315c35713cf033f 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -190,6 +190,7 @@ private slots: void appendInt() const; void appendMovable() const; void appendCustom() const; + void appendRvalue() const; void at() const; void capacityInt() const; void capacityMovable() const; @@ -240,6 +241,9 @@ private slots: void last() const; void lastIndexOf() const; void mid() const; + void moveInt() const; + void moveMovable() const; + void moveCustom() const; void prependInt() const; void prependMovable() const; void prependCustom() const; @@ -312,6 +316,7 @@ private: template<typename T> void fromList() const; template<typename T> void insert() const; template<typename T> void qhash() const; + template<typename T> void move() const; template<typename T> void prepend() const; template<typename T> void remove() const; template<typename T> void size() const; @@ -350,6 +355,14 @@ const Movable SimpleValue<Movable>::Values[] = { 110, 105, 101, 114, 111, 98 }; template<> const Custom SimpleValue<Custom>::Values[] = { 110, 105, 101, 114, 111, 98 }; +// Make some macros for the tests to use in order to be slightly more readable... +#define T_FOO SimpleValue<T>::at(0) +#define T_BAR SimpleValue<T>::at(1) +#define T_BAZ SimpleValue<T>::at(2) +#define T_CAT SimpleValue<T>::at(3) +#define T_DOG SimpleValue<T>::at(4) +#define T_BLAH SimpleValue<T>::at(5) + void tst_QVector::constructors_empty() const { QVector<int> emptyInt; @@ -626,6 +639,21 @@ void tst_QVector::appendCustom() const QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } +void tst_QVector::appendRvalue() const +{ +#ifdef Q_COMPILER_RVALUE_REFS + QVector<QString> v; + v.append("hello"); + QString world = "world"; + v.append(std::move(world)); + QVERIFY(world.isEmpty()); + QCOMPARE(v.front(), QString("hello")); + QCOMPARE(v.back(), QString("world")); +#else + QSKIP("This test requires that C++11 move semantics support is enabled in the compiler"); +#endif +} + void tst_QVector::at() const { QVector<QString> myvec; @@ -1604,6 +1632,44 @@ void tst_QVector::qhash() const QCOMPARE(qHash(l1), qHash(l2)); } +template <typename T> +void tst_QVector::move() const +{ + QVector<T> list; + list << T_FOO << T_BAR << T_BAZ; + + // move an item + list.move(0, list.count() - 1); + QCOMPARE(list, QVector<T>() << T_BAR << T_BAZ << T_FOO); + + // move it back + list.move(list.count() - 1, 0); + QCOMPARE(list, QVector<T>() << T_FOO << T_BAR << T_BAZ); + + // move an item in the middle + list.move(1, 0); + QCOMPARE(list, QVector<T>() << T_BAR << T_FOO << T_BAZ); +} + +void tst_QVector::moveInt() const +{ + move<int>(); +} + +void tst_QVector::moveMovable() const +{ + const int instancesCount = Movable::counter.loadAcquire(); + move<Movable>(); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); +} + +void tst_QVector::moveCustom() const +{ + const int instancesCount = Custom::counter.loadAcquire(); + move<Custom>(); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); +} + template<typename T> void tst_QVector::prepend() const { diff --git a/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp b/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp index 4202b87b2d679ccfdb2e8eba3447eca10e5734b8..0b8b63a1e89766f037e321e1d377d9ee504065b0 100644 --- a/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp +++ b/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp @@ -33,7 +33,7 @@ ****************************************************************************/ #include <QtTest/QtTest> -#include <private/qversionnumber_p.h> +#include <QtCore/qversionnumber.h> class tst_QVersionNumber : public QObject { diff --git a/tests/auto/dbus/qdbusabstractadaptor/BLACKLIST b/tests/auto/dbus/qdbusabstractadaptor/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..d3d970f4f473f1d210987d629e53b4965bcf8014 --- /dev/null +++ b/tests/auto/dbus/qdbusabstractadaptor/BLACKLIST @@ -0,0 +1,2 @@ +[overloadedSignalEmission] +linux diff --git a/tests/auto/dbus/qdbusmarshall/BLACKLIST b/tests/auto/dbus/qdbusmarshall/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..036378d2044ec986a8d79929a223b2e16a2083e8 --- /dev/null +++ b/tests/auto/dbus/qdbusmarshall/BLACKLIST @@ -0,0 +1,3 @@ +[receiveUnknownType] +ubuntu-14.04 +opensuse-13.1 diff --git a/tests/auto/gui/image/qicoimageformat/qicoimageformat.pro b/tests/auto/gui/image/qicoimageformat/qicoimageformat.pro index a58336e5114c74a89cc18e9e48de6fe90fe61419..7ed69ce1d1174a64ca73bbce13c0e5aba3fc4cc7 100644 --- a/tests/auto/gui/image/qicoimageformat/qicoimageformat.pro +++ b/tests/auto/gui/image/qicoimageformat/qicoimageformat.pro @@ -4,7 +4,7 @@ TARGET = tst_qicoimageformat SOURCES+= tst_qicoimageformat.cpp QT += testlib -wince*: { +wince { CONFIG(debug, debug|release):{ addPlugins.files = $$QT_BUILD_TREE/plugins/imageformats/qico4d.dll } else { diff --git a/tests/auto/gui/image/qicon/tst_qicon.cpp b/tests/auto/gui/image/qicon/tst_qicon.cpp index 20a08e10a20481b714895524c9f2ecbaa10c8096..9ed3873682ec8f08bc3579f3d6ffee33cca9ac35 100644 --- a/tests/auto/gui/image/qicon/tst_qicon.cpp +++ b/tests/auto/gui/image/qicon/tst_qicon.cpp @@ -75,14 +75,8 @@ private: const QString m_pngImageFileName; const QString m_pngRectFileName; const QString m_sourceFileName; - - const static QIcon staticIcon; }; -// Creating an icon statically should not cause a crash. -// But we do not officially support this. See QTBUG-8666 -const QIcon tst_QIcon::staticIcon = QIcon::fromTheme("edit-find"); - bool tst_QIcon::haveImageFormat(QByteArray const& desiredFormat) { return QImageReader::supportedImageFormats().contains(desiredFormat); @@ -354,10 +348,10 @@ void tst_QIcon::cacheKey() qint64 icon1_key = icon1.cacheKey(); QIcon icon2 = icon1; - QVERIFY(icon2.cacheKey() == icon1.cacheKey()); + QCOMPARE(icon2.cacheKey(), icon1.cacheKey()); icon2.detach(); QVERIFY(icon2.cacheKey() != icon1.cacheKey()); - QVERIFY(icon1.cacheKey() == icon1_key); + QCOMPARE(icon1.cacheKey(), icon1_key); } void tst_QIcon::detach() @@ -374,7 +368,7 @@ void tst_QIcon::detach() img1 = icon1.pixmap(32, 32).toImage(); img2 = icon2.pixmap(32, 32).toImage(); - QVERIFY(img1 == img2); + QCOMPARE(img1, img2); } void tst_QIcon::addFile() @@ -562,7 +556,7 @@ void tst_QIcon::fromTheme() QString firstSearchPath = QLatin1String(":/icons"); QString secondSearchPath = QLatin1String(":/second_icons"); QIcon::setThemeSearchPaths(QStringList() << firstSearchPath << secondSearchPath); - QVERIFY(QIcon::themeSearchPaths().size() == 2); + QCOMPARE(QIcon::themeSearchPaths().size(), 2); QCOMPARE(firstSearchPath, QIcon::themeSearchPaths()[0]); QCOMPARE(secondSearchPath, QIcon::themeSearchPaths()[1]); @@ -599,7 +593,7 @@ void tst_QIcon::fromTheme() // Test non existing icon with fallback noIcon = QIcon::fromTheme("broken-icon", abIcon); - QVERIFY(noIcon.cacheKey() == abIcon.cacheKey()); + QCOMPARE(noIcon.cacheKey(), abIcon.cacheKey()); // Test svg-only icon noIcon = QIcon::fromTheme("svg-icon", abIcon); diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index da29a57f98c2602129fb8655cf4b7a584802abd8..c1b32a273c96ff51b3d8d532f49c1d3df8dd8690 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -190,6 +190,8 @@ private slots: void devicePixelRatio(); void rgb30Unpremul(); + void rgb30Repremul_data(); + void rgb30Repremul(); void metadataPassthrough(); @@ -475,7 +477,7 @@ void tst_QImage::setAlphaChannel() image.setAlphaChannel(alphaChannel); image = image.convertToFormat(QImage::Format_ARGB32); - QVERIFY(image.format() == QImage::Format_ARGB32); + QCOMPARE(image.format(), QImage::Format_ARGB32); // alpha of 0 becomes black at a=0 due to premultiplication QRgb pixel = alpha == 0 ? 0 : qRgba(red, green, blue, alpha); @@ -1562,12 +1564,12 @@ void tst_QImage::createHeuristicMask() // line 2 QVERIFY(newMask.pixel(0,1) != newMask.pixel(1,1)); - QVERIFY(newMask.pixel(1,1) == newMask.pixel(2,1)); + QCOMPARE(newMask.pixel(1,1), newMask.pixel(2,1)); QVERIFY(newMask.pixel(2,1) != newMask.pixel(3,1)); // line 3 QVERIFY(newMask.pixel(0,2) != newMask.pixel(1,2)); - QVERIFY(newMask.pixel(1,2) == newMask.pixel(2,2)); + QCOMPARE(newMask.pixel(1,2), newMask.pixel(2,2)); QVERIFY(newMask.pixel(2,2) != newMask.pixel(3,2)); } #endif @@ -1578,10 +1580,10 @@ void tst_QImage::cacheKey() qint64 image1_key = image1.cacheKey(); QImage image2 = image1; - QVERIFY(image2.cacheKey() == image1.cacheKey()); + QCOMPARE(image2.cacheKey(), image1.cacheKey()); image2.detach(); QVERIFY(image2.cacheKey() != image1.cacheKey()); - QVERIFY(image1.cacheKey() == image1_key); + QCOMPARE(image1.cacheKey(), image1_key); } void tst_QImage::smoothScale() @@ -2946,6 +2948,31 @@ void tst_QImage::rgb30Unpremul() QCOMPARE(bbits[2], (3U << 30) | (201 << 20) | (393 << 10) | 777); } +void tst_QImage::rgb30Repremul_data() +{ + QTest::addColumn<uint>("color"); + for (int i = 255; i > 0; i -= 15) { + QTest::newRow(qPrintable(QStringLiteral("100% red=") + QString::number(i))) << qRgba(i, 0, 0, 0xff); + QTest::newRow(qPrintable(QStringLiteral("75% red=") + QString::number(i))) << qRgba(i, 0, 0, 0xc0); + QTest::newRow(qPrintable(QStringLiteral("50% red=") + QString::number(i))) << qRgba(i, 0, 0, 0x80); + QTest::newRow(qPrintable(QStringLiteral("37.5% red=") + QString::number(i))) << qRgba(i, 0, 0, 0x60); + } +} + +void tst_QImage::rgb30Repremul() +{ + QFETCH(uint, color); + + QImage a(1, 1, QImage::Format_ARGB32); + a.setPixel(0, 0, color); + + QImage b = a.convertToFormat(QImage::Format_A2BGR30_Premultiplied); + b = b.convertToFormat(QImage::Format_ARGB32); + uint expectedColor = qUnpremultiply(qPremultiply(color)); + uint newColor = b.pixel(0, 0); + QVERIFY(qAbs(qRed(newColor) - qRed(expectedColor)) <= 1); +} + void tst_QImage::metadataPassthrough() { QImage a(64, 64, QImage::Format_ARGB32); diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp index 4b3e2606fdd0a6c58e42fc4b0b169171075dce10..07b75adae4b8a2e75dd48c47ccbfc34cecb4008a 100644 --- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp @@ -733,7 +733,7 @@ void tst_QImageReader::gifHandlerBugs() QVERIFY(io.loopCount() != 1); int count=0; for (; io.canRead(); io.read(), ++count) ; - QVERIFY(count == 34); + QCOMPARE(count, 34); } // Task 95166 @@ -810,7 +810,7 @@ void tst_QImageReader::gifImageCount() QVERIFY(io.canRead()); QImage greenFrame = io.read(); - QVERIFY(io.imageCount() == 4); + QCOMPARE(io.imageCount(), 4); QVERIFY(io.canRead()); QImage blueFrame = io.read(); @@ -925,8 +925,8 @@ void tst_QImageReader::gifImageCount() } { QImageReader io(":images/trolltech.gif"); - QVERIFY(io.imageCount() == 34); - QVERIFY(io.size() == QSize(128,64)); + QCOMPARE(io.imageCount(), 34); + QCOMPARE(io.size(), QSize(128,64)); } } diff --git a/tests/auto/gui/image/qmovie/tst_qmovie.cpp b/tests/auto/gui/image/qmovie/tst_qmovie.cpp index c61c88d1a6495332016d6aecfc2b1cf141fa08f1..b8c99ca32423b35ae26ecc6354fd2ba9048acf31 100644 --- a/tests/auto/gui/image/qmovie/tst_qmovie.cpp +++ b/tests/auto/gui/image/qmovie/tst_qmovie.cpp @@ -188,8 +188,8 @@ void tst_QMovie::jumpToFrame() QMovie movie(QFINDTESTDATA(fileName)); movie.start(); movie.stop(); - QVERIFY(movie.jumpToFrame(-1) == false); - QVERIFY(movie.currentFrameNumber() == 0); + QVERIFY(!movie.jumpToFrame(-1)); + QCOMPARE(movie.currentFrameNumber(), 0); } void tst_QMovie::changeMovieFile() @@ -198,7 +198,7 @@ void tst_QMovie::changeMovieFile() movie.start(); movie.stop(); movie.setFileName(QFINDTESTDATA("animations/trolltech.gif")); - QVERIFY(movie.currentFrameNumber() == -1); + QCOMPARE(movie.currentFrameNumber(), -1); } #ifndef QT_NO_WIDGETS diff --git a/tests/auto/gui/image/qpicture/tst_qpicture.cpp b/tests/auto/gui/image/qpicture/tst_qpicture.cpp index 3cf848b08d5b8d2ef6a4a60605ad588cb23daa0c..5406284c056a9942756408eacf9bfb0ee731a91a 100644 --- a/tests/auto/gui/image/qpicture/tst_qpicture.cpp +++ b/tests/auto/gui/image/qpicture/tst_qpicture.cpp @@ -133,10 +133,10 @@ void tst_QPicture::boundingRect() QRect r2( 10, 20, 100, 60 ); QCOMPARE( p1.boundingRect(), r2 ); QPicture p2( p1 ); - QCOMPARE( p1.boundingRect(), r2 ); + QCOMPARE( p2.boundingRect(), r2 ); QPicture p3; p3 = p1; - QCOMPARE( p1.boundingRect(), r2 ); + QCOMPARE( p3.boundingRect(), r2 ); { QPicture p4; diff --git a/tests/auto/gui/image/qpixmap/qpixmap.pro b/tests/auto/gui/image/qpixmap/qpixmap.pro index 33c301a500e0ba463e2931c2f2c7af4bb06fee61..5a4656998a2849c973c2183e4ae5b753b0e54317 100644 --- a/tests/auto/gui/image/qpixmap/qpixmap.pro +++ b/tests/auto/gui/image/qpixmap/qpixmap.pro @@ -5,7 +5,7 @@ QT += core-private gui-private testlib qtHaveModule(widgets): QT += widgets widgets-private SOURCES += tst_qpixmap.cpp -!wince*:!winrt { +!wince:!winrt { win32:LIBS += -lgdi32 -luser32 } diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp index 58cc5824bd09c8997e813a550b2ab7d13087dda1..67d7e57fd448288c0527ed76ce4ec8f3f57c355c 100644 --- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp @@ -447,7 +447,7 @@ void tst_QPixmap::scroll() QString fileName = QString(":/images/%1.png").arg(QTest::currentDataTag()); QPixmap output(fileName); - QVERIFY(input.isNull() == output.isNull()); + QCOMPARE(input.isNull(), output.isNull()); QVERIFY(lenientCompare(pixmap, output)); QCOMPARE(exp, exposed); } @@ -713,11 +713,11 @@ void tst_QPixmap::cacheKey() QVERIFY(pixmap1.cacheKey() != pixmap2.cacheKey()); pixmap2 = pixmap1; - QVERIFY(pixmap2.cacheKey() == pixmap1.cacheKey()); + QCOMPARE(pixmap2.cacheKey(), pixmap1.cacheKey()); pixmap2.detach(); QVERIFY(pixmap2.cacheKey() != pixmap1.cacheKey()); - QVERIFY(pixmap1.cacheKey() == pixmap1_key); + QCOMPARE(pixmap1.cacheKey(), pixmap1_key); } // Test drawing a bitmap on a pixmap. @@ -743,7 +743,7 @@ void tst_QPixmap::isNull() { { QPixmap pixmap(1,1); - QVERIFY(pixmap.isNull() == false); + QVERIFY(!pixmap.isNull()); } { QPixmap pixmap(0,0); @@ -783,11 +783,11 @@ void tst_QPixmap::convertFromImageNoDetach() QPixmap pix = QPixmap::fromImage(orig); QImage copy = pix.toImage(); - QVERIFY(copy.format() == screenFormat); + QCOMPARE(copy.format(), screenFormat); const QImage constOrig = orig; const QImage constCopy = copy; - QVERIFY(constOrig.bits() == constCopy.bits()); + QCOMPARE(constOrig.bits(), constCopy.bits()); } void tst_QPixmap::convertFromImageDetach() @@ -821,7 +821,7 @@ void tst_QPixmap::convertFromImageCacheKey() QPixmap pix = QPixmap::fromImage(orig); QImage copy = pix.toImage(); - QVERIFY(copy.format() == screenFormat); + QCOMPARE(copy.format(), screenFormat); QCOMPARE(orig.cacheKey(), pix.cacheKey()); QCOMPARE(copy.cacheKey(), pix.cacheKey()); @@ -1135,9 +1135,9 @@ void tst_QPixmap::copy() void tst_QPixmap::depthOfNullObjects() { QBitmap b1; - QVERIFY(b1.depth() == 0); + QCOMPARE(b1.depth(), 0); QPixmap p4; - QVERIFY(p4.depth() == 0); + QCOMPARE(p4.depth(), 0); } void tst_QPixmap::transformed() @@ -1437,7 +1437,7 @@ void tst_QPixmap::task_246446() { QPixmap pm2(pm); } - QVERIFY(pm.width() == 10); + QCOMPARE(pm.width(), 10); QVERIFY(pm.mask().isNull()); } @@ -1490,14 +1490,14 @@ void tst_QPixmap::loadAsBitmapOrPixmap() // The do the same check for bitmaps.. QBitmap bitmap("temp_image.png"); QVERIFY(!bitmap.isNull()); - QVERIFY(bitmap.depth() == 1); + QCOMPARE(bitmap.depth(), 1); QVERIFY(bitmap.isQBitmap()); bitmap = QBitmap(); ok = bitmap.load("temp_image.png"); QVERIFY(ok); QVERIFY(!bitmap.isNull()); - QVERIFY(bitmap.depth() == 1); + QCOMPARE(bitmap.depth(), 1); QVERIFY(bitmap.isQBitmap()); } diff --git a/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp b/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp index f22aa63112d85332a6861aa605f219f445e5c0e9..a3cf66da18259e5b9d43665843426e86453f1c52 100644 --- a/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp +++ b/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp @@ -111,7 +111,7 @@ void tst_QPixmapCache::setCacheLimit() delete p1; QPixmapCache::setCacheLimit(0); - QVERIFY(QPixmapCache::find("P1") == 0); + QVERIFY(!QPixmapCache::find("P1")); p1 = new QPixmap(2, 3); QPixmapCache::setCacheLimit(1000); @@ -346,12 +346,12 @@ void tst_QPixmapCache::remove() QVERIFY(p1.toImage() == p1.toImage()); // sanity check QPixmapCache::remove("red"); - QVERIFY(QPixmapCache::find("red") == 0); + QVERIFY(!QPixmapCache::find("red")); QPixmapCache::remove("red"); - QVERIFY(QPixmapCache::find("red") == 0); + QVERIFY(!QPixmapCache::find("red")); QPixmapCache::remove("green"); - QVERIFY(QPixmapCache::find("green") == 0); + QVERIFY(!QPixmapCache::find("green")); //The int part of the API QPixmapCache::clear(); @@ -424,7 +424,7 @@ void tst_QPixmapCache::clear() QPixmapCache::clear(); for (int k = 0; k < numberOfKeys; ++k) - QVERIFY(QPixmapCache::find(QString::number(k)) == 0); + QVERIFY(!QPixmapCache::find(QString::number(k))); //The int part of the API QPixmap p2(10, 10); diff --git a/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp b/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp index 70daa244e71d16bc527095c51d054251b92e5fcb..ff263c166a33e63cc09184e643ff5655e05811ef 100644 --- a/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp +++ b/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp @@ -81,6 +81,7 @@ private slots: void clone(); void sortChildren(); void subclassing(); + void lessThan(); }; tst_QStandardItem::tst_QStandardItem() @@ -1107,5 +1108,19 @@ void tst_QStandardItem::subclassing() QCOMPARE(item->child(2), (QStandardItem*)child1); } +void tst_QStandardItem::lessThan() +{ + QStandardItem stringA("A"); + QStandardItem stringB("B"); + QStandardItem invalid1; + QStandardItem invalid2; + QVERIFY(stringA < stringB); + QVERIFY(!(stringB < stringA)); + // Items with invalid data go to the end. + QVERIFY(stringA < invalid1); + QVERIFY(!(invalid1 < stringA)); + QVERIFY(!(invalid1 < invalid2)); +} + QTEST_MAIN(tst_QStandardItem) #include "tst_qstandarditem.moc" diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp index 19365bffdd9dcc8eb651910de986b5c09f2984f3..2ddfdad7e42cff34530eef526f78cd4a6717bc16 100644 --- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp +++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp @@ -912,7 +912,7 @@ void tst_QGuiApplication::genericPluginsAndWindowSystemEvents() QGuiApplication app(argc, argv); QVERIFY(QGuiApplication::primaryScreen()); - QVERIFY(QGuiApplication::primaryScreen()->orientation() == testOrientationToSend); + QCOMPARE(QGuiApplication::primaryScreen()->orientation(), testOrientationToSend); QCOMPARE(testReceiver.customEvents, 0); QCoreApplication::sendPostedEvents(&testReceiver); diff --git a/tests/auto/gui/kernel/qguieventloop/BLACKLIST b/tests/auto/gui/kernel/qguieventloop/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..688df0192bd84b861e21aa266e550e2476e25cff --- /dev/null +++ b/tests/auto/gui/kernel/qguieventloop/BLACKLIST @@ -0,0 +1,2 @@ +[processEvents] +ubuntu-14.04 diff --git a/tests/auto/gui/kernel/qguivariant/no_application/main.cpp b/tests/auto/gui/kernel/qguivariant/no_application/main.cpp index c37e633d75b8248dc969c9b23bd65bb4048cf866..1294751224abd8f956df15ec945e482308b8e209 100644 --- a/tests/auto/gui/kernel/qguivariant/no_application/main.cpp +++ b/tests/auto/gui/kernel/qguivariant/no_application/main.cpp @@ -56,7 +56,7 @@ void tst_QGuiVariantNoApplication::variantWithoutApplication() { QVariant v = QString("red"); - QVERIFY(qvariant_cast<QColor>(v) == QColor(Qt::red)); + QCOMPARE(qvariant_cast<QColor>(v), QColor(Qt::red)); } diff --git a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp index 58c595ad07b87f2373b5b579401ea043decb68a2..0e822ced5b46126598f149267330595399b2169b 100644 --- a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp +++ b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp @@ -140,13 +140,13 @@ void tst_QGuiVariant::constructor_invalid() QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^Trying to construct an instance of an invalid type, type id:")); QVariant variant(static_cast<QVariant::Type>(typeId)); QVERIFY(!variant.isValid()); - QVERIFY(variant.userType() == QMetaType::UnknownType); + QCOMPARE(variant.userType(), int(QMetaType::UnknownType)); } { QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^Trying to construct an instance of an invalid type, type id:")); QVariant variant(typeId, /* copy */ 0); QVERIFY(!variant.isValid()); - QVERIFY(variant.userType() == QMetaType::UnknownType); + QCOMPARE(variant.userType(), int(QMetaType::UnknownType)); } } @@ -611,9 +611,9 @@ void tst_QGuiVariant::writeToReadFromDataStream() // the uninitialized float can be NaN (observed on Windows Mobile 5 ARMv4i) float readFloat = qvariant_cast<float>(readVariant); float writtenFloat = qvariant_cast<float>(writeVariant); - QVERIFY(qIsNaN(readFloat) == qIsNaN(writtenFloat)); + QCOMPARE(qIsNaN(readFloat), qIsNaN(writtenFloat)); if (!qIsNaN(readFloat)) - QVERIFY(readFloat == writtenFloat); + QCOMPARE(readFloat, writtenFloat); } break; } @@ -632,7 +632,7 @@ void tst_QGuiVariant::writeToReadFromOldDataStream() dataFileStream.setVersion(QDataStream::Qt_4_9); QVariant readVariant; dataFileStream >> readVariant; - QVERIFY(readVariant.userType() == QMetaType::QPolygonF); + QCOMPARE(readVariant.userType(), int(QMetaType::QPolygonF)); QCOMPARE(testVariant, readVariant); file.close(); } @@ -656,7 +656,7 @@ void tst_QGuiVariant::writeToReadFromOldDataStream() QDataStream readVarData(variantData); readVarData >> dummy; readVarData >> polyData50; - QVERIFY(polyData49 == polyData50); + QCOMPARE(polyData49, polyData50); } } diff --git a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp index 2edfddf6dd4a3c576422951308647fdf04fe5b59..3fcbd0a16f0ff5909131ecb360adcd8cd6f088cf 100644 --- a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp +++ b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp @@ -400,7 +400,7 @@ void tst_QKeySequence::keyBindings() void tst_QKeySequence::mnemonic_data() { #ifdef Q_OS_MAC - QSKIP("Test not applicable to Mac OS X"); + QSKIP("Test not applicable to OS X"); #endif QTest::addColumn<QString>("string"); QTest::addColumn<QString>("key"); diff --git a/tests/auto/gui/kernel/qopenglwindow/tst_qopenglwindow.cpp b/tests/auto/gui/kernel/qopenglwindow/tst_qopenglwindow.cpp index dcead8bfbf195775c17a071e73250e784af3354d..1fc4967b123d2b55974bf7bcc286ccdf0fb134fc 100644 --- a/tests/auto/gui/kernel/qopenglwindow/tst_qopenglwindow.cpp +++ b/tests/auto/gui/kernel/qopenglwindow/tst_qopenglwindow.cpp @@ -248,7 +248,7 @@ public: GLuint fbo = 0xFFFF; QOpenGLContext::currentContext()->functions()->glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *) &fbo); - QVERIFY(fbo == 0); + QCOMPARE(fbo, GLuint(0)); } void paintGL() Q_DECL_OVERRIDE { @@ -272,7 +272,7 @@ public: GLuint fbo = 0xFFFF; QOpenGLContext::currentContext()->functions()->glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *) &fbo); - QVERIFY(fbo == 0); + QCOMPARE(fbo, GLuint(0)); } }; diff --git a/tests/auto/gui/kernel/qpixelformat/tst_qpixelformat.cpp b/tests/auto/gui/kernel/qpixelformat/tst_qpixelformat.cpp index 0d5991ef419aa6d616f50e9d3c3b53452967cb6a..a5f86c6c09b202ab026f42366cac30b52f96d2f9 100644 --- a/tests/auto/gui/kernel/qpixelformat/tst_qpixelformat.cpp +++ b/tests/auto/gui/kernel/qpixelformat/tst_qpixelformat.cpp @@ -53,7 +53,7 @@ void tst_QPixelFormat::testOperators() { QPixelFormat first = qPixelFormatRgba(8,8,8,8,QPixelFormat::UsesAlpha, QPixelFormat::AtBeginning, QPixelFormat::Premultiplied); QPixelFormat second = qPixelFormatRgba(8,8,8,8,QPixelFormat::UsesAlpha, QPixelFormat::AtBeginning, QPixelFormat::Premultiplied); - QVERIFY(first == second); + QCOMPARE(first, second); QPixelFormat third = qPixelFormatRgba(8,8,8,8,QPixelFormat::UsesAlpha, QPixelFormat::AtEnd, QPixelFormat::NotPremultiplied); QVERIFY(first != third); diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index aa1f573aa94043840b381f9521b5b34944e039ff..d754e0b3c3ad516a6cccd10092922c5ed5d592fc 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -39,33 +39,8 @@ #include <QtWidgets/QWidget> #include <QtTest> #include <qpa/qwindowsysteminterface.h> - -// FIXME: Use static functions of QWindowSystemInterface introduced with HighDPI scaling in 5.6 instead. -static QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint& pt) -{ - QWindowSystemInterface::TouchPoint p; - p.id = pt.id(); - p.flags = pt.flags(); - p.normalPosition = pt.normalizedPos(); - p.area = pt.screenRect(); - p.pressure = pt.pressure(); - p.state = pt.state(); - p.velocity = pt.velocity(); - p.rawPositions = pt.rawScreenPositions(); - return p; -} - -static QList<struct QWindowSystemInterface::TouchPoint> touchPointList(const QList<QTouchEvent::TouchPoint>& pointList) -{ - QList<struct QWindowSystemInterface::TouchPoint> newList; - - Q_FOREACH (QTouchEvent::TouchPoint p, pointList) - { - newList.append(touchPoint(p)); - } - return newList; -} - +#include <qpa/qwindowsysteminterface_p.h> +#include <private/qhighdpiscaling_p.h> class tst_QTouchEventWidget : public QWidget { @@ -170,7 +145,10 @@ public: } QRectF boundingRect() const Q_DECL_OVERRIDE { return QRectF(0, 0, 10, 10); } - void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) Q_DECL_OVERRIDE { } + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) Q_DECL_OVERRIDE + { + painter->fillRect(QRectF(QPointF(0, 0), boundingRect().size()), Qt::yellow); + } bool sceneEvent(QEvent *event) Q_DECL_OVERRIDE { @@ -619,11 +597,10 @@ void tst_QTouchEvent::basicRawEventTranslation() rawPosList << QPointF(12, 34) << QPointF(56, 78); rawTouchPoint.setRawScreenPositions(rawPosList); const ulong timestamp = 1234; - QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(), - timestamp, - touchScreenDevice, - touchPointList( - QList<QTouchEvent::TouchPoint>() << rawTouchPoint)); + QWindow *window = touchWidget.windowHandle(); + QList<QWindowSystemInterface::TouchPoint> nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoint, window); + QWindowSystemInterface::handleTouchEvent(window, timestamp, touchScreenDevice, nativeTouchPoints); QCoreApplication::processEvents(); QVERIFY(touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); @@ -650,16 +627,16 @@ void tst_QTouchEvent::basicRawEventTranslation() QCOMPARE(touchBeginPoint.sceneRect(), touchBeginPoint.screenRect()); QCOMPARE(touchBeginPoint.pressure(), qreal(1.)); QCOMPARE(touchBeginPoint.velocity(), QVector2D()); - QCOMPARE(touchBeginPoint.rawScreenPositions(), rawPosList); + if (!QHighDpiScaling::isActive()) + QCOMPARE(touchBeginPoint.rawScreenPositions(), rawPosList); // moving the point should translate to TouchUpdate rawTouchPoint.setState(Qt::TouchPointMoved); rawTouchPoint.setScreenPos(screenPos + delta); rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry)); - QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(), - 0, - touchScreenDevice, - touchPointList(QList<QTouchEvent::TouchPoint>() << rawTouchPoint)); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoint, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints); QCoreApplication::processEvents(); QVERIFY(touchWidget.seenTouchBegin); QVERIFY(touchWidget.seenTouchUpdate); @@ -689,10 +666,9 @@ void tst_QTouchEvent::basicRawEventTranslation() rawTouchPoint.setState(Qt::TouchPointReleased); rawTouchPoint.setScreenPos(screenPos + delta + delta); rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry)); - QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(), - 0, - touchScreenDevice, - touchPointList(QList<QTouchEvent::TouchPoint>() << rawTouchPoint)); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoint, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints); QCoreApplication::processEvents(); QVERIFY(touchWidget.seenTouchBegin); QVERIFY(touchWidget.seenTouchUpdate); @@ -759,10 +735,10 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() rawTouchPoints[1].setState(Qt::TouchPointPressed); rawTouchPoints[1].setScreenPos(rightScreenPos); rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); - QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(), - 0, - touchScreenDevice, - touchPointList(rawTouchPoints)); + QWindow *window = touchWidget.windowHandle(); + QList<QWindowSystemInterface::TouchPoint> nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints); QCoreApplication::processEvents(); QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); @@ -824,10 +800,9 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() rawTouchPoints[1].setState(Qt::TouchPointMoved); rawTouchPoints[1].setScreenPos(centerScreenPos); rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); - QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(), - 0, - touchScreenDevice, - touchPointList(rawTouchPoints)); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints); QCoreApplication::processEvents(); QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); @@ -889,10 +864,9 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() rawTouchPoints[1].setState(Qt::TouchPointReleased); rawTouchPoints[1].setScreenPos(centerScreenPos); rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); - QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(), - 0, - touchScreenDevice, - touchPointList(rawTouchPoints)); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints); QCoreApplication::processEvents(); QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); @@ -989,10 +963,10 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() rawTouchPoints[1].setState(Qt::TouchPointPressed); rawTouchPoints[1].setScreenPos(rightScreenPos); rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); - QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(), - 0, - touchPadDevice, - touchPointList(rawTouchPoints)); + QWindow *window = touchWidget.windowHandle(); + QList<QWindowSystemInterface::TouchPoint> nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchPadDevice, nativeTouchPoints); QCoreApplication::processEvents(); QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); @@ -1055,10 +1029,9 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() rawTouchPoints[1].setState(Qt::TouchPointMoved); rawTouchPoints[1].setScreenPos(centerScreenPos); rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); - QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(), - 0, - touchPadDevice, - touchPointList(rawTouchPoints)); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchPadDevice, nativeTouchPoints); QCoreApplication::processEvents(); QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); @@ -1120,10 +1093,9 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() rawTouchPoints[1].setState(Qt::TouchPointReleased); rawTouchPoints[1].setScreenPos(centerScreenPos); rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); - QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(), - 0, - touchPadDevice, - touchPointList(rawTouchPoints)); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchPadDevice, nativeTouchPoints); QCoreApplication::processEvents(); QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); @@ -1382,10 +1354,10 @@ void tst_QTouchEvent::deleteInRawEventTranslation() rawTouchPoints[2].setNormalizedPos(normalized(rawTouchPoints[2].pos(), screenGeometry)); // generate begin events on all widgets, the left widget should die - QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(), - 0, - touchScreenDevice, - touchPointList(rawTouchPoints)); + QWindow *window = touchWidget.windowHandle(); + QList<QWindowSystemInterface::TouchPoint> nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints); QCoreApplication::processEvents(); QVERIFY(leftWidget.isNull()); QVERIFY(!centerWidget.isNull()); @@ -1395,20 +1367,18 @@ void tst_QTouchEvent::deleteInRawEventTranslation() rawTouchPoints[0].setState(Qt::TouchPointMoved); rawTouchPoints[1].setState(Qt::TouchPointMoved); rawTouchPoints[2].setState(Qt::TouchPointMoved); - QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(), - 0, - touchScreenDevice, - touchPointList(rawTouchPoints)); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints); QCoreApplication::processEvents(); // generate end events on all widget, the right widget should die rawTouchPoints[0].setState(Qt::TouchPointReleased); rawTouchPoints[1].setState(Qt::TouchPointReleased); rawTouchPoints[2].setState(Qt::TouchPointReleased); - QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(), - 0, - touchScreenDevice, - touchPointList(rawTouchPoints)); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints); QCoreApplication::processEvents(); } @@ -1444,8 +1414,11 @@ void tst_QTouchEvent::crashInQGraphicsSceneAfterNotHandlingTouchBegin() void tst_QTouchEvent::touchBeginWithGraphicsWidget() { + if (QHighDpiScaling::isActive()) + QSKIP("Fails when scaling is active"); QGraphicsScene scene; QGraphicsView view(&scene); + view.setWindowTitle(QTest::currentTestFunction()); QScopedPointer<tst_QTouchEventGraphicsItem> root(new tst_QTouchEventGraphicsItem); root->setAcceptTouchEvents(true); scene.addItem(root.data()); @@ -1454,10 +1427,13 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget() glassWidget->setMinimumSize(100, 100); scene.addItem(glassWidget.data()); - view.resize(200, 200); + view.setAlignment(Qt::AlignLeft | Qt::AlignTop); + const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry(); + view.resize(availableGeometry.size() - QSize(100, 100)); + view.move(availableGeometry.topLeft() + QPoint(50, 50)); + view.fitInView(scene.sceneRect()); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); - view.fitInView(scene.sceneRect()); QTest::touchEvent(&view, touchScreenDevice) .press(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport()); @@ -1598,12 +1574,15 @@ void tst_QTouchEvent::testMultiDevice() QWindowSystemInterface::TouchPoint tp; tp.id = 0; tp.state = Qt::TouchPointPressed; - tp.area = QRectF(120, 120, 20, 20); + const QPoint screenOrigin = w.screen()->geometry().topLeft(); + const QRect area0(120, 120, 20, 20); + tp.area = QHighDpi::toNative(area0, QHighDpiScaling::factor(&w), screenOrigin); pointsOne.append(tp); pointsTwo.append(tp); tp.id = 1; - tp.area = QRectF(140, 140, 20, 20); + const QRect area1(140, 140, 20, 20); + tp.area = QHighDpi::toNative(area1, QHighDpiScaling::factor(&w), screenOrigin); pointsTwo.append(tp); QWindowSystemInterface::handleTouchEvent(&w, deviceOne, pointsOne); @@ -1618,12 +1597,12 @@ void tst_QTouchEvent::testMultiDevice() QCOMPARE(filter.d.value(deviceOne).points.count(), 1); QCOMPARE(filter.d.value(deviceTwo).points.count(), 2); - QCOMPARE(filter.d.value(deviceOne).points.at(0).screenRect(), pointsOne[0].area); + QCOMPARE(filter.d.value(deviceOne).points.at(0).screenRect(), QRectF(area0)); QCOMPARE(filter.d.value(deviceOne).points.at(0).state(), pointsOne[0].state); - QCOMPARE(filter.d.value(deviceTwo).points.at(0).screenRect(), pointsTwo[0].area); + QCOMPARE(filter.d.value(deviceTwo).points.at(0).screenRect(), QRectF(area0)); QCOMPARE(filter.d.value(deviceTwo).points.at(0).state(), pointsTwo[0].state); - QCOMPARE(filter.d.value(deviceTwo).points.at(1).screenRect(), pointsTwo[1].area); + QCOMPARE(filter.d.value(deviceTwo).points.at(1).screenRect(), QRectF(area1)); QCOMPARE(filter.d.value(deviceTwo).points.at(1).state(), pointsTwo[1].state); } diff --git a/tests/auto/gui/kernel/qwindow/qwindow.pro b/tests/auto/gui/kernel/qwindow/qwindow.pro index 521058579664791bc420d5c0fae95d27b71ccd0c..08e1b1d3a02e8ee4d65b24abf93f882ec2feea19 100644 --- a/tests/auto/gui/kernel/qwindow/qwindow.pro +++ b/tests/auto/gui/kernel/qwindow/qwindow.pro @@ -5,4 +5,4 @@ QT += core-private gui-private testlib SOURCES += tst_qwindow.cpp -contains(QT_CONFIG,dynamicgl):win32:!wince*:!winrt: LIBS += -luser32 +contains(QT_CONFIG,dynamicgl):win32:!wince:!winrt: LIBS += -luser32 diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index d361aa12a648287038301daf094c1a4995298915..ccb8c759c6a66729e871677dbeab64ea89c38391 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -35,6 +35,7 @@ #include <qpa/qwindowsysteminterface.h> #include <qpa/qplatformintegration.h> #include <private/qguiapplication_p.h> +#include <private/qhighdpiscaling_p.h> #include <QtGui/QPainter> #include <QtTest/QtTest> @@ -265,6 +266,19 @@ void tst_QWindow::positioning_data() #endif } +// Compare a window position that may go through scaling in the platform plugin with fuzz. +static inline bool qFuzzyCompareWindowPosition(const QPoint &p1, const QPoint p2, int fuzz) +{ + return (p1 - p2).manhattanLength() <= fuzz; +} + +static QString msgPointMismatch(const QPoint &p1, const QPoint p2) +{ + QString result; + QDebug(&result) << p1 << "!=" << p2 << ", manhattanLength=" << (p1 - p2).manhattanLength(); + return result; +} + void tst_QWindow::positioning() { if (!QGuiApplicationPrivate::platformIntegration()->hasCapability( @@ -327,21 +341,25 @@ void tst_QWindow::positioning() // if our positioning is actually fully respected by the window manager // test whether it correctly handles frame positioning as well if (originalPos == geometry.topLeft() && (originalMargins.top() != 0 || originalMargins.left() != 0)) { - QPoint framePos = QPlatformScreen::platformScreenForWindow(&window)->availableGeometry().center(); + const QScreen *screen = window.screen(); + const QRect availableGeometry = screen->availableGeometry(); + const QPoint framePos = availableGeometry.center(); window.reset(); const QPoint oldFramePos = window.framePosition(); window.setFramePosition(framePos); QTRY_VERIFY(window.received(QEvent::Move)); - if (window.framePosition() != framePos) { + const int fuzz = int(QHighDpiScaling::factor(&window)); + if (!qFuzzyCompareWindowPosition(window.framePosition(), framePos, fuzz)) { qDebug() << "About to fail auto-test. Here is some additional information:"; qDebug() << "window.framePosition() == " << window.framePosition(); qDebug() << "old frame position == " << oldFramePos; qDebug() << "We received " << window.received(QEvent::Move) << " move events"; qDebug() << "frame positions after each move event:" << window.m_framePositionsOnMove; } - QTRY_COMPARE(framePos, window.framePosition()); + QTRY_VERIFY2(qFuzzyCompareWindowPosition(window.framePosition(), framePos, fuzz), + qPrintable(msgPointMismatch(window.framePosition(), framePos))); QTRY_COMPARE(originalMargins, window.frameMargins()); QCOMPARE(window.position(), window.framePosition() + QPoint(originalMargins.left(), originalMargins.top())); @@ -357,7 +375,8 @@ void tst_QWindow::positioning() void tst_QWindow::positioningDuringMinimized() { // QTBUG-39544, setting a geometry in minimized state should work as well. - if (QGuiApplication::platformName().compare("windows", Qt::CaseInsensitive)) + if (QGuiApplication::platformName().compare("windows", Qt::CaseInsensitive) != 0 + && QGuiApplication::platformName().compare("cocoa", Qt::CaseInsensitive) != 0) QSKIP("Not supported on this platform"); Window window; window.setTitle(QStringLiteral("positioningDuringMinimized")); @@ -418,14 +437,14 @@ void tst_QWindow::platformSurface() QCOMPARE(window.geometry(), geometry); window.create(); - QTRY_VERIFY(window.received(QEvent::PlatformSurface) == 1); - QTRY_VERIFY(window.surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated); + QTRY_COMPARE(window.received(QEvent::PlatformSurface), 1); + QTRY_COMPARE(window.surfaceEventType(), QPlatformSurfaceEvent::SurfaceCreated); QTRY_VERIFY(window.handle() != Q_NULLPTR); window.destroy(); - QTRY_VERIFY(window.received(QEvent::PlatformSurface) == 2); - QTRY_VERIFY(window.surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed); - QTRY_VERIFY(window.handle() == Q_NULLPTR); + QTRY_COMPARE(window.received(QEvent::PlatformSurface), 2); + QTRY_COMPARE(window.surfaceEventType(), QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed); + QTRY_VERIFY(!window.handle()); // Check for synchronous delivery of platform surface events and that the platform // surface always existed upon event delivery @@ -487,7 +506,7 @@ void tst_QWindow::isActive() context.swapBuffers(&window); #endif QTRY_COMPARE(window.received(QEvent::Resize), 1); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QVERIFY(window.isActive()); Window child; @@ -499,7 +518,7 @@ void tst_QWindow::isActive() child.requestActivate(); - QTRY_VERIFY(QGuiApplication::focusWindow() == &child); + QTRY_COMPARE(QGuiApplication::focusWindow(), &child); QVERIFY(child.isActive()); // parent shouldn't receive new resize events from child being shown @@ -522,7 +541,7 @@ void tst_QWindow::isActive() QTRY_VERIFY(dialog.isExposed()); QCoreApplication::processEvents(); QTRY_COMPARE(dialog.received(QEvent::Resize), 1); - QTRY_VERIFY(QGuiApplication::focusWindow() == &dialog); + QTRY_COMPARE(QGuiApplication::focusWindow(), &dialog); QVERIFY(dialog.isActive()); // transient child has focus @@ -533,7 +552,7 @@ void tst_QWindow::isActive() window.requestActivate(); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QCoreApplication::processEvents(); QTRY_COMPARE(dialog.received(QEvent::FocusOut), 1); QTRY_COMPARE(window.received(QEvent::FocusIn), 2); @@ -654,15 +673,13 @@ void tst_QWindow::testInputEvents() window.showNormal(); QVERIFY(QTest::qWaitForWindowExposed(&window)); - QWindowSystemInterface::handleKeyEvent(&window, QEvent::KeyPress, Qt::Key_A, Qt::NoModifier); - QWindowSystemInterface::handleKeyEvent(&window, QEvent::KeyRelease, Qt::Key_A, Qt::NoModifier); + QTest::keyClick(&window, Qt::Key_A, Qt::NoModifier); QCoreApplication::processEvents(); QCOMPARE(window.keyPressCode, int(Qt::Key_A)); QCOMPARE(window.keyReleaseCode, int(Qt::Key_A)); QPointF local(12, 34); - QWindowSystemInterface::handleMouseEvent(&window, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, local, local, Qt::NoButton); + QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, local.toPoint()); QCoreApplication::processEvents(); QCOMPARE(window.mousePressButton, int(Qt::LeftButton)); QCOMPARE(window.mouseReleaseButton, int(Qt::LeftButton)); @@ -688,15 +705,17 @@ void tst_QWindow::testInputEvents() // Now with null pointer as window. local param should not be utilized: // handleMouseEvent() with tlw == 0 means the event is in global coords only. window.mousePressButton = window.mouseReleaseButton = 0; - QPointF nonWindowGlobal(window.geometry().topRight() + QPoint(200, 50)); // not inside the window - QWindowSystemInterface::handleMouseEvent(0, nonWindowGlobal, nonWindowGlobal, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(0, nonWindowGlobal, nonWindowGlobal, Qt::NoButton); + const QPointF nonWindowGlobal(window.geometry().topRight() + QPoint(200, 50)); // not inside the window + const QPointF deviceNonWindowGlobal = QHighDpi::toNativePixels(nonWindowGlobal, window.screen()); + QWindowSystemInterface::handleMouseEvent(0, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::LeftButton); + QWindowSystemInterface::handleMouseEvent(0, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::NoButton); QCoreApplication::processEvents(); QCOMPARE(window.mousePressButton, 0); QCOMPARE(window.mouseReleaseButton, 0); - QPointF windowGlobal = window.mapToGlobal(local.toPoint()); - QWindowSystemInterface::handleMouseEvent(0, windowGlobal, windowGlobal, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(0, windowGlobal, windowGlobal, Qt::NoButton); + const QPointF windowGlobal = window.mapToGlobal(local.toPoint()); + const QPointF deviceWindowGlobal = QHighDpi::toNativePixels(windowGlobal, window.screen()); + QWindowSystemInterface::handleMouseEvent(0, deviceWindowGlobal, deviceWindowGlobal, Qt::LeftButton); + QWindowSystemInterface::handleMouseEvent(0, deviceWindowGlobal, deviceWindowGlobal, Qt::NoButton); QCoreApplication::processEvents(); QCOMPARE(window.mousePressButton, int(Qt::LeftButton)); QCOMPARE(window.mouseReleaseButton, int(Qt::LeftButton)); @@ -718,7 +737,7 @@ void tst_QWindow::touchToMouseTranslation() const QRectF moveArea(105, 108, 4, 4); tp1.id = 1; tp1.state = Qt::TouchPointPressed; - tp1.area = pressArea; + tp1.area = QHighDpi::toNativePixels(pressArea, &window); tp2.id = 2; tp2.state = Qt::TouchPointPressed; points << tp1 << tp2; @@ -729,7 +748,7 @@ void tst_QWindow::touchToMouseTranslation() tp1.state = Qt::TouchPointStationary; tp2.id = 1; tp2.state = Qt::TouchPointMoved; - tp2.area = moveArea; + tp2.area = QHighDpi::toNativePixels(moveArea, &window); points.clear(); points << tp1 << tp2; QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points); @@ -946,12 +965,15 @@ void tst_QWindow::touchCancelWithTouchToMouse() tp1.id = 1; tp1.state = Qt::TouchPointPressed; - tp1.area = QRect(100, 100, 4, 4); + const QRect area(100, 100, 4, 4); + tp1.area = QHighDpi::toNativePixels(area, &window); points << tp1; QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points); QCoreApplication::processEvents(); QTRY_COMPARE(window.mousePressButton, int(Qt::LeftButton)); - QTRY_COMPARE(window.mousePressScreenPos, points[0].area.center()); + const int fuzz = 2 * int(QHighDpiScaling::factor(&window)); + QTRY_VERIFY2(qFuzzyCompareWindowPosition(window.mousePressScreenPos.toPoint(), area.center(), fuzz), + qPrintable(msgPointMismatch(window.mousePressScreenPos.toPoint(), area.center()))); // Cancel the touch. Should result in a mouse release for windows that have // have an active touch-to-mouse sequence. @@ -1149,8 +1171,9 @@ void tst_QWindow::mouseEventSequence() ulong timestamp = 0; QPointF local(12, 34); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton); + const QPointF deviceLocal = QHighDpi::toNativePixels(local, &window); + QWindowSystemInterface::handleMouseEvent(&window, timestamp++, deviceLocal, deviceLocal, Qt::LeftButton); + QWindowSystemInterface::handleMouseEvent(&window, timestamp++, deviceLocal, deviceLocal, Qt::NoButton); QCoreApplication::processEvents(); QCOMPARE(window.mousePressedCount, 1); QCOMPARE(window.mouseReleasedCount, 1); @@ -1308,14 +1331,14 @@ void tst_QWindow::inputReentrancy() class TabletTestWindow : public QWindow { public: - TabletTestWindow() : eventType(0) { } + TabletTestWindow() : eventType(QEvent::None) { } void tabletEvent(QTabletEvent *ev) { eventType = ev->type(); eventGlobal = ev->globalPosF(); eventLocal = ev->posF(); eventDevice = ev->device(); } - int eventType; + QEvent::Type eventType; QPointF eventGlobal, eventLocal; int eventDevice; bool eventFilter(QObject *obj, QEvent *ev) { @@ -1337,25 +1360,27 @@ void tst_QWindow::tabletEvents() window.setGeometry(QRect(m_availableTopLeft + QPoint(10, 10), m_testWindowSize)); qGuiApp->installEventFilter(&window); - QPoint local(10, 10); - QPoint global = window.mapToGlobal(local); - QWindowSystemInterface::handleTabletEvent(&window, true, local, global, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0); + const QPoint local(10, 10); + const QPoint global = window.mapToGlobal(local); + const QPoint deviceLocal = QHighDpi::toNativeLocalPosition(local, &window); + const QPoint deviceGlobal = QHighDpi::toNativePixels(global, window.screen()); + QWindowSystemInterface::handleTabletEvent(&window, true, deviceLocal, deviceGlobal, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0); QCoreApplication::processEvents(); QTRY_VERIFY(window.eventType == QEvent::TabletPress); QTRY_COMPARE(window.eventGlobal.toPoint(), global); QTRY_COMPARE(window.eventLocal.toPoint(), local); - QWindowSystemInterface::handleTabletEvent(&window, false, local, global, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0); + QWindowSystemInterface::handleTabletEvent(&window, false, deviceLocal, deviceGlobal, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0); QCoreApplication::processEvents(); - QTRY_VERIFY(window.eventType == QEvent::TabletRelease); + QTRY_COMPARE(window.eventType, QEvent::TabletRelease); QWindowSystemInterface::handleTabletEnterProximityEvent(1, 2, 3); QCoreApplication::processEvents(); - QTRY_VERIFY(window.eventType == QEvent::TabletEnterProximity); + QTRY_COMPARE(window.eventType, QEvent::TabletEnterProximity); QTRY_COMPARE(window.eventDevice, 1); QWindowSystemInterface::handleTabletLeaveProximityEvent(1, 2, 3); QCoreApplication::processEvents(); - QTRY_VERIFY(window.eventType == QEvent::TabletLeaveProximity); + QTRY_COMPARE(window.eventType, QEvent::TabletLeaveProximity); QTRY_COMPARE(window.eventDevice, 1); #endif @@ -1703,13 +1728,13 @@ void tst_QWindow::requestUpdate() QCoreApplication::processEvents(); QTRY_VERIFY(window.isExposed()); - QVERIFY(window.received(QEvent::UpdateRequest) == 0); + QCOMPARE(window.received(QEvent::UpdateRequest), 0); window.requestUpdate(); - QTRY_VERIFY(window.received(QEvent::UpdateRequest) == 1); + QTRY_COMPARE(window.received(QEvent::UpdateRequest), 1); window.requestUpdate(); - QTRY_VERIFY(window.received(QEvent::UpdateRequest) == 2); + QTRY_COMPARE(window.received(QEvent::UpdateRequest), 2); } #include <tst_qwindow.moc> diff --git a/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp b/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp index e7659a25bdcf9b33cb095feda80ea3eca9123f17..463322ff2accd43f2a00848f603bc51649d843e6 100644 --- a/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp +++ b/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp @@ -673,7 +673,7 @@ void tst_QMatrixNxN::compare2x2() QMatrix2x2 m2(uniqueValues2); QMatrix2x2 m3(transposedValues2); - QVERIFY(m1 == m2); + QCOMPARE(m1, m2); QVERIFY(!(m1 != m2)); QVERIFY(m1 != m3); QVERIFY(!(m1 == m3)); @@ -686,7 +686,7 @@ void tst_QMatrixNxN::compare3x3() QMatrix3x3 m2(uniqueValues3); QMatrix3x3 m3(transposedValues3); - QVERIFY(m1 == m2); + QCOMPARE(m1, m2); QVERIFY(!(m1 != m2)); QVERIFY(m1 != m3); QVERIFY(!(m1 == m3)); @@ -699,7 +699,7 @@ void tst_QMatrixNxN::compare4x4() QMatrix4x4 m2(uniqueValues4); QMatrix4x4 m3(transposedValues4); - QVERIFY(m1 == m2); + QCOMPARE(m1, m2); QVERIFY(!(m1 != m2)); QVERIFY(m1 != m3); QVERIFY(!(m1 == m3)); @@ -712,7 +712,7 @@ void tst_QMatrixNxN::compare4x3() QMatrix4x3 m2(uniqueValues4x3); QMatrix4x3 m3(transposedValues3x4); - QVERIFY(m1 == m2); + QCOMPARE(m1, m2); QVERIFY(!(m1 != m2)); QVERIFY(m1 != m3); QVERIFY(!(m1 == m3)); @@ -1858,7 +1858,7 @@ void tst_QMatrixNxN::inverted4x4() if (invertible) QVERIFY(m1.determinant() != 0.0f); else - QVERIFY(m1.determinant() == 0.0f); + QCOMPARE(m1.determinant(), 0.0f); Matrix4 m1alt; memcpy(m1alt.v, (const float *)m1Values, sizeof(m1alt.v)); @@ -1992,7 +1992,7 @@ void tst_QMatrixNxN::scale4x4() if (z == 1.0f) { QMatrix4x4 m2b; m2b.scale(x, y); - QVERIFY(m2b == m2); + QCOMPARE(m2b, m2); } QVector3D v1(2.0f, 3.0f, -4.0f); @@ -2051,7 +2051,7 @@ void tst_QMatrixNxN::scale4x4() if (z == 1.0f) { QMatrix4x4 m4b(m3); m4b.scale(x, y); - QVERIFY(m4b == m4); + QCOMPARE(m4b, m4); } // Test coverage when the special matrix type is unknown. @@ -2138,7 +2138,7 @@ void tst_QMatrixNxN::translate4x4() if (z == 0.0f) { QMatrix4x4 m2b; m2b.translate(x, y); - QVERIFY(m2b == m2); + QCOMPARE(m2b, m2); } QVector3D v1(2.0f, 3.0f, -4.0f); @@ -2179,7 +2179,7 @@ void tst_QMatrixNxN::translate4x4() if (z == 0.0f) { QMatrix4x4 m4b(m3); m4b.translate(x, y); - QVERIFY(m4b == m4); + QCOMPARE(m4b, m4); } } @@ -3073,7 +3073,7 @@ void tst_QMatrixNxN::convertQMatrix() QPointF p2 = m2 * QPointF(100.0, 150.0); QCOMPARE((double)p2.x(), 100.0 - 3.5); QCOMPARE((double)p2.y(), 150.0 + 2.0); - QVERIFY(m1 == m2.toAffine()); + QCOMPARE(m1, m2.toAffine()); QMatrix m3; m3.scale(1.5, -2.0); @@ -3085,7 +3085,7 @@ void tst_QMatrixNxN::convertQMatrix() QPointF p4 = m4 * QPointF(100.0, 150.0); QCOMPARE((double)p4.x(), 1.5 * 100.0); QCOMPARE((double)p4.y(), -2.0 * 150.0); - QVERIFY(m3 == m4.toAffine()); + QCOMPARE(m3, m4.toAffine()); QMatrix m5; m5.rotate(45.0); @@ -3120,7 +3120,7 @@ void tst_QMatrixNxN::convertQTransform() QPointF p2 = m2 * QPointF(100.0, 150.0); QCOMPARE((double)p2.x(), 100.0 - 3.5); QCOMPARE((double)p2.y(), 150.0 + 2.0); - QVERIFY(m1 == m2.toTransform()); + QCOMPARE(m1, m2.toTransform()); QTransform m3; m3.scale(1.5, -2.0); @@ -3132,7 +3132,7 @@ void tst_QMatrixNxN::convertQTransform() QPointF p4 = m4 * QPointF(100.0, 150.0); QCOMPARE((double)p4.x(), 1.5 * 100.0); QCOMPARE((double)p4.y(), -2.0 * 150.0); - QVERIFY(m3 == m4.toTransform()); + QCOMPARE(m3, m4.toTransform()); QTransform m5; m5.rotate(45.0); @@ -3206,16 +3206,16 @@ void tst_QMatrixNxN::mapRect() QRect recti(qRound(x), qRound(y), qRound(width), qRound(height)); QMatrix4x4 m1; - QVERIFY(m1.mapRect(rect) == rect); - QVERIFY(m1.mapRect(recti) == recti); + QCOMPARE(m1.mapRect(rect), rect); + QCOMPARE(m1.mapRect(recti), recti); QMatrix4x4 m2; m2.translate(-100.5f, 64.0f); QRectF translated = rect.translated(-100.5f, 64.0f); QRect translatedi = QRect(qRound(recti.x() - 100.5f), recti.y() + 64, recti.width(), recti.height()); - QVERIFY(m2.mapRect(rect) == translated); - QVERIFY(m2.mapRect(recti) == translatedi); + QCOMPARE(m2.mapRect(rect), translated); + QCOMPARE(m2.mapRect(recti), translatedi); QMatrix4x4 m3; m3.scale(-100.5f, 64.0f); @@ -3232,7 +3232,7 @@ void tst_QMatrixNxN::mapRect() scaley -= scaleht; } QRectF scaled(scalex, scaley, scalewid, scaleht); - QVERIFY(m3.mapRect(rect) == scaled); + QCOMPARE(m3.mapRect(rect), scaled); scalex = recti.x() * -100.5f; scaley = recti.y() * 64.0f; scalewid = recti.width() * -100.5f; @@ -3247,7 +3247,7 @@ void tst_QMatrixNxN::mapRect() } QRect scaledi(qRound(scalex), qRound(scaley), qRound(scalewid), qRound(scaleht)); - QVERIFY(m3.mapRect(recti) == scaledi); + QCOMPARE(m3.mapRect(recti), scaledi); QMatrix4x4 m4; m4.translate(-100.5f, 64.0f); @@ -3261,7 +3261,7 @@ void tst_QMatrixNxN::mapRect() if (transy1 > transy2) qSwap(transy1, transy2); QRectF trans(transx1, transy1, transx2 - transx1, transy2 - transy1); - QVERIFY(m4.mapRect(rect) == trans); + QCOMPARE(m4.mapRect(rect), trans); transx1 = recti.x() * -2.5f - 100.5f; transy1 = recti.y() * 4.0f + 64.0f; transx2 = (recti.x() + recti.width()) * -2.5f - 100.5f; @@ -3273,7 +3273,7 @@ void tst_QMatrixNxN::mapRect() QRect transi(qRound(transx1), qRound(transy1), qRound(transx2) - qRound(transx1), qRound(transy2) - qRound(transy1)); - QVERIFY(m4.mapRect(recti) == transi); + QCOMPARE(m4.mapRect(recti), transi); m4.rotate(45.0f, 0.0f, 0.0f, 1.0f); @@ -3290,7 +3290,7 @@ void tst_QMatrixNxN::mapRect() QRect mri = m4.mapRect(recti); QRect tri = t4.mapRect(recti); - QVERIFY(mri == tri); + QCOMPARE(mri, tri); } void tst_QMatrixNxN::mapVector_data() @@ -3389,14 +3389,14 @@ void tst_QMatrixNxN::properties() void tst_QMatrixNxN::metaTypes() { - QVERIFY(QMetaType::type("QMatrix4x4") == QMetaType::QMatrix4x4); + QCOMPARE(QMetaType::type("QMatrix4x4"), int(QMetaType::QMatrix4x4)); QCOMPARE(QByteArray(QMetaType::typeName(QMetaType::QMatrix4x4)), QByteArray("QMatrix4x4")); QVERIFY(QMetaType::isRegistered(QMetaType::QMatrix4x4)); - QVERIFY(qMetaTypeId<QMatrix4x4>() == QMetaType::QMatrix4x4); + QCOMPARE(qMetaTypeId<QMatrix4x4>(), int(QMetaType::QMatrix4x4)); } QTEST_APPLESS_MAIN(tst_QMatrixNxN) diff --git a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp index ec7af97f07f417ecdb0171dd92f319270709325e..1fbad5b829e859610b952c19a344e19132552141 100644 --- a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp @@ -446,7 +446,7 @@ void tst_QQuaternion::compare() QQuaternion v5(8, 1, 2, 3); QQuaternion v6(3, 1, 2, 4); - QVERIFY(v1 == v2); + QCOMPARE(v1, v2); QVERIFY(v1 != v3); QVERIFY(v1 != v4); QVERIFY(v1 != v5); @@ -522,7 +522,7 @@ void tst_QQuaternion::add() QQuaternion v4(v1); v4 += v2; - QVERIFY(v4 == v3); + QCOMPARE(v4, v3); QCOMPARE(v4.x(), v1.x() + v2.x()); QCOMPARE(v4.y(), v1.y() + v2.y()); @@ -560,7 +560,7 @@ void tst_QQuaternion::subtract() QQuaternion v4(v3); v4 -= v1; - QVERIFY(v4 == v2); + QCOMPARE(v4, v2); QCOMPARE(v4.x(), v3.x() - v1.x()); QCOMPARE(v4.y(), v3.y() - v1.y()); @@ -569,7 +569,7 @@ void tst_QQuaternion::subtract() QQuaternion v5(v3); v5 -= v2; - QVERIFY(v5 == v1); + QCOMPARE(v5, v1); QCOMPARE(v5.x(), v3.x() - v2.x()); QCOMPARE(v5.y(), v3.y() - v2.y()); @@ -704,7 +704,7 @@ void tst_QQuaternion::multiplyFactor() QQuaternion v3(v1); v3 *= factor; - QVERIFY(v3 == v2); + QCOMPARE(v3, v2); QCOMPARE(v3.x(), v1.x() * factor); QCOMPARE(v3.y(), v1.y() * factor); @@ -740,7 +740,7 @@ void tst_QQuaternion::divide() QQuaternion v3(v2); v3 /= factor; - QVERIFY(v3 == v1); + QCOMPARE(v3, v1); QCOMPARE(v3.x(), v2.x() / factor); QCOMPARE(v3.y(), v2.y() / factor); @@ -764,7 +764,7 @@ void tst_QQuaternion::negate() QQuaternion v1(w1, x1, y1, z1); QQuaternion v2(-w1, -x1, -y1, -z1); - QVERIFY(-v1 == v2); + QCOMPARE(-v1, v2); } // Test quaternion conjugate calculations. @@ -783,7 +783,7 @@ void tst_QQuaternion::conjugate() QQuaternion v1(w1, x1, y1, z1); QQuaternion v2(w1, -x1, -y1, -z1); - QVERIFY(v1.conjugate() == v2); + QCOMPARE(v1.conjugate(), v2); } // Test quaternion creation from an axis and an angle. @@ -1325,14 +1325,14 @@ void tst_QQuaternion::properties() void tst_QQuaternion::metaTypes() { - QVERIFY(QMetaType::type("QQuaternion") == QMetaType::QQuaternion); + QCOMPARE(QMetaType::type("QQuaternion"), int(QMetaType::QQuaternion)); QCOMPARE(QByteArray(QMetaType::typeName(QMetaType::QQuaternion)), QByteArray("QQuaternion")); QVERIFY(QMetaType::isRegistered(QMetaType::QQuaternion)); - QVERIFY(qMetaTypeId<QQuaternion>() == QMetaType::QQuaternion); + QCOMPARE(qMetaTypeId<QQuaternion>(), int(QMetaType::QQuaternion)); } QTEST_APPLESS_MAIN(tst_QQuaternion) diff --git a/tests/auto/gui/math3d/qvectornd/tst_qvectornd.cpp b/tests/auto/gui/math3d/qvectornd/tst_qvectornd.cpp index d2e0bbe3750233f5cfd1dc003e4b81e529c4db40..eeff2c3bae96fc503a12bfe37c0aa07f0c7866c3 100644 --- a/tests/auto/gui/math3d/qvectornd/tst_qvectornd.cpp +++ b/tests/auto/gui/math3d/qvectornd/tst_qvectornd.cpp @@ -885,7 +885,7 @@ void tst_QVectorND::compare2() QVector2D v3(3, 2); QVector2D v4(1, 3); - QVERIFY(v1 == v2); + QCOMPARE(v1, v2); QVERIFY(v1 != v3); QVERIFY(v1 != v4); } @@ -899,7 +899,7 @@ void tst_QVectorND::compare3() QVector3D v4(1, 3, 4); QVector3D v5(1, 2, 3); - QVERIFY(v1 == v2); + QCOMPARE(v1, v2); QVERIFY(v1 != v3); QVERIFY(v1 != v4); QVERIFY(v1 != v5); @@ -915,7 +915,7 @@ void tst_QVectorND::compare4() QVector4D v5(1, 2, 3, 8); QVector4D v6(1, 2, 4, 3); - QVERIFY(v1 == v2); + QCOMPARE(v1, v2); QVERIFY(v1 != v3); QVERIFY(v1 != v4); QVERIFY(v1 != v5); @@ -969,7 +969,7 @@ void tst_QVectorND::add2() QVector2D v4(v1); v4 += v2; - QVERIFY(v4 == v3); + QCOMPARE(v4, v3); QCOMPARE(v4.x(), v1.x() + v2.x()); QCOMPARE(v4.y(), v1.y() + v2.y()); @@ -1033,7 +1033,7 @@ void tst_QVectorND::add3() QVector3D v4(v1); v4 += v2; - QVERIFY(v4 == v3); + QCOMPARE(v4, v3); QCOMPARE(v4.x(), v1.x() + v2.x()); QCOMPARE(v4.y(), v1.y() + v2.y()); @@ -1109,7 +1109,7 @@ void tst_QVectorND::add4() QVector4D v4(v1); v4 += v2; - QVERIFY(v4 == v3); + QCOMPARE(v4, v3); QCOMPARE(v4.x(), v1.x() + v2.x()); QCOMPARE(v4.y(), v1.y() + v2.y()); @@ -1141,14 +1141,14 @@ void tst_QVectorND::subtract2() QVector2D v4(v3); v4 -= v1; - QVERIFY(v4 == v2); + QCOMPARE(v4, v2); QCOMPARE(v4.x(), v3.x() - v1.x()); QCOMPARE(v4.y(), v3.y() - v1.y()); QVector2D v5(v3); v5 -= v2; - QVERIFY(v5 == v1); + QCOMPARE(v5, v1); QCOMPARE(v5.x(), v3.x() - v2.x()); QCOMPARE(v5.y(), v3.y() - v2.y()); @@ -1181,7 +1181,7 @@ void tst_QVectorND::subtract3() QVector3D v4(v3); v4 -= v1; - QVERIFY(v4 == v2); + QCOMPARE(v4, v2); QCOMPARE(v4.x(), v3.x() - v1.x()); QCOMPARE(v4.y(), v3.y() - v1.y()); @@ -1189,7 +1189,7 @@ void tst_QVectorND::subtract3() QVector3D v5(v3); v5 -= v2; - QVERIFY(v5 == v1); + QCOMPARE(v5, v1); QCOMPARE(v5.x(), v3.x() - v2.x()); QCOMPARE(v5.y(), v3.y() - v2.y()); @@ -1226,7 +1226,7 @@ void tst_QVectorND::subtract4() QVector4D v4(v3); v4 -= v1; - QVERIFY(v4 == v2); + QCOMPARE(v4, v2); QCOMPARE(v4.x(), v3.x() - v1.x()); QCOMPARE(v4.y(), v3.y() - v1.y()); @@ -1235,7 +1235,7 @@ void tst_QVectorND::subtract4() QVector4D v5(v3); v5 -= v2; - QVERIFY(v5 == v1); + QCOMPARE(v5, v1); QCOMPARE(v5.x(), v3.x() - v2.x()); QCOMPARE(v5.y(), v3.y() - v2.y()); @@ -1290,7 +1290,7 @@ void tst_QVectorND::multiply2() QVector2D v4(v1); v4 *= v2; - QVERIFY(v4 == v3); + QCOMPARE(v4, v3); QCOMPARE(v4.x(), v1.x() * v2.x()); QCOMPARE(v4.y(), v1.y() * v2.y()); @@ -1354,7 +1354,7 @@ void tst_QVectorND::multiply3() QVector3D v4(v1); v4 *= v2; - QVERIFY(v4 == v3); + QCOMPARE(v4, v3); QCOMPARE(v4.x(), v1.x() * v2.x()); QCOMPARE(v4.y(), v1.y() * v2.y()); @@ -1430,7 +1430,7 @@ void tst_QVectorND::multiply4() QVector4D v4(v1); v4 *= v2; - QVERIFY(v4 == v3); + QCOMPARE(v4, v3); QCOMPARE(v4.x(), v1.x() * v2.x()); QCOMPARE(v4.y(), v1.y() * v2.y()); @@ -1488,7 +1488,7 @@ void tst_QVectorND::multiplyFactor2() QVector2D v3(v1); v3 *= factor; - QVERIFY(v3 == v2); + QCOMPARE(v3, v2); QCOMPARE(v3.x(), v1.x() * factor); QCOMPARE(v3.y(), v1.y() * factor); @@ -1553,7 +1553,7 @@ void tst_QVectorND::multiplyFactor3() QVector3D v3(v1); v3 *= factor; - QVERIFY(v3 == v2); + QCOMPARE(v3, v2); QCOMPARE(v3.x(), v1.x() * factor); QCOMPARE(v3.y(), v1.y() * factor); @@ -1628,7 +1628,7 @@ void tst_QVectorND::multiplyFactor4() QVector4D v3(v1); v3 *= factor; - QVERIFY(v3 == v2); + QCOMPARE(v3, v2); QCOMPARE(v3.x(), v1.x() * factor); QCOMPARE(v3.y(), v1.y() * factor); @@ -1660,7 +1660,7 @@ void tst_QVectorND::divide2() QVector2D v4(v3); v4 /= v2; - QVERIFY(v4 == v1); + QCOMPARE(v4, v1); QCOMPARE(v4.x(), v3.x() / v2.x()); QCOMPARE(v4.y(), v3.y() / v2.y()); @@ -1670,7 +1670,7 @@ void tst_QVectorND::divide2() QVector2D v4(v3); v4 /= v1; - QVERIFY(v4 == v2); + QCOMPARE(v4, v2); QCOMPARE(v4.x(), v3.x() / v1.x()); QCOMPARE(v4.y(), v3.y() / v1.y()); @@ -1704,7 +1704,7 @@ void tst_QVectorND::divide3() QVector3D v4(v3); v4 /= v2; - QVERIFY(v4 == v1); + QCOMPARE(v4, v1); QCOMPARE(v4.x(), v3.x() / v2.x()); QCOMPARE(v4.y(), v3.y() / v2.y()); @@ -1715,7 +1715,7 @@ void tst_QVectorND::divide3() QVector3D v4(v3); v4 /= v1; - QVERIFY(v4 == v2); + QCOMPARE(v4, v2); QCOMPARE(v4.x(), v3.x() / v1.x()); QCOMPARE(v4.y(), v3.y() / v1.y()); @@ -1753,7 +1753,7 @@ void tst_QVectorND::divide4() QVector4D v4(v3); v4 /= v2; - QVERIFY(v4 == v1); + QCOMPARE(v4, v1); QCOMPARE(v4.x(), v3.x() / v2.x()); QCOMPARE(v4.y(), v3.y() / v2.y()); @@ -1765,7 +1765,7 @@ void tst_QVectorND::divide4() QVector4D v4(v3); v4 /= v1; - QVERIFY(v4 == v2); + QCOMPARE(v4, v2); QCOMPARE(v4.x(), v3.x() / v1.x()); QCOMPARE(v4.y(), v3.y() / v1.y()); @@ -1798,7 +1798,7 @@ void tst_QVectorND::divideFactor2() QVector2D v3(v2); v3 /= factor; - QVERIFY(v3 == v1); + QCOMPARE(v3, v1); QCOMPARE(v3.x(), v2.x() / factor); QCOMPARE(v3.y(), v2.y() / factor); @@ -1830,7 +1830,7 @@ void tst_QVectorND::divideFactor3() QVector3D v3(v2); v3 /= factor; - QVERIFY(v3 == v1); + QCOMPARE(v3, v1); QCOMPARE(v3.x(), v2.x() / factor); QCOMPARE(v3.y(), v2.y() / factor); @@ -1865,7 +1865,7 @@ void tst_QVectorND::divideFactor4() QVector4D v3(v2); v3 /= factor; - QVERIFY(v3 == v1); + QCOMPARE(v3, v1); QCOMPARE(v3.x(), v2.x() / factor); QCOMPARE(v3.y(), v2.y() / factor); @@ -1887,7 +1887,7 @@ void tst_QVectorND::negate2() QVector2D v1(x1, y1); QVector2D v2(-x1, -y1); - QVERIFY(-v1 == v2); + QCOMPARE(-v1, v2); } // Test vector negation for 3D vectors. @@ -1905,7 +1905,7 @@ void tst_QVectorND::negate3() QVector3D v1(x1, y1, z1); QVector3D v2(-x1, -y1, -z1); - QVERIFY(-v1 == v2); + QCOMPARE(-v1, v2); } // Test vector negation for 4D vectors. @@ -1924,7 +1924,7 @@ void tst_QVectorND::negate4() QVector4D v1(x1, y1, z1, w1); QVector4D v2(-x1, -y1, -z1, -w1); - QVERIFY(-v1 == v2); + QCOMPARE(-v1, v2); } // Test the computation of vector cross-products. @@ -1976,7 +1976,7 @@ void tst_QVectorND::crossProduct() QVector3D v3(x3, y3, z3); QVector3D v4 = QVector3D::crossProduct(v1, v2); - QVERIFY(v4 == v3); + QCOMPARE(v4, v3); // Compute the cross-product long-hand and check again. float xres = y1 * z2 - z1 * y2; @@ -2667,9 +2667,9 @@ void tst_QVectorND::properties() void tst_QVectorND::metaTypes() { - QVERIFY(QMetaType::type("QVector2D") == QMetaType::QVector2D); - QVERIFY(QMetaType::type("QVector3D") == QMetaType::QVector3D); - QVERIFY(QMetaType::type("QVector4D") == QMetaType::QVector4D); + QCOMPARE(QMetaType::type("QVector2D"), int(QMetaType::QVector2D)); + QCOMPARE(QMetaType::type("QVector3D"), int(QMetaType::QVector3D)); + QCOMPARE(QMetaType::type("QVector4D"), int(QMetaType::QVector4D)); QCOMPARE(QByteArray(QMetaType::typeName(QMetaType::QVector2D)), QByteArray("QVector2D")); @@ -2682,9 +2682,9 @@ void tst_QVectorND::metaTypes() QVERIFY(QMetaType::isRegistered(QMetaType::QVector3D)); QVERIFY(QMetaType::isRegistered(QMetaType::QVector4D)); - QVERIFY(qMetaTypeId<QVector2D>() == QMetaType::QVector2D); - QVERIFY(qMetaTypeId<QVector3D>() == QMetaType::QVector3D); - QVERIFY(qMetaTypeId<QVector4D>() == QMetaType::QVector4D); + QCOMPARE(qMetaTypeId<QVector2D>(), int(QMetaType::QVector2D)); + QCOMPARE(qMetaTypeId<QVector3D>(), int(QMetaType::QVector3D)); + QCOMPARE(qMetaTypeId<QVector4D>(), int(QMetaType::QVector4D)); } QTEST_APPLESS_MAIN(tst_QVectorND) diff --git a/tests/auto/gui/painting/qbrush/tst_qbrush.cpp b/tests/auto/gui/painting/qbrush/tst_qbrush.cpp index 4f58178f2cd3670645e067778cd1bbcd0293a6a6..30982f1e24b21bb3a09f86ab1239b2fce91f03c6 100644 --- a/tests/auto/gui/painting/qbrush/tst_qbrush.cpp +++ b/tests/auto/gui/painting/qbrush/tst_qbrush.cpp @@ -461,8 +461,8 @@ void tst_QBrush::textureBrushComparison() imageBrush1.setTextureImage(image1); imageBrush2.setTextureImage(image2); - QVERIFY(imageBrush1 == imageBrush2); - QVERIFY(pixmapBrush == imageBrush1); + QCOMPARE(imageBrush1, imageBrush2); + QCOMPARE(pixmapBrush, imageBrush1); } QTEST_MAIN(tst_QBrush) diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp index cf0d82f3f7f2463b731362b9335c034f47ee87dc..b9d17bae621cb3ce1426e0f3ad46f15257277f49 100644 --- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp +++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp @@ -253,7 +253,7 @@ void tst_QColor::isValid() { QFETCH(QColor, color); QFETCH(bool, isValid); - QVERIFY(color.isValid() == isValid); + QCOMPARE(color.isValid(), isValid); } Q_DECLARE_METATYPE(QColor::NameFormat); @@ -1325,19 +1325,19 @@ void tst_QColor::convertTo() QColor color(Qt::black); QColor rgb = color.convertTo(QColor::Rgb); - QVERIFY(rgb.spec() == QColor::Rgb); + QCOMPARE(rgb.spec(), QColor::Rgb); QColor hsv = color.convertTo(QColor::Hsv); - QVERIFY(hsv.spec() == QColor::Hsv); + QCOMPARE(hsv.spec(), QColor::Hsv); QColor cmyk = color.convertTo(QColor::Cmyk); - QVERIFY(cmyk.spec() == QColor::Cmyk); + QCOMPARE(cmyk.spec(), QColor::Cmyk); QColor hsl = color.convertTo(QColor::Hsl); - QVERIFY(hsl.spec() == QColor::Hsl); + QCOMPARE(hsl.spec(), QColor::Hsl); QColor invalid = color.convertTo(QColor::Invalid); - QVERIFY(invalid.spec() == QColor::Invalid); + QCOMPARE(invalid.spec(), QColor::Invalid); } void tst_QColor::light() diff --git a/tests/auto/gui/painting/qpagelayout/tst_qpagelayout.cpp b/tests/auto/gui/painting/qpagelayout/tst_qpagelayout.cpp index 964487f5663a75aac2dce856ef385bc045f660dc..0f2f51d9b62745665a146c3e9a4c71db3e67e668 100644 --- a/tests/auto/gui/painting/qpagelayout/tst_qpagelayout.cpp +++ b/tests/auto/gui/painting/qpagelayout/tst_qpagelayout.cpp @@ -76,7 +76,7 @@ void tst_QPageLayout::basics() QCOMPARE(simple.paintRectPixels(72), QRect(0, 0, 595, 842)); const QPageLayout a4portrait = simple; - QVERIFY(a4portrait == simple); + QCOMPARE(a4portrait, simple); // Change orientation simple.setOrientation(QPageLayout::Landscape); diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index e13a6b026d728230e5aea6c31d9dff6be26e1d24..3e98e630c226fd8e292e93d844fe7b5a2d0c1d22 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -799,7 +799,7 @@ void tst_QPainter::drawPixmapFragments() QImage origImage = origPixmap.toImage().convertToFormat(QImage::Format_ARGB32); QImage resImage = resPixmap.toImage().convertToFormat(QImage::Format_ARGB32); - QVERIFY(resImage.size() == resPixmap.size()); + QCOMPARE(resImage.size(), resPixmap.size()); QVERIFY(resImage.pixel(5, 5) == origImage.pixel(15, 15)); QVERIFY(resImage.pixel(5, 15) == origImage.pixel(15, 5)); QVERIFY(resImage.pixel(15, 5) == origImage.pixel(5, 15)); @@ -807,16 +807,16 @@ void tst_QPainter::drawPixmapFragments() QPainter::PixmapFragment fragment = QPainter::PixmapFragment::create(QPointF(20, 20), QRectF(30, 30, 2, 2)); - QVERIFY(fragment.x == 20); - QVERIFY(fragment.y == 20); - QVERIFY(fragment.sourceLeft == 30); - QVERIFY(fragment.sourceTop == 30); - QVERIFY(fragment.width == 2); - QVERIFY(fragment.height == 2); - QVERIFY(fragment.scaleX == 1); - QVERIFY(fragment.scaleY == 1); - QVERIFY(fragment.rotation == 0); - QVERIFY(fragment.opacity == 1); + QCOMPARE(fragment.x, qreal(20)); + QCOMPARE(fragment.y, qreal(20)); + QCOMPARE(fragment.sourceLeft, qreal(30)); + QCOMPARE(fragment.sourceTop, qreal(30)); + QCOMPARE(fragment.width, qreal(2)); + QCOMPARE(fragment.height, qreal(2)); + QCOMPARE(fragment.scaleX, qreal(1)); + QCOMPARE(fragment.scaleY, qreal(1)); + QCOMPARE(fragment.rotation, qreal(0)); + QCOMPARE(fragment.opacity, qreal(1)); } void tst_QPainter::drawPixmapNegativeScale() @@ -1481,7 +1481,7 @@ void tst_QPainter::drawPath3() p.drawPath(path); p.end(); - QVERIFY(imgA == imgB); + QCOMPARE(imgA, imgB); imgA.invertPixels(); imgB.fill(0xffffff); @@ -1495,7 +1495,7 @@ void tst_QPainter::drawPath3() p.drawPath(path); p.end(); - QVERIFY(imgA == imgB); + QCOMPARE(imgA, imgB); path.setFillRule(Qt::WindingFill); imgB.fill(0xffffff); @@ -4877,17 +4877,17 @@ void tst_QPainter::blendARGBonRGB_data() QTest::newRow("ARGB_PM source-in RGB666") << QImage::Format_RGB666 << QImage::Format_ARGB32_Premultiplied << QPainter::CompositionMode_SourceIn << qRgba(127, 0, 0, 127) << 125; QTest::newRow("ARGB over RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32 - << QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 127) << 127; + << QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 85) << 85; QTest::newRow("ARGB_PM over RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied - << QPainter::CompositionMode_SourceOver << qRgba(127, 0, 0, 127) << 127; + << QPainter::CompositionMode_SourceOver << qRgba(85, 0, 0, 85) << 85; QTest::newRow("ARGB source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32 - << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 127) << 127; + << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 85) << 85; QTest::newRow("ARGB_PM source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied - << QPainter::CompositionMode_Source << qRgba(127, 0, 0, 127) << 127; + << QPainter::CompositionMode_Source << qRgba(85, 0, 0, 85) << 85; QTest::newRow("ARGB source-in RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32 - << QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 127) << 127; + << QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 85) << 85; QTest::newRow("ARGB_PM source-in RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied - << QPainter::CompositionMode_SourceIn << qRgba(127, 0, 0, 127) << 127; + << QPainter::CompositionMode_SourceIn << qRgba(85, 0, 0, 85) << 85; } void tst_QPainter::blendARGBonRGB() diff --git a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp index 0a073f5c8428eb2e64ec71f2944cedb3e6eb7e49..ae30719ee764e8c3f56ae4cf76cf5488fa6ff510 100644 --- a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp +++ b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp @@ -602,16 +602,16 @@ void tst_QPainterPath::testOperatorEquals() { QPainterPath empty1; QPainterPath empty2; - QVERIFY(empty1 == empty2); + QCOMPARE(empty1, empty2); QPainterPath rect1; rect1.addRect(100, 100, 100, 100); - QVERIFY(rect1 == rect1); + QCOMPARE(rect1, rect1); QVERIFY(rect1 != empty1); QPainterPath rect2; rect2.addRect(100, 100, 100, 100); - QVERIFY(rect1 == rect2); + QCOMPARE(rect1, rect2); rect2.setFillRule(Qt::WindingFill); QVERIFY(rect1 != rect2); @@ -622,7 +622,7 @@ void tst_QPainterPath::testOperatorEquals() QPainterPath ellipse2; ellipse2.addEllipse(50, 50, 100, 100); - QVERIFY(ellipse1 == ellipse2); + QCOMPARE(ellipse1, ellipse2); } void tst_QPainterPath::testOperatorEquals_fuzzy() @@ -638,12 +638,12 @@ void tst_QPainterPath::testOperatorEquals_fuzzy() QPainterPath pb; pb.addRect(b); - QVERIFY(pa == pb); + QCOMPARE(pa, pb); QTransform transform; transform.translate(-100, -100); - QVERIFY(transform.map(pa) == transform.map(pb)); + QCOMPARE(transform.map(pa), transform.map(pb)); } // higher tolerance for error when path's bounding rect is big @@ -656,12 +656,12 @@ void tst_QPainterPath::testOperatorEquals_fuzzy() QPainterPath pb; pb.addRect(b); - QVERIFY(pa == pb); + QCOMPARE(pa, pb); QTransform transform; transform.translate(-1, -1); - QVERIFY(transform.map(pa) == transform.map(pb)); + QCOMPARE(transform.map(pa), transform.map(pb)); } // operator== should return true for a path that has @@ -676,7 +676,7 @@ void tst_QPainterPath::testOperatorEquals_fuzzy() QPainterPath b = transform.inverted().map(transform.map(a)); - QVERIFY(a == b); + QCOMPARE(a, b); } { @@ -720,7 +720,7 @@ void tst_QPainterPath::testOperatorDatastream() stream >> other; } - QVERIFY(other == path); + QCOMPARE(other, path); } void tst_QPainterPath::closing() @@ -1066,19 +1066,19 @@ void tst_QPainterPath::setElementPositionAt() { QPainterPath path(QPointF(42., 42.)); QCOMPARE(path.elementCount(), 1); - QVERIFY(path.elementAt(0).type == QPainterPath::MoveToElement); + QCOMPARE(path.elementAt(0).type, QPainterPath::MoveToElement); QCOMPARE(path.elementAt(0).x, qreal(42.)); QCOMPARE(path.elementAt(0).y, qreal(42.)); QPainterPath copy = path; copy.setElementPositionAt(0, qreal(0), qreal(0)); QCOMPARE(copy.elementCount(), 1); - QVERIFY(copy.elementAt(0).type == QPainterPath::MoveToElement); + QCOMPARE(copy.elementAt(0).type, QPainterPath::MoveToElement); QCOMPARE(copy.elementAt(0).x, qreal(0)); QCOMPARE(copy.elementAt(0).y, qreal(0)); QCOMPARE(path.elementCount(), 1); - QVERIFY(path.elementAt(0).type == QPainterPath::MoveToElement); + QCOMPARE(path.elementAt(0).type, QPainterPath::MoveToElement); QCOMPARE(path.elementAt(0).x, qreal(42.)); QCOMPARE(path.elementAt(0).y, qreal(42.)); } @@ -1253,10 +1253,10 @@ void tst_QPainterPath::connectPathMoveTo() path1.connectPath(path2); - QVERIFY(path1.elementAt(0).type == QPainterPath::MoveToElement); - QVERIFY(path2.elementAt(0).type == QPainterPath::MoveToElement); - QVERIFY(path3.elementAt(0).type == QPainterPath::MoveToElement); - QVERIFY(path4.elementAt(0).type == QPainterPath::MoveToElement); + QCOMPARE(path1.elementAt(0).type, QPainterPath::MoveToElement); + QCOMPARE(path2.elementAt(0).type, QPainterPath::MoveToElement); + QCOMPARE(path3.elementAt(0).type, QPainterPath::MoveToElement); + QCOMPARE(path4.elementAt(0).type, QPainterPath::MoveToElement); } void tst_QPainterPath::translate() diff --git a/tests/auto/gui/painting/qregion/tst_qregion.cpp b/tests/auto/gui/painting/qregion/tst_qregion.cpp index c0e3c6d18745ce992fc9d4495dab3ea341e94975..33f81cc10e859071c3dc838d1bab76539a87fba3 100644 --- a/tests/auto/gui/painting/qregion/tst_qregion.cpp +++ b/tests/auto/gui/painting/qregion/tst_qregion.cpp @@ -173,7 +173,7 @@ void tst_QRegion::setRects() QRect rect; region.setRects(&rect, 0); QVERIFY(region.isEmpty()); - QVERIFY(region == QRegion()); + QCOMPARE(region, QRegion()); QVERIFY(!region.boundingRect().isValid()); QVERIFY(region.rects().isEmpty()); } diff --git a/tests/auto/gui/painting/qtransform/tst_qtransform.cpp b/tests/auto/gui/painting/qtransform/tst_qtransform.cpp index 1327cff1bd0ba2e2436b50169458c0d04df43e39..60b89aa6ab3173ddf5767c4a3672a72c0b9c4c1c 100644 --- a/tests/auto/gui/painting/qtransform/tst_qtransform.cpp +++ b/tests/auto/gui/painting/qtransform/tst_qtransform.cpp @@ -428,14 +428,14 @@ void tst_QTransform::matrix() mat1.m21(), mat1.m22(), 0, mat1.dx(), mat1.dy(), 1); - QVERIFY(tran1 == dummy); - QVERIFY(tran1.inverted() == dummy.inverted()); - QVERIFY(tran1.inverted() == QTransform(mat1.inverted())); - QVERIFY(tran2.inverted() == QTransform(mat2.inverted())); + QCOMPARE(tran1, dummy); + QCOMPARE(tran1.inverted(), dummy.inverted()); + QCOMPARE(tran1.inverted(), QTransform(mat1.inverted())); + QCOMPARE(tran2.inverted(), QTransform(mat2.inverted())); QMatrix mat3 = mat1 * mat2; QTransform tran3 = tran1 * tran2; - QVERIFY(QTransform(mat3) == tran3); + QCOMPARE(QTransform(mat3), tran3); /* QMatrix::operator==() doesn't use qFuzzyCompare(), which * on win32-g++ results in a failure. So we work around it by @@ -447,15 +447,15 @@ void tst_QTransform::matrix() QRect rect(43, 70, 200, 200); QPoint pt(43, 66); - QVERIFY(tranInv.map(pt) == matInv.map(pt)); - QVERIFY(tranInv.map(pt) == matInv.map(pt)); + QCOMPARE(tranInv.map(pt), matInv.map(pt)); + QCOMPARE(tranInv.map(pt), matInv.map(pt)); QPainterPath path; path.moveTo(55, 60); path.lineTo(110, 110); path.quadTo(220, 50, 10, 20); path.closeSubpath(); - QVERIFY(tranInv.map(path) == matInv.map(path)); + QCOMPARE(tranInv.map(path), matInv.map(path)); } void tst_QTransform::testOffset() @@ -741,8 +741,8 @@ void tst_QTransform::inverted() const QTransform inverted = matrix.inverted(); - QVERIFY(matrix.isIdentity() == inverted.isIdentity()); - QVERIFY(matrix.type() == inverted.type()); + QCOMPARE(matrix.isIdentity(), inverted.isIdentity()); + QCOMPARE(matrix.type(), inverted.type()); QVERIFY((matrix * inverted).isIdentity()); QVERIFY((inverted * matrix).isIdentity()); diff --git a/tests/auto/gui/qopengl/BLACKLIST b/tests/auto/gui/qopengl/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..7f167d81df015c776d6499f345b54e0a7c096cd4 --- /dev/null +++ b/tests/auto/gui/qopengl/BLACKLIST @@ -0,0 +1,8 @@ +[fboRendering] +windows +[QTBUG15621_triangulatingStrokerDivZero] +windows +[imageFormatPainting] +windows +[openGLPaintDevice] +windows diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp index 8c6c28b4924fffce80ec9e52675067e6c85fa89b..8103f2791110282f512ccfd2ec794046becf60e7 100644 --- a/tests/auto/gui/qopengl/tst_qopengl.cpp +++ b/tests/auto/gui/qopengl/tst_qopengl.cpp @@ -86,6 +86,8 @@ private slots: void fboRenderingRGB30_data(); void fboRenderingRGB30(); void fboHandleNulledAfterContextDestroyed(); + void fboMRT(); + void fboMRT_differentFormats(); void openGLPaintDevice_data(); void openGLPaintDevice(); void aboutToBeDestroyed(); @@ -514,7 +516,7 @@ void tst_QOpenGL::fboTextureOwnership() // pull out the texture GLuint texture = fbo->takeTexture(); QVERIFY(texture != 0); - QVERIFY(fbo->texture() == 0); + QCOMPARE(fbo->texture(), GLuint(0)); // verify that the next bind() creates a new texture fbo->bind(); @@ -594,6 +596,14 @@ void tst_QOpenGL::fboRenderingRGB30_data() common_data(); } +#ifndef GL_RGB5_A1 +#define GL_RGB5_A1 0x8057 +#endif + +#ifndef GL_RGBA8 +#define GL_RGBA8 0x8058 +#endif + #ifndef GL_RGB10_A2 #define GL_RGB10_A2 0x8059 #endif @@ -606,6 +616,24 @@ void tst_QOpenGL::fboRenderingRGB30_data() #define GL_FULL_SUPPORT 0x82B7 #endif +static bool hasRGB10A2(QOpenGLContext *ctx) +{ + if (ctx->format().majorVersion() < 3) + return false; +#ifndef QT_OPENGL_ES_2 + if (!ctx->isOpenGLES() && ctx->format().majorVersion() >= 4) { + GLint value = -1; + QOpenGLFunctions_4_2_Core* vFuncs = ctx->versionFunctions<QOpenGLFunctions_4_2_Core>(); + if (vFuncs && vFuncs->initializeOpenGLFunctions()) { + vFuncs->glGetInternalformativ(GL_TEXTURE_2D, GL_RGB10_A2, GL_FRAMEBUFFER_RENDERABLE, 1, &value); + if (value != GL_FULL_SUPPORT) + return false; + } + } +#endif + return true; +} + void tst_QOpenGL::fboRenderingRGB30() { #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(__x86_64__) @@ -623,24 +651,9 @@ void tst_QOpenGL::fboRenderingRGB30() if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) QSKIP("QOpenGLFramebufferObject not supported on this platform"); - if (ctx.format().majorVersion() < 3) + if (!hasRGB10A2(&ctx)) QSKIP("An internal RGB30_A2 format is not guaranteed on this platform"); -#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2) - // NVidia currently only supports RGB30 and RGB30_A2 in their Quadro drivers, - // but they do provide an extension for querying the support. We use the query - // in case they implement the required formats later. - if (!ctx.isOpenGLES() && ctx.format().majorVersion() >= 4) { - GLint value = -1; - QOpenGLFunctions_4_2_Core* vFuncs = ctx.versionFunctions<QOpenGLFunctions_4_2_Core>(); - if (vFuncs && vFuncs->initializeOpenGLFunctions()) { - vFuncs->glGetInternalformativ(GL_TEXTURE_2D, GL_RGB10_A2, GL_FRAMEBUFFER_RENDERABLE, 1, &value); - if (value != GL_FULL_SUPPORT) - QSKIP("The required RGB30_A2 format is not supported by this driver"); - } - } -#endif - // No multisample with combined depth/stencil attachment: QOpenGLFramebufferObjectFormat fboFormat; fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); @@ -720,6 +733,150 @@ void tst_QOpenGL::fboHandleNulledAfterContextDestroyed() QCOMPARE(fbo->handle(), 0U); } +void tst_QOpenGL::fboMRT() +{ + QWindow window; + window.setSurfaceType(QWindow::OpenGLSurface); + window.setGeometry(0, 0, 10, 10); + window.create(); + + QOpenGLContext ctx; + QVERIFY(ctx.create()); + ctx.makeCurrent(&window); + + if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) + QSKIP("QOpenGLFramebufferObject not supported on this platform"); + + if (!ctx.functions()->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) + QSKIP("Multiple render targets not supported on this platform"); + + QOpenGLExtraFunctions *ef = ctx.extraFunctions(); + + { + // 3 color attachments, different sizes, same internal format, no depth/stencil. + QVector<QSize> sizes; + sizes << QSize(128, 128) << QSize(192, 128) << QSize(432, 123); + QOpenGLFramebufferObject fbo(sizes[0]); + fbo.addColorAttachment(sizes[1]); + fbo.addColorAttachment(sizes[2]); + QVERIFY(fbo.bind()); + QCOMPARE(fbo.attachment(), QOpenGLFramebufferObject::NoAttachment); + QCOMPARE(sizes, fbo.sizes()); + QCOMPARE(sizes[0], fbo.size()); + // Clear the three buffers to red, green and blue. + GLenum drawBuf = GL_COLOR_ATTACHMENT0; + ef->glDrawBuffers(1, &drawBuf); + ef->glClearColor(1, 0, 0, 1); + ef->glClear(GL_COLOR_BUFFER_BIT); + drawBuf = GL_COLOR_ATTACHMENT0 + 1; + ef->glDrawBuffers(1, &drawBuf); + ef->glClearColor(0, 1, 0, 1); + ef->glClear(GL_COLOR_BUFFER_BIT); + drawBuf = GL_COLOR_ATTACHMENT0 + 2; + ef->glDrawBuffers(1, &drawBuf); + ef->glClearColor(0, 0, 1, 1); + ef->glClear(GL_COLOR_BUFFER_BIT); + // Verify, keeping in mind that only a 128x123 area is touched in the buffers. + // Some drivers do not get this right, unfortunately, so do not rely on it. + const char *vendor = (const char *) ef->glGetString(GL_VENDOR); + bool hasCorrectMRT = false; + if (vendor && strstr(vendor, "NVIDIA")) // maybe others too + hasCorrectMRT = true; + QImage img = fbo.toImage(false, 0); + QCOMPARE(img.size(), sizes[0]); + QCOMPARE(img.pixel(0, 0), qRgb(255, 0, 0)); + if (hasCorrectMRT) + QCOMPARE(img.pixel(127, 122), qRgb(255, 0, 0)); + img = fbo.toImage(false, 1); + QCOMPARE(img.size(), sizes[1]); + QCOMPARE(img.pixel(0, 0), qRgb(0, 255, 0)); + if (hasCorrectMRT) + QCOMPARE(img.pixel(127, 122), qRgb(0, 255, 0)); + img = fbo.toImage(false, 2); + QCOMPARE(img.size(), sizes[2]); + QCOMPARE(img.pixel(0, 0), qRgb(0, 0, 255)); + if (hasCorrectMRT) + QCOMPARE(img.pixel(127, 122), qRgb(0, 0, 255)); + fbo.release(); + } + + { + // 2 color attachments, same size, same internal format, depth/stencil. + QVector<QSize> sizes; + sizes.fill(QSize(128, 128), 2); + QOpenGLFramebufferObject fbo(sizes[0], QOpenGLFramebufferObject::CombinedDepthStencil); + fbo.addColorAttachment(sizes[1]); + QVERIFY(fbo.bind()); + QCOMPARE(fbo.attachment(), QOpenGLFramebufferObject::CombinedDepthStencil); + QCOMPARE(sizes, fbo.sizes()); + QCOMPARE(sizes[0], fbo.size()); + ef->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + ef->glFinish(); + fbo.release(); + } +} + +void tst_QOpenGL::fboMRT_differentFormats() +{ + QWindow window; + window.setSurfaceType(QWindow::OpenGLSurface); + window.setGeometry(0, 0, 10, 10); + window.create(); + + QOpenGLContext ctx; + QVERIFY(ctx.create()); + ctx.makeCurrent(&window); + + QOpenGLFunctions *f = ctx.functions(); + const char * vendor = (const char *) f->glGetString(GL_VENDOR); + if (vendor && strstr(vendor, "VMware, Inc.")) + QSKIP("The tested formats may not be supported on this platform"); + + if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) + QSKIP("QOpenGLFramebufferObject not supported on this platform"); + + if (!f->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) + QSKIP("Multiple render targets not supported on this platform"); + + if (!hasRGB10A2(&ctx)) + QSKIP("RGB10_A2 not supported on this platform"); + + // 3 color attachments, same size, different internal format, depth/stencil. + QVector<QSize> sizes; + sizes.fill(QSize(128, 128), 3); + QOpenGLFramebufferObjectFormat format; + format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + QVector<GLenum> internalFormats; + internalFormats << GL_RGBA8 << GL_RGB10_A2 << GL_RGB5_A1; + format.setInternalTextureFormat(internalFormats[0]); + QOpenGLFramebufferObject fbo(sizes[0], format); + fbo.addColorAttachment(sizes[1], internalFormats[1]); + fbo.addColorAttachment(sizes[2], internalFormats[2]); + + QVERIFY(fbo.bind()); + QCOMPARE(fbo.attachment(), QOpenGLFramebufferObject::CombinedDepthStencil); + QCOMPARE(sizes, fbo.sizes()); + QCOMPARE(sizes[0], fbo.size()); + + QOpenGLExtraFunctions *ef = ctx.extraFunctions(); + QVERIFY(ef->glGetError() == 0); + ef->glClearColor(1, 0, 0, 1); + GLenum drawBuf[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0 + 1, GL_COLOR_ATTACHMENT0 + 2 }; + ef->glDrawBuffers(3, drawBuf); + ef->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + QVERIFY(ef->glGetError() == 0); + + QImage img = fbo.toImage(true, 0); + QCOMPARE(img.size(), sizes[0]); + QCOMPARE(img.pixel(0, 0), qRgb(255, 0, 0)); + img = fbo.toImage(true, 1); + QCOMPARE(img.size(), sizes[1]); + QCOMPARE(img.format(), QImage::Format_A2BGR30_Premultiplied); + QCOMPARE(img.pixel(0, 0), qRgb(255, 0, 0)); + + fbo.release(); +} + void tst_QOpenGL::imageFormatPainting() { QScopedPointer<QSurface> surface(createSurface(QSurface::Window)); @@ -1174,18 +1331,18 @@ void tst_QOpenGL::textureblitterPartTargetRectTransform() void tst_QOpenGL::defaultSurfaceFormat() { QSurfaceFormat fmt; - QVERIFY(QSurfaceFormat::defaultFormat() == fmt); + QCOMPARE(QSurfaceFormat::defaultFormat(), fmt); fmt.setDepthBufferSize(16); QSurfaceFormat::setDefaultFormat(fmt); - QVERIFY(QSurfaceFormat::defaultFormat() == fmt); + QCOMPARE(QSurfaceFormat::defaultFormat(), fmt); QCOMPARE(QSurfaceFormat::defaultFormat().depthBufferSize(), 16); QScopedPointer<QWindow> window(new QWindow); - QVERIFY(window->requestedFormat() == fmt); + QCOMPARE(window->requestedFormat(), fmt); QScopedPointer<QOpenGLContext> context(new QOpenGLContext); - QVERIFY(context->format() == fmt); + QCOMPARE(context->format(), fmt); } #ifdef USE_GLX @@ -1214,7 +1371,7 @@ void tst_QOpenGL::glxContextWrap() QOpenGLContext *ctx = new QOpenGLContext; ctx->setNativeHandle(QVariant::fromValue<QGLXNativeContext>(QGLXNativeContext(context))); QVERIFY(ctx->create()); - QVERIFY(ctx->nativeHandle().value<QGLXNativeContext>().context() == context); + QCOMPARE(ctx->nativeHandle().value<QGLXNativeContext>().context(), context); QVERIFY(nativeIf->nativeResourceForContext(QByteArrayLiteral("glxcontext"), ctx) == (void *) context); QVERIFY(ctx->makeCurrent(window)); diff --git a/tests/auto/gui/qopenglconfig/buglist.json b/tests/auto/gui/qopenglconfig/buglist.json index c7b8e61bc8a8fbc878edbfc0e43c93c8c853772f..ef311612b2588fc77df26abf3ddc9a65ab352b04 100644 --- a/tests/auto/gui/qopenglconfig/buglist.json +++ b/tests/auto/gui/qopenglconfig/buglist.json @@ -102,6 +102,28 @@ "feature1" ] }, + { + "id": 7, + "description": "driver description test", + "driver_description": "Long And Special Driver Description", + "os": { + "type": "win" + }, + "features": [ + "feature2" + ] + }, + { + "id": 8, + "description": "Windows version test", + "os": { + "type": "win", + "release": [ "10" ] + }, + "features": [ + "win10_feature" + ] + }, { "id": 128, "description": "check for matching GL_VENDOR", diff --git a/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp b/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp index f88cbdc7581c7067661b8048ced500c2d5ea7abd..3bf59910f3b51a064a371cfa520bc740d804c524 100644 --- a/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp +++ b/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp @@ -243,25 +243,43 @@ void tst_QOpenGlConfig::testBugList() QSet<QString> expectedFeatures; expectedFeatures << "feature1"; + // adapter info QVersionNumber driverVersion(QVector<int>() << 9 << 18 << 13 << 4460); - QOpenGLConfig::Gpu gpu = QOpenGLConfig::Gpu::fromDevice(0x10DE, 0x0DE9, driverVersion); + QOpenGLConfig::Gpu gpu = QOpenGLConfig::Gpu::fromDevice(0x10DE, 0x0DE9, driverVersion, QByteArrayLiteral("Unknown")); QSet<QString> actualFeatures = QOpenGLConfig::gpuFeatures(gpu, QStringLiteral("win"), - QVersionNumber(6, 3), fileName); + QVersionNumber(6, 3), QStringLiteral("7"), fileName); QVERIFY2(expectedFeatures == actualFeatures, msgSetMismatch(expectedFeatures, actualFeatures)); + // driver_description + gpu = QOpenGLConfig::Gpu::fromDevice(0xDEAD, 0xBEEF, driverVersion, QByteArrayLiteral("Very Long And Special Driver Description")); + actualFeatures = QOpenGLConfig::gpuFeatures(gpu, QStringLiteral("win"), + QVersionNumber(6, 3), QStringLiteral("8"), fileName); + expectedFeatures = QSet<QString>() << "feature2"; + QVERIFY2(expectedFeatures == actualFeatures, + msgSetMismatch(expectedFeatures, actualFeatures)); + + // os.release + gpu = QOpenGLConfig::Gpu::fromDevice(0xDEAD, 0xBEEF, driverVersion, QByteArrayLiteral("WinVerTest")); + actualFeatures = QOpenGLConfig::gpuFeatures(gpu, QStringLiteral("win"), + QVersionNumber(12, 34), QStringLiteral("10"), fileName); + expectedFeatures = QSet<QString>() << "win10_feature"; + QVERIFY2(expectedFeatures == actualFeatures, + msgSetMismatch(expectedFeatures, actualFeatures)); + + // gl_vendor gpu = QOpenGLConfig::Gpu::fromGLVendor(QByteArrayLiteral("Somebody Else")); expectedFeatures.clear(); actualFeatures = QOpenGLConfig::gpuFeatures(gpu, QStringLiteral("linux"), - QVersionNumber(1, 0), fileName); + QVersionNumber(1, 0), QString(), fileName); QVERIFY2(expectedFeatures == actualFeatures, msgSetMismatch(expectedFeatures, actualFeatures)); gpu = QOpenGLConfig::Gpu::fromGLVendor(QByteArrayLiteral("The Qt Company")); expectedFeatures = QSet<QString>() << "cool_feature"; actualFeatures = QOpenGLConfig::gpuFeatures(gpu, QStringLiteral("linux"), - QVersionNumber(1, 0), fileName); + QVersionNumber(1, 0), QString(), fileName); QVERIFY2(expectedFeatures == actualFeatures, msgSetMismatch(expectedFeatures, actualFeatures)); } diff --git a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp index 5d78bc1d0110da042f2912cc37da61b7a6cf2063..b1beb0ffd04822d1a111a69789316ab22fd5a0bf 100644 --- a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp +++ b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp @@ -203,8 +203,8 @@ void tst_QCssParser::scanner() QCss::Scanner::scan(QCss::Scanner::preprocess(QString::fromUtf8(inputFile.readAll())), &symbols); QVERIFY(symbols.count() > 1); - QVERIFY(symbols.last().token == QCss::S); - QVERIFY(symbols.last().lexem() == QLatin1String("\n")); + QCOMPARE(symbols.last().token, QCss::S); + QCOMPARE(symbols.last().lexem(), QLatin1String("\n")); symbols.remove(symbols.count() - 1, 1); QFile outputFile(output); @@ -861,7 +861,7 @@ void tst_QCssParser::colorValue() QCss::Declaration decl; QVERIFY(parser.parseNextDeclaration(&decl)); const QColor col = decl.colorValue(); - QVERIFY(expectedColor.isValid() == col.isValid()); + QCOMPARE(expectedColor.isValid(), col.isValid()); QCOMPARE(col, expectedColor); } @@ -1304,7 +1304,7 @@ void tst_QCssParser::rulesForNode() decls += rules.at(i).declarations; } - QVERIFY(decls.count() == declCount); + QCOMPARE(decls.count(), declCount); if (declCount > 0) QCOMPARE(decls.at(0).d->values.at(0).variant.toString(), value0); @@ -1364,7 +1364,7 @@ void tst_QCssParser::shorthandBackgroundProperty() v.extractBackground(&brush, &image, &repeat, &alignment, &origin, &attachment, &ignoredOrigin); QFETCH(QBrush, expectedBrush); - QVERIFY(expectedBrush.color() == brush.color()); + QCOMPARE(expectedBrush.color(), brush.color()); QTEST(image, "expectedImage"); QTEST(int(repeat), "expectedRepeatValue"); @@ -1372,7 +1372,7 @@ void tst_QCssParser::shorthandBackgroundProperty() //QTBUG-9674 : a second evaluation should give the same results QVERIFY(v.extractBackground(&brush, &image, &repeat, &alignment, &origin, &attachment, &ignoredOrigin)); - QVERIFY(expectedBrush.color() == brush.color()); + QCOMPARE(expectedBrush.color(), brush.color()); QTEST(image, "expectedImage"); QTEST(int(repeat), "expectedRepeatValue"); QTEST(int(alignment), "expectedAlignment"); @@ -1438,7 +1438,7 @@ void tst_QCssParser::pseudoElement() decls += rules.at(i).declarations; } - QVERIFY(decls.count() == declCount); + QCOMPARE(decls.count(), declCount); } void tst_QCssParser::gradient_data() @@ -1517,21 +1517,21 @@ void tst_QCssParser::gradient() QBrush sbg, abg; QVERIFY(ve.extractPalette(&fg, &sfg, &sbg, &abg)); if (type == "linear") { - QVERIFY(sbg.style() == Qt::LinearGradientPattern); + QCOMPARE(sbg.style(), Qt::LinearGradientPattern); const QLinearGradient *lg = static_cast<const QLinearGradient *>(sbg.gradient()); QCOMPARE(lg->start(), start); QCOMPARE(lg->finalStop(), finalStop); } else if (type == "conical") { - QVERIFY(sbg.style() == Qt::ConicalGradientPattern); + QCOMPARE(sbg.style(), Qt::ConicalGradientPattern); const QConicalGradient *cg = static_cast<const QConicalGradient *>(sbg.gradient()); QCOMPARE(cg->center(), start); } const QGradient *g = sbg.gradient(); QCOMPARE(g->spread(), QGradient::Spread(spread)); - QVERIFY(g->stops().at(0).first == stop0); - QVERIFY(g->stops().at(0).second == color0); - QVERIFY(g->stops().at(1).first == stop1); - QVERIFY(g->stops().at(1).second == color1); + QCOMPARE(g->stops().at(0).first, stop0); + QCOMPARE(g->stops().at(0).second, color0); + QCOMPARE(g->stops().at(1).first, stop1); + QCOMPARE(g->stops().at(1).second, color1); } void tst_QCssParser::extractFontFamily_data() @@ -1637,15 +1637,15 @@ void tst_QCssParser::extractBorder() QSize radii[4]; extractor.extractBorder(widths, colors, styles, radii); - QVERIFY(widths[QCss::TopEdge] == expectedTopWidth); - QVERIFY(styles[QCss::TopEdge] == expectedTopStyle); - QVERIFY(colors[QCss::TopEdge] == expectedTopColor); + QCOMPARE(widths[QCss::TopEdge], expectedTopWidth); + QCOMPARE(int(styles[QCss::TopEdge]), expectedTopStyle); + QCOMPARE(colors[QCss::TopEdge].color(), expectedTopColor); //QTBUG-9674 : a second evaluation should give the same results QVERIFY(extractor.extractBorder(widths, colors, styles, radii)); - QVERIFY(widths[QCss::TopEdge] == expectedTopWidth); - QVERIFY(styles[QCss::TopEdge] == expectedTopStyle); - QVERIFY(colors[QCss::TopEdge] == expectedTopColor); + QCOMPARE(widths[QCss::TopEdge], expectedTopWidth); + QCOMPARE(int(styles[QCss::TopEdge]), expectedTopStyle); + QCOMPARE(colors[QCss::TopEdge].color(), expectedTopColor); } void tst_QCssParser::noTextDecoration() diff --git a/tests/auto/gui/text/qfont/BLACKLIST b/tests/auto/gui/text/qfont/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..d859dee03eef97eb1a91c39acf3c2c970a396763 --- /dev/null +++ b/tests/auto/gui/text/qfont/BLACKLIST @@ -0,0 +1,2 @@ +[exactMatch] +opensuse-13.1 diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp index 64b06e9856d4ee2cb71f2e7b01b857340eaa8f2c..462e5115b497eb8067c10d01cef34e9642b7bf88 100644 --- a/tests/auto/gui/text/qfont/tst_qfont.cpp +++ b/tests/auto/gui/text/qfont/tst_qfont.cpp @@ -217,15 +217,15 @@ void tst_QFont::exactMatch() || fontinfo.family().isEmpty()); } if (font.pointSize() != -1) { - QVERIFY(font.pointSize() == fontinfo.pointSize()); + QCOMPARE(font.pointSize(), fontinfo.pointSize()); } else { - QVERIFY(font.pixelSize() == fontinfo.pixelSize()); + QCOMPARE(font.pixelSize(), fontinfo.pixelSize()); } - QVERIFY(font.italic() == fontinfo.italic()); + QCOMPARE(font.italic(), fontinfo.italic()); if (font.weight() != fontinfo.weight()) { qDebug("font is %s", font.toString().toLatin1().constData()); } - QVERIFY(font.weight() == fontinfo.weight()); + QCOMPARE(font.weight(), fontinfo.weight()); } else { font.setFixedPitch(!fontinfo.fixedPitch()); QFontInfo fontinfo1(font); @@ -274,12 +274,12 @@ void tst_QFont::exactMatch() || fontinfo.family().contains(font.family()) || fontinfo.family().isEmpty()); if (font.pointSize() != -1) { - QVERIFY(font.pointSize() == fontinfo.pointSize()); + QCOMPARE(font.pointSize(), fontinfo.pointSize()); } else { - QVERIFY(font.pixelSize() == fontinfo.pixelSize()); + QCOMPARE(font.pixelSize(), fontinfo.pixelSize()); } - QVERIFY(font.italic() == fontinfo.italic()); - QVERIFY(font.weight() == fontinfo.weight()); + QCOMPARE(font.italic(), fontinfo.italic()); + QCOMPARE(font.weight(), fontinfo.weight()); } else { font.setFixedPitch(!fontinfo.fixedPitch()); QFontInfo fontinfo1(font, (QFont::Script) script); @@ -371,42 +371,42 @@ void tst_QFont::compare() QVERIFY(font != font2); QCOMPARE(font < font2,!(font2 < font)); font2.setItalic(false); - QVERIFY(font == font2); + QCOMPARE(font, font2); QVERIFY(!(font < font2)); font2.setWeight(QFont::Bold); QVERIFY(font != font2); QCOMPARE(font < font2,!(font2 < font)); font2.setWeight(QFont::Normal); - QVERIFY(font == font2); + QCOMPARE(font, font2); QVERIFY(!(font < font2)); font.setUnderline(true); QVERIFY(font != font2); QCOMPARE(font < font2,!(font2 < font)); font.setUnderline(false); - QVERIFY(font == font2); + QCOMPARE(font, font2); QVERIFY(!(font < font2)); font.setStrikeOut(true); QVERIFY(font != font2); QCOMPARE(font < font2,!(font2 < font)); font.setStrikeOut(false); - QVERIFY(font == font2); + QCOMPARE(font, font2); QVERIFY(!(font < font2)); font.setOverline(true); QVERIFY(font != font2); QCOMPARE(font < font2,!(font2 < font)); font.setOverline(false); - QVERIFY(font == font2); + QCOMPARE(font, font2); QVERIFY(!(font < font2)); font.setCapitalization(QFont::SmallCaps); QVERIFY(font != font2); QCOMPARE(font < font2,!(font2 < font)); font.setCapitalization(QFont::MixedCase); - QVERIFY(font == font2); + QCOMPARE(font, font2); QVERIFY(!(font < font2)); } } @@ -426,27 +426,27 @@ void tst_QFont::resolve() font1.setWeight(QFont::Bold); QFont font2 = font1.resolve(font); - QVERIFY(font2.weight() == font1.weight()); + QCOMPARE(font2.weight(), font1.weight()); - QVERIFY(font2.pointSize() == font.pointSize()); - QVERIFY(font2.italic() == font.italic()); - QVERIFY(font2.underline() == font.underline()); - QVERIFY(font2.overline() == font.overline()); - QVERIFY(font2.strikeOut() == font.strikeOut()); - QVERIFY(font2.stretch() == font.stretch()); + QCOMPARE(font2.pointSize(), font.pointSize()); + QCOMPARE(font2.italic(), font.italic()); + QCOMPARE(font2.underline(), font.underline()); + QCOMPARE(font2.overline(), font.overline()); + QCOMPARE(font2.strikeOut(), font.strikeOut()); + QCOMPARE(font2.stretch(), font.stretch()); QFont font3; font3.setStretch(QFont::UltraCondensed); QFont font4 = font3.resolve(font1).resolve(font); - QVERIFY(font4.stretch() == font3.stretch()); + QCOMPARE(font4.stretch(), font3.stretch()); - QVERIFY(font4.weight() == font.weight()); - QVERIFY(font4.pointSize() == font.pointSize()); - QVERIFY(font4.italic() == font.italic()); - QVERIFY(font4.underline() == font.underline()); - QVERIFY(font4.overline() == font.overline()); - QVERIFY(font4.strikeOut() == font.strikeOut()); + QCOMPARE(font4.weight(), font.weight()); + QCOMPARE(font4.pointSize(), font.pointSize()); + QCOMPARE(font4.italic(), font.italic()); + QCOMPARE(font4.underline(), font.underline()); + QCOMPARE(font4.overline(), font.overline()); + QCOMPARE(font4.strikeOut(), font.strikeOut()); QFont f1,f2,f3; @@ -479,8 +479,8 @@ void tst_QFont::resetFont() child->setFont(QFont()); // reset font - QVERIFY(child->font().resolve() == 0); - QVERIFY(child->font().pointSize() == parent.font().pointSize()); + QCOMPARE(child->font().resolve(), uint(0)); + QCOMPARE(child->font().pointSize(), parent.font().pointSize()); QVERIFY(parent.font().resolve() != 0); } #endif @@ -728,24 +728,24 @@ void tst_QFont::sharing() QCOMPARE(QFontPrivate::get(f)->engineData->ref.load(), 1 + refs_by_cache); QFont f2(f); - QVERIFY(QFontPrivate::get(f2) == QFontPrivate::get(f)); + QCOMPARE(QFontPrivate::get(f2), QFontPrivate::get(f)); QCOMPARE(QFontPrivate::get(f2)->ref.load(), 2); QVERIFY(QFontPrivate::get(f2)->engineData); - QVERIFY(QFontPrivate::get(f2)->engineData == QFontPrivate::get(f)->engineData); + QCOMPARE(QFontPrivate::get(f2)->engineData, QFontPrivate::get(f)->engineData); QCOMPARE(QFontPrivate::get(f2)->engineData->ref.load(), 1 + refs_by_cache); f2.setKerning(!f.kerning()); QVERIFY(QFontPrivate::get(f2) != QFontPrivate::get(f)); QCOMPARE(QFontPrivate::get(f2)->ref.load(), 1); QVERIFY(QFontPrivate::get(f2)->engineData); - QVERIFY(QFontPrivate::get(f2)->engineData == QFontPrivate::get(f)->engineData); + QCOMPARE(QFontPrivate::get(f2)->engineData, QFontPrivate::get(f)->engineData); QCOMPARE(QFontPrivate::get(f2)->engineData->ref.load(), 2 + refs_by_cache); f2 = f; - QVERIFY(QFontPrivate::get(f2) == QFontPrivate::get(f)); + QCOMPARE(QFontPrivate::get(f2), QFontPrivate::get(f)); QCOMPARE(QFontPrivate::get(f2)->ref.load(), 2); QVERIFY(QFontPrivate::get(f2)->engineData); - QVERIFY(QFontPrivate::get(f2)->engineData == QFontPrivate::get(f)->engineData); + QCOMPARE(QFontPrivate::get(f2)->engineData, QFontPrivate::get(f)->engineData); QCOMPARE(QFontPrivate::get(f2)->engineData->ref.load(), 1 + refs_by_cache); if (f.pointSize() > 0) diff --git a/tests/auto/gui/text/qrawfont/BLACKLIST b/tests/auto/gui/text/qrawfont/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..a6145956897fb1a597de86475c642fd7d359e53c --- /dev/null +++ b/tests/auto/gui/text/qrawfont/BLACKLIST @@ -0,0 +1,4 @@ +[correctFontData] +osx-10.8 +[unsupportedWritingSystem] +osx-10.8 diff --git a/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp b/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp index c0b0738e2ad178ca68dd3581b334638a89dfe974..06448d11fe4e61c48888ea95fef78f5947d8dd57 100644 --- a/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp +++ b/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp @@ -170,7 +170,7 @@ void tst_QSyntaxHighlighter::basic() QVERIFY(hl->highlighted); QVERIFY(lout->documentChangedCalled); - QVERIFY(doc->begin().layout()->formats() == formats); + QCOMPARE(doc->begin().layout()->formats(), formats); } class CommentTestHighlighter : public QSyntaxHighlighter diff --git a/tests/auto/gui/text/qtextblock/tst_qtextblock.cpp b/tests/auto/gui/text/qtextblock/tst_qtextblock.cpp index 967fe3114ee7995fd7f886227fc2334095a46e60..49300871d9574a1b76000bf00aafbed48b033c6b 100644 --- a/tests/auto/gui/text/qtextblock/tst_qtextblock.cpp +++ b/tests/auto/gui/text/qtextblock/tst_qtextblock.cpp @@ -102,7 +102,7 @@ void tst_QTextBlock::fragmentOverBlockBoundaries() // Block separators are always a fragment of their self. Thus: // |Hello|\b|World|\b| #if !defined(Q_OS_WIN) - QVERIFY(doc->docHandle()->fragmentMap().numNodes() == 4); + QCOMPARE(doc->docHandle()->fragmentMap().numNodes(), 4); #endif QCOMPARE(cursor.block().text(), QString("Hello")); cursor.movePosition(QTextCursor::NextBlock); @@ -126,7 +126,7 @@ void tst_QTextBlock::excludeParagraphSeparatorFragment() ++it; QVERIFY(it.atEnd()); - QVERIFY(it == block.end()); + QCOMPARE(it, block.end()); } void tst_QTextBlock::backwardsBlockIterator() diff --git a/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp b/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp index 42b3c53bc52d2810aaee8aa34342169eb094185f..9396cd678bdc07f066fddad16b99294c2a8e5972 100644 --- a/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp +++ b/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp @@ -178,15 +178,15 @@ void tst_QTextCursor::navigation1() QVERIFY(doc->toPlainText() == "Hello World"); cursor.movePosition(QTextCursor::End); - QVERIFY(cursor.position() == 11); + QCOMPARE(cursor.position(), 11); cursor.deletePreviousChar(); - QVERIFY(cursor.position() == 10); + QCOMPARE(cursor.position(), 10); cursor.deletePreviousChar(); cursor.deletePreviousChar(); cursor.deletePreviousChar(); cursor.deletePreviousChar(); cursor.deletePreviousChar(); - QVERIFY(doc->toPlainText() == "Hello"); + QCOMPARE(doc->toPlainText(), QLatin1String("Hello")); QTextCursor otherCursor(doc); otherCursor.movePosition(QTextCursor::Start); @@ -195,12 +195,12 @@ void tst_QTextCursor::navigation1() cursor.movePosition(QTextCursor::Right); QVERIFY(cursor != otherCursor); otherCursor.insertText("Hey"); - QVERIFY(cursor.position() == 5); + QCOMPARE(cursor.position(), 5); doc->undo(); - QVERIFY(cursor.position() == 2); + QCOMPARE(cursor.position(), 2); doc->redo(); - QVERIFY(cursor.position() == 5); + QCOMPARE(cursor.position(), 5); doc->undo(); @@ -209,29 +209,29 @@ void tst_QTextCursor::navigation1() cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 6); - QVERIFY(cursor.position() == 6); + QCOMPARE(cursor.position(), 6); otherCursor = cursor; otherCursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2); otherCursor.deletePreviousChar(); otherCursor.deletePreviousChar(); otherCursor.deletePreviousChar(); - QVERIFY(cursor.position() == 5); + QCOMPARE(cursor.position(), 5); cursor.movePosition(QTextCursor::End); cursor.insertBlock(); { int oldPos = cursor.position(); cursor.movePosition(QTextCursor::End); - QVERIFY(cursor.position() == oldPos); + QCOMPARE(cursor.position(), oldPos); } QVERIFY(cursor.atBlockStart()); - QVERIFY(cursor.position() == 9); + QCOMPARE(cursor.position(), 9); QTextCharFormat fmt; fmt.setForeground(Qt::blue); cursor.insertText("Test", fmt); - QVERIFY(fmt == cursor.charFormat()); - QVERIFY(cursor.position() == 13); + QCOMPARE(fmt, cursor.charFormat()); + QCOMPARE(cursor.position(), 13); } void tst_QTextCursor::navigation2_data() @@ -497,7 +497,7 @@ void tst_QTextCursor::navigation10() QVERIFY(ok); QCOMPARE(cursor.position(), 99); ok = cursor.movePosition(QTextCursor::NextCell); - QVERIFY(ok == false); + QVERIFY(!ok); QCOMPARE(cursor.position(), 99); // didn't move. QVERIFY(cursor.currentTable()); @@ -573,8 +573,8 @@ void tst_QTextCursor::insertBlock() QTextBlockFormat fmt; fmt.setTopMargin(100); cursor.insertBlock(fmt); - QVERIFY(cursor.position() == 1); - QVERIFY(cursor.blockFormat() == fmt); + QCOMPARE(cursor.position(), 1); + QCOMPARE(cursor.blockFormat(), fmt); } void tst_QTextCursor::insertWithBlockSeparator1() @@ -584,28 +584,28 @@ void tst_QTextCursor::insertWithBlockSeparator1() cursor.insertText(text); cursor.movePosition(QTextCursor::PreviousBlock); - QVERIFY(cursor.position() == 0); + QCOMPARE(cursor.position(), 0); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.position() == 6); + QCOMPARE(cursor.position(), 6); } void tst_QTextCursor::insertWithBlockSeparator2() { cursor.insertText(QString(QChar::ParagraphSeparator)); - QVERIFY(cursor.position() == 1); + QCOMPARE(cursor.position(), 1); } void tst_QTextCursor::insertWithBlockSeparator3() { cursor.insertText(QString(QChar::ParagraphSeparator) + "Hi" + QString(QChar::ParagraphSeparator)); - QVERIFY(cursor.position() == 4); + QCOMPARE(cursor.position(), 4); } void tst_QTextCursor::insertWithBlockSeparator4() { cursor.insertText(QString(QChar::ParagraphSeparator) + QString(QChar::ParagraphSeparator)); - QVERIFY(cursor.position() == 2); + QCOMPARE(cursor.position(), 2); } void tst_QTextCursor::clearObjectType1() @@ -656,7 +656,7 @@ void tst_QTextCursor::comparisonOperators1() midCursor.movePosition(QTextCursor::NextWord); QVERIFY(midCursor <= cursor); - QVERIFY(midCursor == cursor); + QCOMPARE(midCursor, cursor); QVERIFY(midCursor >= cursor); QVERIFY(midCursor > startCursor); @@ -690,7 +690,7 @@ void tst_QTextCursor::comparisonOperators2() QTextCursor cursor2(&doc2); QVERIFY(cursor1 != cursor2); - QVERIFY(cursor1 == QTextCursor(&doc1)); + QCOMPARE(cursor1, QTextCursor(&doc1)); } void tst_QTextCursor::selection1() @@ -718,97 +718,97 @@ void tst_QTextCursor::dontCopyTableAttributes() void tst_QTextCursor::checkFrame1() { - QVERIFY(cursor.position() == 0); + QCOMPARE(cursor.position(), 0); QPointer<QTextFrame> frame = cursor.insertFrame(QTextFrameFormat()); QVERIFY(frame != 0); QTextFrame *root = frame->parentFrame(); QVERIFY(root != 0); - QVERIFY(frame->firstPosition() == 1); - QVERIFY(frame->lastPosition() == 1); + QCOMPARE(frame->firstPosition(), 1); + QCOMPARE(frame->lastPosition(), 1); QVERIFY(frame->parentFrame() != 0); - QVERIFY(root->childFrames().size() == 1); + QCOMPARE(root->childFrames().size(), 1); - QVERIFY(cursor.position() == 1); - QVERIFY(cursor.selectionStart() == 1); - QVERIFY(cursor.selectionEnd() == 1); + QCOMPARE(cursor.position(), 1); + QCOMPARE(cursor.selectionStart(), 1); + QCOMPARE(cursor.selectionEnd(), 1); doc->undo(); QVERIFY(!frame); - QVERIFY(root->childFrames().size() == 0); + QCOMPARE(root->childFrames().size(), 0); - QVERIFY(cursor.position() == 0); - QVERIFY(cursor.selectionStart() == 0); - QVERIFY(cursor.selectionEnd() == 0); + QCOMPARE(cursor.position(), 0); + QCOMPARE(cursor.selectionStart(), 0); + QCOMPARE(cursor.selectionEnd(), 0); doc->redo(); frame = doc->frameAt(1); QVERIFY(frame); - QVERIFY(frame->firstPosition() == 1); - QVERIFY(frame->lastPosition() == 1); + QCOMPARE(frame->firstPosition(), 1); + QCOMPARE(frame->lastPosition(), 1); QVERIFY(frame->parentFrame() != 0); - QVERIFY(root->childFrames().size() == 1); + QCOMPARE(root->childFrames().size(), 1); - QVERIFY(cursor.position() == 1); - QVERIFY(cursor.selectionStart() == 1); - QVERIFY(cursor.selectionEnd() == 1); + QCOMPARE(cursor.position(), 1); + QCOMPARE(cursor.selectionStart(), 1); + QCOMPARE(cursor.selectionEnd(), 1); // cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor); -// QVERIFY(cursor.position() == 2); -// QVERIFY(cursor.selectionStart() == 0); -// QVERIFY(cursor.selectionEnd() == 2); +// QCOMPARE(cursor.position(), 2); +// QCOMPARE(cursor.selectionStart(), 0); +// QCOMPARE(cursor.selectionEnd(), 2); } void tst_QTextCursor::checkFrame2() { - QVERIFY(cursor.position() == 0); + QCOMPARE(cursor.position(), 0); cursor.insertText("A"); - QVERIFY(cursor.position() == 1); + QCOMPARE(cursor.position(), 1); cursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor); QPointer<QTextFrame> frame = cursor.insertFrame(QTextFrameFormat()); QTextFrame *root = frame->parentFrame(); - QVERIFY(frame->firstPosition() == 1); - QVERIFY(frame->lastPosition() == 2); + QCOMPARE(frame->firstPosition(), 1); + QCOMPARE(frame->lastPosition(), 2); QVERIFY(frame->parentFrame() != 0); - QVERIFY(root->childFrames().size() == 1); + QCOMPARE(root->childFrames().size(), 1); - QVERIFY(cursor.position() == 1); - QVERIFY(cursor.selectionStart() == 1); - QVERIFY(cursor.selectionEnd() == 2); + QCOMPARE(cursor.position(), 1); + QCOMPARE(cursor.selectionStart(), 1); + QCOMPARE(cursor.selectionEnd(), 2); doc->undo(); QVERIFY(!frame); - QVERIFY(root->childFrames().size() == 0); + QCOMPARE(root->childFrames().size(), 0); - QVERIFY(cursor.position() == 0); - QVERIFY(cursor.selectionStart() == 0); - QVERIFY(cursor.selectionEnd() == 1); + QCOMPARE(cursor.position(), 0); + QCOMPARE(cursor.selectionStart(), 0); + QCOMPARE(cursor.selectionEnd(), 1); doc->redo(); frame = doc->frameAt(1); QVERIFY(frame); - QVERIFY(frame->firstPosition() == 1); - QVERIFY(frame->lastPosition() == 2); + QCOMPARE(frame->firstPosition(), 1); + QCOMPARE(frame->lastPosition(), 2); QVERIFY(frame->parentFrame() != 0); - QVERIFY(root->childFrames().size() == 1); + QCOMPARE(root->childFrames().size(), 1); - QVERIFY(cursor.position() == 1); - QVERIFY(cursor.selectionStart() == 1); - QVERIFY(cursor.selectionEnd() == 2); + QCOMPARE(cursor.position(), 1); + QCOMPARE(cursor.selectionStart(), 1); + QCOMPARE(cursor.selectionEnd(), 2); cursor.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor); - QVERIFY(cursor.position() == 0); - QVERIFY(cursor.selectionStart() == 0); - QVERIFY(cursor.selectionEnd() == 3); + QCOMPARE(cursor.position(), 0); + QCOMPARE(cursor.selectionStart(), 0); + QCOMPARE(cursor.selectionEnd(), 3); } void tst_QTextCursor::insertBlockToUseCharFormat() @@ -833,9 +833,9 @@ void tst_QTextCursor::insertBlockToUseCharFormat() void tst_QTextCursor::tableMovement() { - QVERIFY(cursor.position() == 0); + QCOMPARE(cursor.position(), 0); cursor.insertText("AA"); - QVERIFY(cursor.position() == 2); + QCOMPARE(cursor.position(), 2); cursor.movePosition(QTextCursor::Left); cursor.insertTable(3, 3); @@ -1030,7 +1030,7 @@ void tst_QTextCursor::insertBlockShouldRemoveSelection() cursor.insertBlock(); QVERIFY(!cursor.hasSelection()); - QVERIFY(doc->toPlainText().indexOf("Hello") == -1); + QCOMPARE(doc->toPlainText().indexOf("Hello"), -1); } void tst_QTextCursor::insertBlockShouldRemoveSelection2() @@ -1046,7 +1046,7 @@ void tst_QTextCursor::insertBlockShouldRemoveSelection2() cursor.insertBlock(fmt); QVERIFY(!cursor.hasSelection()); - QVERIFY(doc->toPlainText().indexOf("Hello") == -1); + QCOMPARE(doc->toPlainText().indexOf("Hello"), -1); } void tst_QTextCursor::mergeCellShouldUpdateSelection() @@ -1159,7 +1159,7 @@ void tst_QTextCursor::setBlockFormatInTable() cursor.setBlockFormat(fmt); cursor.movePosition(QTextCursor::Start); - QVERIFY(cursor.blockFormat().background().color() == Qt::blue); + QCOMPARE(cursor.blockFormat().background().color(), QColor(Qt::blue)); } void tst_QTextCursor::blockCharFormat2() @@ -1174,7 +1174,7 @@ void tst_QTextCursor::blockCharFormat2() cursor.movePosition(QTextCursor::Start); cursor.insertText("Red"); cursor.movePosition(QTextCursor::PreviousCharacter); - QVERIFY(cursor.charFormat().foreground().color() == Qt::red); + QCOMPARE(cursor.charFormat().foreground().color(), QColor(Qt::red)); } void tst_QTextCursor::blockCharFormat3() @@ -1189,21 +1189,23 @@ void tst_QTextCursor::blockCharFormat3() cursor.insertText("Test"); cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::NextCharacter); - QVERIFY(cursor.charFormat().foreground().color() == Qt::green); + const QColor red(Qt::red); + const QColor green(Qt::green); + QCOMPARE(cursor.charFormat().foreground().color(), green); cursor.movePosition(QTextCursor::Start); - QVERIFY(cursor.charFormat().foreground().color() == Qt::green); + QCOMPARE(cursor.charFormat().foreground().color(), green); fmt.setForeground(Qt::red); cursor.setBlockCharFormat(fmt); - QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::red); + QCOMPARE(cursor.blockCharFormat().foreground().color(), red); cursor.movePosition(QTextCursor::End); cursor.movePosition(QTextCursor::Start); - QVERIFY(cursor.charFormat().foreground().color() == Qt::green); + QCOMPARE(cursor.charFormat().foreground().color(), green); cursor.insertText("Test"); - QVERIFY(cursor.charFormat().foreground().color() == Qt::green); + QCOMPARE(cursor.charFormat().foreground().color(), green); cursor.select(QTextCursor::Document); cursor.removeSelectedText(); @@ -1212,7 +1214,7 @@ void tst_QTextCursor::blockCharFormat3() QVERIFY(cursor.atStart()); cursor.insertText("Test"); - QVERIFY(cursor.charFormat().foreground().color() == Qt::red); + QCOMPARE(cursor.charFormat().foreground().color(), red); } void tst_QTextCursor::blockCharFormat() @@ -1222,12 +1224,12 @@ void tst_QTextCursor::blockCharFormat() cursor.insertBlock(QTextBlockFormat(), fmt); cursor.insertText("Hm"); - QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::blue); + QCOMPARE(cursor.blockCharFormat().foreground().color(), QColor(Qt::blue)); fmt.setForeground(Qt::red); cursor.setBlockCharFormat(fmt); - QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::red); + QCOMPARE(cursor.blockCharFormat().foreground().color(), QColor(Qt::red)); } void tst_QTextCursor::blockCharFormatOnSelection() @@ -1249,11 +1251,11 @@ void tst_QTextCursor::blockCharFormatOnSelection() cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::blue); + QCOMPARE(cursor.blockCharFormat().foreground().color(), QColor(Qt::blue)); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::red); + QCOMPARE(cursor.blockCharFormat().foreground().color(), QColor(Qt::red)); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::white); + QCOMPARE(cursor.blockCharFormat().foreground().color(), QColor(Qt::white)); cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::NextBlock); @@ -1264,17 +1266,17 @@ void tst_QTextCursor::blockCharFormatOnSelection() cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::cyan); + QCOMPARE(cursor.blockCharFormat().foreground().color(), QColor(Qt::cyan)); cursor.movePosition(QTextCursor::Right); cursor.movePosition(QTextCursor::Right); - QVERIFY(cursor.charFormat().foreground().color() == Qt::green); + QCOMPARE(cursor.charFormat().foreground().color(), QColor(Qt::green)); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::cyan); + QCOMPARE(cursor.blockCharFormat().foreground().color(), QColor(Qt::cyan)); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::white); + QCOMPARE(cursor.blockCharFormat().foreground().color(), QColor(Qt::white)); } void tst_QTextCursor::anchorInitialized1() @@ -1404,7 +1406,7 @@ void tst_QTextCursor::selectBlock() cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.blockFormat().alignment() == Qt::AlignHCenter); + QCOMPARE(cursor.blockFormat().alignment(), Qt::AlignHCenter); QCOMPARE(cursor.block().text(), QString("blah")); } @@ -1449,7 +1451,7 @@ void tst_QTextCursor::insertFragmentShouldUseCurrentCharFormat() cursor.insertFragment(fragment); cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::NextCharacter); - QVERIFY(cursor.charFormat() == fmt); + QCOMPARE(cursor.charFormat(), fmt); } int tst_QTextCursor::blockCount() @@ -1910,15 +1912,15 @@ void tst_QTextCursor::cursorPositionWithBlockUndoAndRedo() int cursorPositionAfter = cursor.position(); cursor.endEditBlock(); - QVERIFY(doc->toPlainText() == "*AAAA*BBBB*CCCC*DDDD"); + QCOMPARE(doc->toPlainText(), QLatin1String("*AAAA*BBBB*CCCC*DDDD")); QCOMPARE(12, cursorPositionBefore); QCOMPARE(1, cursorPositionAfter); doc->undo(&cursor); - QVERIFY(doc->toPlainText() == "AAAABBBBCCCCDDDD"); + QCOMPARE(doc->toPlainText(), QLatin1String("AAAABBBBCCCCDDDD")); QCOMPARE(cursor.position(), cursorPositionBefore); doc->redo(&cursor); - QVERIFY(doc->toPlainText() == "*AAAA*BBBB*CCCC*DDDD"); + QCOMPARE(doc->toPlainText(), QLatin1String("*AAAA*BBBB*CCCC*DDDD")); QCOMPARE(cursor.position(), cursorPositionAfter); } @@ -1932,11 +1934,11 @@ void tst_QTextCursor::cursorPositionWithBlockUndoAndRedo2() cursor.insertText("AAAABBBBCCCCDDDD"); cursor.endEditBlock(); doc->undo(&cursor); - QVERIFY(doc->toPlainText() == "AAAABBBB"); + QCOMPARE(doc->toPlainText(), QLatin1String("AAAABBBB")); QCOMPARE(cursor.position(), cursorPositionBefore); cursor.insertText("CCCC"); - QVERIFY(doc->toPlainText() == "AAAABBBBCCCC"); + QCOMPARE(doc->toPlainText(), QLatin1String("AAAABBBBCCCC")); cursorPositionBefore = cursor.position(); cursor.setPosition(0, QTextCursor::KeepAnchor); @@ -1951,7 +1953,7 @@ void tst_QTextCursor::cursorPositionWithBlockUndoAndRedo2() doc->undo(&cursor); - QVERIFY(doc->toPlainText() == "AAAABBBBCCCC"); + QCOMPARE(doc->toPlainText(), QLatin1String("AAAABBBBCCCC")); QCOMPARE(cursor.position(), cursorPositionBefore); } diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp index 5e6b606d83a9013f55bd68e20d52dd0af7577c11..7378ca85ee0a6277533530562cc20a865871f988 100644 --- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp @@ -744,7 +744,7 @@ void tst_QTextDocument::mightBeRichText() { QFETCH(QString, input); QFETCH(bool, result); - QVERIFY(result == Qt::mightBeRichText(input)); + QCOMPARE(result, Qt::mightBeRichText(input)); } Q_DECLARE_METATYPE(QTextDocumentFragment) @@ -2222,7 +2222,7 @@ void tst_QTextDocument::clonePreservesUserStates() b2 = b2.next(); QCOMPARE(b1.userState(), b2.userState()); } - QVERIFY(b2 == clone->end()); + QCOMPARE(b2, clone->end()); delete clone; } @@ -2269,7 +2269,7 @@ void tst_QTextDocument::resolvedFontInEmptyFormat() doc->setDefaultFont(font); QTextCharFormat fmt = doc->begin().charFormat(); QVERIFY(fmt.properties().isEmpty()); - QVERIFY(fmt.font() == font); + QCOMPARE(fmt.font(), font); } void tst_QTextDocument::defaultRootFrameMargin() @@ -2369,6 +2369,7 @@ void tst_QTextDocument::deleteTextObjectsOnClear() void tst_QTextDocument::defaultStyleSheet() { + const QColor green("green"); const QString sheet("p { background-color: green; }"); QVERIFY(doc->defaultStyleSheet().isEmpty()); doc->setDefaultStyleSheet(sheet); @@ -2376,30 +2377,30 @@ void tst_QTextDocument::defaultStyleSheet() cursor.insertHtml("<p>test"); QTextBlockFormat fmt = doc->begin().blockFormat(); - QVERIFY(fmt.background().color() == QColor("green")); + QCOMPARE(fmt.background().color(), green); doc->clear(); cursor.insertHtml("<p>test"); fmt = doc->begin().blockFormat(); - QVERIFY(fmt.background().color() == QColor("green")); + QCOMPARE(fmt.background().color(), green); QTextDocument *clone = doc->clone(); QCOMPARE(clone->defaultStyleSheet(), sheet); cursor = QTextCursor(clone); cursor.insertHtml("<p>test"); fmt = clone->begin().blockFormat(); - QVERIFY(fmt.background().color() == QColor("green")); + QCOMPARE(fmt.background().color(), green); delete clone; cursor = QTextCursor(doc); cursor.insertHtml("<p>test"); fmt = doc->begin().blockFormat(); - QVERIFY(fmt.background().color() == QColor("green")); + QCOMPARE(fmt.background().color(), green); doc->clear(); cursor.insertHtml("<style>p { background-color: red; }</style><p>test"); fmt = doc->begin().blockFormat(); - QVERIFY(fmt.background().color() == QColor("red")); + QCOMPARE(fmt.background().color(), QColor(Qt::red)); doc->clear(); doc->setDefaultStyleSheet("invalid style sheet...."); @@ -2567,7 +2568,7 @@ void tst_QTextDocument::setTextPreservesUndoRedoEnabled() void tst_QTextDocument::firstLast() { QCOMPARE(doc->blockCount(), 1); - QVERIFY(doc->firstBlock() == doc->lastBlock()); + QCOMPARE(doc->firstBlock(), doc->lastBlock()); doc->setPlainText("Hello\nTest\nWorld"); @@ -3013,8 +3014,8 @@ void tst_QTextDocument::QTBUG27354_spaceAndSoftSpace() QTextBlock block = td.begin(); while (block.isValid()) { QTextBlockFormat fmt = block.blockFormat(); - QVERIFY(fmt.lineHeightType() == QTextBlockFormat::SingleHeight); - QVERIFY(fmt.lineHeight() == 0); + QCOMPARE(fmt.lineHeightType(), int(QTextBlockFormat::SingleHeight)); + QCOMPARE(fmt.lineHeight(), qreal(0)); block = block.next(); } } @@ -3164,8 +3165,8 @@ void tst_QTextDocument::cssInheritance() QTextBlock block = td.begin(); while (block.isValid()) { QTextBlockFormat fmt = block.blockFormat(); - QVERIFY(fmt.lineHeightType() == QTextBlockFormat::ProportionalHeight); - QVERIFY(fmt.lineHeight() == 200); + QCOMPARE(fmt.lineHeightType(), int(QTextBlockFormat::ProportionalHeight)); + QCOMPARE(fmt.lineHeight(), qreal(200)); block = block.next(); } } @@ -3175,12 +3176,12 @@ void tst_QTextDocument::cssInheritance() "<p style=\"line-height: 40px\">Foo</p><p>Bar</p><p>Baz</p></body></html>"); QTextBlock block = td.begin(); QTextBlockFormat fmt = block.blockFormat(); - QVERIFY(fmt.lineHeightType() == QTextBlockFormat::FixedHeight); - QVERIFY(fmt.lineHeight() == 40); + QCOMPARE(fmt.lineHeightType(), int(QTextBlockFormat::FixedHeight)); + QCOMPARE(fmt.lineHeight(), qreal(40)); block = block.next(); fmt = block.blockFormat(); - QVERIFY(fmt.lineHeightType() == QTextBlockFormat::ProportionalHeight); - QVERIFY(fmt.lineHeight() == 300); + QCOMPARE(fmt.lineHeightType(), int(QTextBlockFormat::ProportionalHeight)); + QCOMPARE(fmt.lineHeight(), qreal(300)); } { QTextDocument td; @@ -3188,7 +3189,7 @@ void tst_QTextDocument::cssInheritance() "<p>Foo</p><p>Bar</p><p>Baz</p></body></html>"); QTextBlock block = td.begin(); while (block.isValid()) { - QVERIFY(block.blockFormat().background() == QBrush()); + QCOMPARE(block.blockFormat().background(), QBrush()); QVERIFY(block.charFormat().font().bold()); block = block.next(); } diff --git a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp index f6bd09958e3c07b75ef09f282ba2b31772a88fe5..1cd9d9bcbee82372eb183e1c7d93c1e1285df57c 100644 --- a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp +++ b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp @@ -727,7 +727,7 @@ void tst_QTextDocumentFragment::html_listIndents5() QCOMPARE(list->format().indent(), 1); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.currentList() == list); + QCOMPARE(cursor.currentList(), list); QCOMPARE(cursor.blockFormat().indent(), 0); } @@ -778,7 +778,7 @@ void tst_QTextDocumentFragment::blockCharFormatCopied() cleanup(); init(); cursor.insertFragment(frag); - QVERIFY(cursor.blockCharFormat() == fmt); + QCOMPARE(cursor.blockCharFormat(), fmt); } void tst_QTextDocumentFragment::initialBlock() @@ -794,19 +794,19 @@ void tst_QTextDocumentFragment::clone() mod.setAlignment(Qt::AlignCenter); cursor.mergeBlockFormat(mod); cursor.insertText("Blah"); - QVERIFY(cursor.blockFormat().alignment() == Qt::AlignCenter); + QCOMPARE(cursor.blockFormat().alignment(), Qt::AlignCenter); QTextDocumentFragment frag(doc); cleanup(); init(); cursor.insertFragment(frag); cursor.movePosition(QTextCursor::Start); - QVERIFY(cursor.blockFormat().alignment() == Qt::AlignCenter); + QCOMPARE(cursor.blockFormat().alignment(), Qt::AlignCenter); } void tst_QTextDocumentFragment::dontRemoveInitialBlockIfItHoldsObjectIndexedCharFormat() { const char html[] = "<table><tr><td>cell one<td>cell two</tr><tr><td>cell three<td>cell four</tr></table>"; - QVERIFY(doc->begin().charFormat().objectIndex() == -1); + QCOMPARE(doc->begin().charFormat().objectIndex(), -1); setHtml(QString::fromLatin1(html)); int cnt = 0; @@ -841,13 +841,13 @@ void tst_QTextDocumentFragment::unorderedListEnumeration() setHtml(QString::fromLatin1(html)); cursor.movePosition(QTextCursor::End); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListDisc); + QCOMPARE(cursor.currentList()->format().style(), QTextListFormat::ListDisc); const char html2[] = "<ul><ul><ul type=circle><li>Blah</li></ul></ul>"; setHtml(QString::fromLatin1(html2)); cursor.movePosition(QTextCursor::End); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListCircle); + QCOMPARE(cursor.currentList()->format().style(), QTextListFormat::ListCircle); } @@ -873,7 +873,7 @@ void tst_QTextDocumentFragment::hrefAnchor() setHtml(QString::fromLatin1(html)); QVERIFY(doc->begin().begin().fragment().charFormat().isAnchor()); QCOMPARE(doc->begin().begin().fragment().charFormat().anchorHref(), QString::fromLatin1("test")); - QVERIFY(doc->begin().begin().fragment().charFormat().fontUnderline() == true); + QVERIFY(doc->begin().begin().fragment().charFormat().fontUnderline()); } { @@ -881,7 +881,7 @@ void tst_QTextDocumentFragment::hrefAnchor() const char html[] = "<a>blah</a>"; setHtml(QString::fromLatin1(html)); QVERIFY(doc->begin().begin().fragment().charFormat().isAnchor()); - QVERIFY(doc->begin().begin().fragment().charFormat().fontUnderline() == false); + QVERIFY(!doc->begin().begin().fragment().charFormat().fontUnderline()); } } @@ -901,7 +901,7 @@ void tst_QTextDocumentFragment::namedAnchorFragments() // the 'a' QVERIFY(it.fragment().isValid()); QCOMPARE(it.fragment().text(), QString::fromLatin1("a")); - QVERIFY(it.fragment().charFormat().isAnchor() == false); + QVERIFY(!it.fragment().charFormat().isAnchor()); // the 'b' of 'blah' as separate fragment with the anchor attribute ++it; @@ -913,7 +913,7 @@ void tst_QTextDocumentFragment::namedAnchorFragments() ++it; QVERIFY(it.fragment().isValid()); QVERIFY(it.fragment().text().startsWith("lah")); - QVERIFY(it.fragment().charFormat().isAnchor() == false); + QVERIFY(!it.fragment().charFormat().isAnchor()); } void tst_QTextDocumentFragment::namedAnchorFragments2() @@ -982,7 +982,7 @@ void tst_QTextDocumentFragment::cellBlockCount() int blockCount = 0; for (QTextFrame::iterator it = cell.begin(); !it.atEnd(); ++it) { - QVERIFY(it.currentFrame() == 0); + QVERIFY(!it.currentFrame()); QVERIFY(it.currentBlock().isValid()); ++blockCount; } @@ -1003,7 +1003,7 @@ void tst_QTextDocumentFragment::cellBlockCount2() int blockCount = 0; for (QTextFrame::iterator it = cell.begin(); !it.atEnd(); ++it) { - QVERIFY(it.currentFrame() == 0); + QVERIFY(!it.currentFrame()); QVERIFY(it.currentBlock().isValid()); ++blockCount; } @@ -1037,7 +1037,7 @@ void tst_QTextDocumentFragment::emptyTable3() QCOMPARE(table->columns(), 2); QTextTableCell cell = table->cellAt(0, 0); QVERIFY(cell.isValid()); - QVERIFY(cell.firstPosition() == cell.lastPosition()); + QCOMPARE(cell.firstPosition(), cell.lastPosition()); cell = table->cellAt(0, 1); QTextCursor cursor = cell.firstCursorPosition(); cursor.setPosition(cell.lastPosition(), QTextCursor::KeepAnchor); @@ -1065,7 +1065,7 @@ void tst_QTextDocumentFragment::inheritAlignment() const char html[] = "<body align=right><p>Hey"; setHtml(QString::fromLatin1(html)); // html alignment is absolute - QVERIFY(doc->begin().blockFormat().alignment() == Qt::Alignment(Qt::AlignRight|Qt::AlignAbsolute)); + QCOMPARE(doc->begin().blockFormat().alignment(), Qt::Alignment(Qt::AlignRight|Qt::AlignAbsolute)); } void tst_QTextDocumentFragment::dontEmitEmptyNodeWhenEmptyTagIsFollowedByCloseTag() @@ -1073,8 +1073,8 @@ void tst_QTextDocumentFragment::dontEmitEmptyNodeWhenEmptyTagIsFollowedByCloseTa // make sure the Hey does not end up as tag text for the img tag const char html[] = "<body align=right><p align=left>Blah<img></img><p>Hey"; setHtml(QString::fromLatin1(html)); - QVERIFY(doc->begin().blockFormat().alignment() == Qt::Alignment(Qt::AlignLeft|Qt::AlignAbsolute)); - QVERIFY(doc->begin().next().blockFormat().alignment() == Qt::Alignment(Qt::AlignRight|Qt::AlignAbsolute)); + QCOMPARE(doc->begin().blockFormat().alignment(), Qt::Alignment(Qt::AlignLeft|Qt::AlignAbsolute)); + QCOMPARE(doc->begin().next().blockFormat().alignment(), Qt::Alignment(Qt::AlignRight|Qt::AlignAbsolute)); } void tst_QTextDocumentFragment::toPlainText() @@ -1480,19 +1480,19 @@ void tst_QTextDocumentFragment::html_subAndSuperScript() const char alignmentInherited[] = "<sub><font face=\"Verdana\">Subby</font></sub>"; setHtml(subHtml); - QVERIFY(cursor.charFormat().verticalAlignment() == QTextCharFormat::AlignSubScript); + QCOMPARE(cursor.charFormat().verticalAlignment(), QTextCharFormat::AlignSubScript); setHtml(subHtmlCss); - QVERIFY(cursor.charFormat().verticalAlignment() == QTextCharFormat::AlignSubScript); + QCOMPARE(cursor.charFormat().verticalAlignment(), QTextCharFormat::AlignSubScript); setHtml(superHtml); - QVERIFY(cursor.charFormat().verticalAlignment() == QTextCharFormat::AlignSuperScript); + QCOMPARE(cursor.charFormat().verticalAlignment(), QTextCharFormat::AlignSuperScript); setHtml(superHtmlCss); - QVERIFY(cursor.charFormat().verticalAlignment() == QTextCharFormat::AlignSuperScript); + QCOMPARE(cursor.charFormat().verticalAlignment(), QTextCharFormat::AlignSuperScript); setHtml(alignmentInherited); - QVERIFY(cursor.charFormat().verticalAlignment() == QTextCharFormat::AlignSubScript); + QCOMPARE(cursor.charFormat().verticalAlignment(), QTextCharFormat::AlignSubScript); } void tst_QTextDocumentFragment::html_cssColors() @@ -1695,7 +1695,7 @@ void tst_QTextDocumentFragment::html_bodyBackground() const char html[] = "<body background=\"foo.png\">Foo</body>"; doc->setHtml(html); - QVERIFY(doc->rootFrame()->frameFormat().background().style() == Qt::TexturePattern); + QCOMPARE(doc->rootFrame()->frameFormat().background().style(), Qt::TexturePattern); } void tst_QTextDocumentFragment::html_tableCellBackground() @@ -1709,7 +1709,7 @@ void tst_QTextDocumentFragment::html_tableCellBackground() QVERIFY(table); QTextTableCell cell = table->cellAt(0, 0); - QVERIFY(cell.format().background().style() == Qt::TexturePattern); + QCOMPARE(cell.format().background().style(), Qt::TexturePattern); } void tst_QTextDocumentFragment::css_bodyBackground() @@ -1717,7 +1717,7 @@ void tst_QTextDocumentFragment::css_bodyBackground() const char html[] = "<body style=\"background-image:url('foo.png')\">Foo</body>"; doc->setHtml(html); - QVERIFY(doc->rootFrame()->frameFormat().background().style() == Qt::TexturePattern); + QCOMPARE(doc->rootFrame()->frameFormat().background().style(), Qt::TexturePattern); } void tst_QTextDocumentFragment::css_tableCellBackground() @@ -1731,7 +1731,7 @@ void tst_QTextDocumentFragment::css_tableCellBackground() QVERIFY(table); QTextTableCell cell = table->cellAt(0, 0); - QVERIFY(cell.format().background().style() == Qt::TexturePattern); + QCOMPARE(cell.format().background().style(), Qt::TexturePattern); } void tst_QTextDocumentFragment::css_cellPaddings() @@ -1767,7 +1767,7 @@ void tst_QTextDocumentFragment::html_blockLevelDiv() setHtml(html); QCOMPARE(doc->begin().blockFormat().alignment(), Qt::AlignRight|Qt::AlignAbsolute); - QVERIFY(doc->begin().next() == doc->end()); + QCOMPARE(doc->begin().next(), doc->end()); } void tst_QTextDocumentFragment::html_spanNesting() @@ -1805,7 +1805,7 @@ void tst_QTextDocumentFragment::html_nestedLists() cursor.movePosition(QTextCursor::NextBlock); QTextList *thirdList = cursor.currentList(); QVERIFY(thirdList); - QVERIFY(thirdList == firstList); + QCOMPARE(thirdList, firstList); } void tst_QTextDocumentFragment::noSpecialCharactersInPlainText() @@ -1837,7 +1837,7 @@ void tst_QTextDocumentFragment::html_doNotInheritBackground() for (QTextBlock block = doc->begin(); block.isValid(); block = block.next()) { - QVERIFY(block.blockFormat().hasProperty(QTextFormat::BackgroundBrush) == false); + QVERIFY(!block.blockFormat().hasProperty(QTextFormat::BackgroundBrush)); } QVERIFY(doc->rootFrame()->frameFormat().hasProperty(QTextFormat::BackgroundBrush)); @@ -2022,7 +2022,7 @@ void tst_QTextDocumentFragment::html_frameImport() cursor.insertFragment(frag); QList<QTextFrame *> childFrames = doc->rootFrame()->childFrames(); - QVERIFY(childFrames.count() == 1); + QCOMPARE(childFrames.count(), 1); QTextFrame *frame = childFrames.first(); QCOMPARE(frame->frameFormat().margin(), ffmt.margin()); QCOMPARE(frame->frameFormat().border(), ffmt.border()); @@ -2050,7 +2050,7 @@ void tst_QTextDocumentFragment::html_frameImport2() cursor.insertFragment(frag); QList<QTextFrame *> childFrames = doc->rootFrame()->childFrames(); - QVERIFY(childFrames.count() == 1); + QCOMPARE(childFrames.count(), 1); QTextFrame *frame = childFrames.first(); QCOMPARE(frame->frameFormat().topMargin(), ffmt.topMargin()); QCOMPARE(frame->frameFormat().bottomMargin(), ffmt.bottomMargin()); @@ -2065,7 +2065,7 @@ void tst_QTextDocumentFragment::html_dontAddMarginsAcrossTableCells() cursor.insertFragment(QTextDocumentFragment::fromHtml(QString::fromLatin1(html))); QList<QTextFrame *> childFrames = doc->rootFrame()->childFrames(); - QVERIFY(childFrames.count() == 1); + QCOMPARE(childFrames.count(), 1); QTextFrame *frame = childFrames.first(); cursor = frame->firstCursorPosition(); QCOMPARE(cursor.blockFormat().leftMargin(), qreal(50.0)); @@ -2078,7 +2078,7 @@ void tst_QTextDocumentFragment::html_dontMergeCenterBlocks() QCOMPARE(doc->blockCount(), 2); QTextBlock blk = doc->begin(); - QVERIFY(blk.blockFormat().alignment() == Qt::AlignCenter); + QCOMPARE(blk.blockFormat().alignment(), Qt::AlignCenter); blk = blk.next(); QVERIFY(blk.blockFormat().alignment() != Qt::AlignCenter); } @@ -2112,7 +2112,7 @@ void tst_QTextDocumentFragment::html_tableCellBgColor2() QTextFrame::Iterator it = cell.begin(); QVERIFY(!it.atEnd()); - QVERIFY(it.currentFrame() == 0); + QVERIFY(!it.currentFrame()); QVERIFY(it.currentBlock().isValid()); ++it; @@ -2122,9 +2122,9 @@ void tst_QTextDocumentFragment::html_tableCellBgColor2() ++it; QVERIFY(!it.atEnd()); - QVERIFY(it.currentFrame() == 0); + QVERIFY(!it.currentFrame()); QVERIFY(it.currentBlock().isValid()); - QVERIFY(it.currentBlock().blockFormat().background() == QBrush(Qt::NoBrush)); + QCOMPARE(it.currentBlock().blockFormat().background(), QBrush(Qt::NoBrush)); ++it; QVERIFY(it.atEnd()); @@ -2245,8 +2245,8 @@ void tst_QTextDocumentFragment::html_blockVsInline() { { setHtml("<html><body><div><b>Foo<div>Bar"); - QVERIFY(cursor.charFormat().fontWeight() == QFont::Bold); - QVERIFY(cursor.blockCharFormat().fontWeight() == QFont::Bold); + QCOMPARE(cursor.charFormat().fontWeight(), int(QFont::Bold)); + QCOMPARE(cursor.blockCharFormat().fontWeight(), int(QFont::Bold)); } { setHtml("<html><body><p><b>Foo<p>Bar"); @@ -2255,23 +2255,23 @@ void tst_QTextDocumentFragment::html_blockVsInline() } { setHtml("<html><body><b><center>Foo</center></b>"); - QVERIFY(cursor.charFormat().fontWeight() == QFont::Bold); - QVERIFY(cursor.blockCharFormat().fontWeight() == QFont::Bold); + QCOMPARE(cursor.charFormat().fontWeight(), int(QFont::Bold)); + QCOMPARE(cursor.blockCharFormat().fontWeight(), int(QFont::Bold)); } { setHtml("<html><body><b><p>Foo"); - QVERIFY(cursor.charFormat().fontWeight() == QFont::Bold); - QVERIFY(cursor.blockCharFormat().fontWeight() == QFont::Bold); + QCOMPARE(cursor.charFormat().fontWeight(), int(QFont::Bold)); + QCOMPARE(cursor.blockCharFormat().fontWeight(), int(QFont::Bold)); } { setHtml("<html><body><b><p>Foo<p>Bar"); - QVERIFY(cursor.charFormat().fontWeight() == QFont::Bold); - QVERIFY(cursor.blockCharFormat().fontWeight() == QFont::Bold); + QCOMPARE(cursor.charFormat().fontWeight(), int(QFont::Bold)); + QCOMPARE(cursor.blockCharFormat().fontWeight(), int(QFont::Bold)); } { setHtml("<div><b>Foo<div>Bar"); - QVERIFY(cursor.charFormat().fontWeight() == QFont::Bold); - QVERIFY(cursor.blockCharFormat().fontWeight() == QFont::Bold); + QCOMPARE(cursor.charFormat().fontWeight(), int(QFont::Bold)); + QCOMPARE(cursor.blockCharFormat().fontWeight(), int(QFont::Bold)); } { setHtml("<p><b>Foo<p>Bar"); @@ -2280,18 +2280,18 @@ void tst_QTextDocumentFragment::html_blockVsInline() } { setHtml("<b><center>Foo</center></b>"); - QVERIFY(cursor.charFormat().fontWeight() == QFont::Bold); - QVERIFY(cursor.blockCharFormat().fontWeight() == QFont::Bold); + QCOMPARE(cursor.charFormat().fontWeight(), int(QFont::Bold)); + QCOMPARE(cursor.blockCharFormat().fontWeight(), int(QFont::Bold)); } { setHtml("<b><p>Foo"); - QVERIFY(cursor.charFormat().fontWeight() == QFont::Bold); - QVERIFY(cursor.blockCharFormat().fontWeight() == QFont::Bold); + QCOMPARE(cursor.charFormat().fontWeight(), int(QFont::Bold)); + QCOMPARE(cursor.blockCharFormat().fontWeight(), int(QFont::Bold)); } { setHtml("<b><p>Foo<p>Bar"); - QVERIFY(cursor.charFormat().fontWeight() == QFont::Bold); - QVERIFY(cursor.blockCharFormat().fontWeight() == QFont::Bold); + QCOMPARE(cursor.charFormat().fontWeight(), int(QFont::Bold)); + QCOMPARE(cursor.blockCharFormat().fontWeight(), int(QFont::Bold)); } } @@ -2338,7 +2338,7 @@ void tst_QTextDocumentFragment::html_nestedTables() QTextTable *firstNestedTable = cursor.currentTable(); QVERIFY(firstNestedTable); - QVERIFY(firstNestedTable->parentFrame() == table); + QCOMPARE(firstNestedTable->parentFrame(), table); QCOMPARE(firstNestedTable->rows(), 1); QCOMPARE(firstNestedTable->columns(), 1); QCOMPARE(firstNestedTable->cellAt(0, 0).firstCursorPosition().block().text(), QString("Hello")); @@ -2348,13 +2348,13 @@ void tst_QTextDocumentFragment::html_nestedTables() ; QVERIFY(!cursor.isNull()); - QVERIFY(cursor.currentTable() == table); + QCOMPARE(cursor.currentTable(), table); cursor.movePosition(QTextCursor::NextBlock); QTextTable *secondNestedTable = cursor.currentTable(); QVERIFY(secondNestedTable); - QVERIFY(secondNestedTable->parentFrame() == table); + QCOMPARE(secondNestedTable->parentFrame(), table); QCOMPARE(secondNestedTable->rows(), 1); QCOMPARE(secondNestedTable->columns(), 1); QCOMPARE(secondNestedTable->cellAt(0, 0).firstCursorPosition().block().text(), QString("World")); @@ -2454,7 +2454,7 @@ void tst_QTextDocumentFragment::html_anchorColor() setHtml("<span style=\"color: red;\"><a href=\"http://www.kde.org/\">Blue</a></span>"); cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::NextCharacter); - QVERIFY(cursor.charFormat().foreground().color() == QGuiApplication::palette().link().color()); + QCOMPARE(cursor.charFormat().foreground().color(), QGuiApplication::palette().link().color()); setHtml("<span style=\"color: red;\"><a href=\"http://www.kde.org/\" style=\"color: yellow;\">Green</a></span>"); cursor.movePosition(QTextCursor::Start); @@ -2525,17 +2525,17 @@ void tst_QTextDocumentFragment::html_columnWidths() const QVector<QTextLength> columnWidths = fmt.columnWidthConstraints(); QCOMPARE(columnWidths.count(), 2); - QVERIFY(columnWidths.at(0).type() == QTextLength::VariableLength); - QVERIFY(columnWidths.at(1).type() == QTextLength::PercentageLength); - QVERIFY(columnWidths.at(1).rawValue() == 1); + QCOMPARE(columnWidths.at(0).type(), QTextLength::VariableLength); + QCOMPARE(columnWidths.at(1).type(), QTextLength::PercentageLength); + QCOMPARE(columnWidths.at(1).rawValue(), qreal(1)); } void tst_QTextDocumentFragment::css_fontWeight() { setHtml("<p style=\"font-weight:bold\">blah</p>"); - QVERIFY(doc->begin().charFormat().fontWeight() == QFont::Bold); + QCOMPARE(doc->begin().charFormat().fontWeight(), int(QFont::Bold)); setHtml("<p style=\"font-weight:600\">blah</p>"); - QVERIFY(doc->begin().charFormat().fontWeight() == QFont::Bold); + QCOMPARE(doc->begin().charFormat().fontWeight(), int(QFont::Bold)); } @@ -2548,7 +2548,7 @@ void tst_QTextDocumentFragment::css_float() QVERIFY(o); QTextFormat f = o->format(); QVERIFY(f.isFrameFormat()); - QVERIFY(f.toFrameFormat().position() == QTextFrameFormat::FloatRight); + QCOMPARE(f.toFrameFormat().position(), QTextFrameFormat::FloatRight); setHtml("<img src=\"foo\" align=right>"); fmt = doc->begin().begin().fragment().charFormat(); @@ -2557,7 +2557,7 @@ void tst_QTextDocumentFragment::css_float() QVERIFY(o); f = o->format(); QVERIFY(f.isFrameFormat()); - QVERIFY(f.toFrameFormat().position() == QTextFrameFormat::FloatRight); + QCOMPARE(f.toFrameFormat().position(), QTextFrameFormat::FloatRight); setHtml("<img src=\"foo\" align=left>"); fmt = doc->begin().begin().fragment().charFormat(); @@ -2566,7 +2566,7 @@ void tst_QTextDocumentFragment::css_float() QVERIFY(o); f = o->format(); QVERIFY(f.isFrameFormat()); - QVERIFY(f.toFrameFormat().position() == QTextFrameFormat::FloatLeft); + QCOMPARE(f.toFrameFormat().position(), QTextFrameFormat::FloatLeft); } void tst_QTextDocumentFragment::css_textIndent() @@ -2585,7 +2585,7 @@ void tst_QTextDocumentFragment::css_inline() "<p>test</p>" ); QTextBlockFormat fmt = doc->begin().blockFormat(); - QVERIFY(fmt.background().color() == QColor("green")); + QCOMPARE(fmt.background().color(), QColor("green")); } void tst_QTextDocumentFragment::css_external() @@ -2596,11 +2596,12 @@ void tst_QTextDocumentFragment::css_external() "<p>test</p>" ); QTextBlockFormat fmt = doc->begin().blockFormat(); - QVERIFY(fmt.background().color() == QColor("green")); + QCOMPARE(fmt.background().color(), QColor("green")); } void tst_QTextDocumentFragment::css_import() { + const QColor green("green"); doc->addResource(QTextDocument::StyleSheetResource, QUrl("test.css"), QString("@import \"other.css\";")); doc->addResource(QTextDocument::StyleSheetResource, QUrl("other.css"), QString("@import url(\"other2.css\");")); doc->addResource(QTextDocument::StyleSheetResource, QUrl("other2.css"), QString("p { background-color: green; }")); @@ -2609,14 +2610,14 @@ void tst_QTextDocumentFragment::css_import() "<p>test</p>" ); QTextBlockFormat fmt = doc->begin().blockFormat(); - QVERIFY(fmt.background().color() == QColor("green")); + QCOMPARE(fmt.background().color(), green); doc->setHtml("" "<style>@import \"test.css\" screen;</style>" "<p>test</p>" ); fmt = doc->begin().blockFormat(); - QVERIFY(fmt.background().color() == QColor("green")); + QCOMPARE(fmt.background().color(), green); } void tst_QTextDocumentFragment::css_selectors_data() @@ -2662,9 +2663,9 @@ void tst_QTextDocumentFragment::css_selectors() QTextBlockFormat fmt = doc->begin().blockFormat(); if (match) - QVERIFY(fmt.background().color() == QColor("red")); + QCOMPARE(fmt.background().color(), QColor("red")); else - QVERIFY(fmt.background().color() == QColor("green")); + QCOMPARE(fmt.background().color(), QColor("green")); } void tst_QTextDocumentFragment::css_nodeNameCaseInsensitivity() @@ -2674,7 +2675,7 @@ void tst_QTextDocumentFragment::css_nodeNameCaseInsensitivity() "</style>" "<p>test</p>"); QTextBlockFormat fmt = doc->begin().blockFormat(); - QVERIFY(fmt.background().color() == QColor("green")); + QCOMPARE(fmt.background().color(), QColor("green")); } void tst_QTextDocumentFragment::css_textUnderlineStyle_data() @@ -2710,14 +2711,14 @@ void tst_QTextDocumentFragment::css_textUnderlineStyleAndDecoration() QTextFragment fragment = doc->begin().begin().fragment(); QVERIFY(fragment.isValid()); - QVERIFY(fragment.charFormat().underlineStyle() == QTextCharFormat::SingleUnderline); + QCOMPARE(fragment.charFormat().underlineStyle(), QTextCharFormat::SingleUnderline); QVERIFY(fragment.charFormat().fontOverline()); doc->setHtml("<span style=\"text-underline-style: solid; text-decoration: overline\">Test</span>"); fragment = doc->begin().begin().fragment(); QVERIFY(fragment.isValid()); - QVERIFY(fragment.charFormat().underlineStyle() == QTextCharFormat::SingleUnderline); + QCOMPARE(fragment.charFormat().underlineStyle(), QTextCharFormat::SingleUnderline); QVERIFY(fragment.charFormat().fontOverline()); } @@ -2726,48 +2727,48 @@ void tst_QTextDocumentFragment::css_listStyleType() doc->setHtml("<ol style=\"list-style-type: disc\"><li>Blah</li></ol>"); cursor.movePosition(QTextCursor::End); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListDisc); + QCOMPARE(cursor.currentList()->format().style(), QTextListFormat::ListDisc); doc->setHtml("<ul style=\"list-style-type: square\"><li>Blah</li></ul>"); cursor.movePosition(QTextCursor::End); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListSquare); + QCOMPARE(cursor.currentList()->format().style(), QTextListFormat::ListSquare); doc->setHtml("<ul style=\"list-style-type: circle\"><li>Blah</li></ul>"); cursor.movePosition(QTextCursor::End); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListCircle); + QCOMPARE(cursor.currentList()->format().style(), QTextListFormat::ListCircle); doc->setHtml("<ul style=\"list-style-type: decimal\"><li>Blah</li></ul>"); cursor.movePosition(QTextCursor::End); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListDecimal); + QCOMPARE(cursor.currentList()->format().style(), QTextListFormat::ListDecimal); doc->setHtml("<ul style=\"list-style-type: lower-alpha\"><li>Blah</li></ul>"); cursor.movePosition(QTextCursor::End); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListLowerAlpha); + QCOMPARE(cursor.currentList()->format().style(), QTextListFormat::ListLowerAlpha); doc->setHtml("<ul style=\"list-style-type: upper-alpha\"><li>Blah</li></ul>"); cursor.movePosition(QTextCursor::End); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListUpperAlpha); + QCOMPARE(cursor.currentList()->format().style(), QTextListFormat::ListUpperAlpha); doc->setHtml("<ul style=\"list-style-type: upper-roman\"><li>Blah</li></ul>"); cursor.movePosition(QTextCursor::End); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListUpperRoman); + QCOMPARE(cursor.currentList()->format().style(), QTextListFormat::ListUpperRoman); doc->setHtml("<ul style=\"list-style-type: lower-roman\"><li>Blah</li></ul>"); cursor.movePosition(QTextCursor::End); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListLowerRoman); + QCOMPARE(cursor.currentList()->format().style(), QTextListFormat::ListLowerRoman); // ignore the unsupported list-style-position inside the list-style shorthand property doc->setHtml("<ul style=\"list-style: outside decimal\"><li>Blah</li></ul>"); cursor.movePosition(QTextCursor::End); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListDecimal); + QCOMPARE(cursor.currentList()->format().style(), QTextListFormat::ListDecimal); } void tst_QTextDocumentFragment::css_linkPseudo() @@ -2785,13 +2786,13 @@ void tst_QTextDocumentFragment::css_linkPseudo() void tst_QTextDocumentFragment::css_pageBreaks() { doc->setHtml("<p>Foo</p>"); - QVERIFY(doc->begin().blockFormat().pageBreakPolicy() == QTextFormat::PageBreak_Auto); + QCOMPARE(doc->begin().blockFormat().pageBreakPolicy(), QTextFormat::PageBreak_Auto); doc->setHtml("<p style=\" page-break-before:always;\">Foo</p>"); - QVERIFY(doc->begin().blockFormat().pageBreakPolicy() == QTextFormat::PageBreak_AlwaysBefore); + QCOMPARE(doc->begin().blockFormat().pageBreakPolicy(), QTextFormat::PageBreak_AlwaysBefore); doc->setHtml("<p style=\" page-break-after:always;\">Foo</p>"); - QVERIFY(doc->begin().blockFormat().pageBreakPolicy() == QTextFormat::PageBreak_AlwaysAfter); + QCOMPARE(doc->begin().blockFormat().pageBreakPolicy(), QTextFormat::PageBreak_AlwaysAfter); doc->setHtml("<p style=\" page-break-before:always; page-break-after:always;\">Foo</p>"); QVERIFY(doc->begin().blockFormat().pageBreakPolicy() == (QTextFormat::PageBreak_AlwaysAfter | QTextFormat::PageBreak_AlwaysBefore)); @@ -2832,13 +2833,14 @@ void tst_QTextDocumentFragment::universalSelectors() QTextBlockFormat fmt = doc->begin().blockFormat(); if (match) - QVERIFY(fmt.background().color() == QColor("green")); + QCOMPARE(fmt.background().color(), QColor("green")); else QVERIFY(!fmt.hasProperty(QTextFormat::BackgroundBrush)); } void tst_QTextDocumentFragment::screenMedia() { + const QColor green("green"); setHtml("<style>" "@media screen {" "p { background-color: green }" @@ -2847,7 +2849,7 @@ void tst_QTextDocumentFragment::screenMedia() "<p>test</p>" ""); QTextBlockFormat fmt = doc->begin().blockFormat(); - QVERIFY(fmt.background().color() == QColor("green")); + QCOMPARE(fmt.background().color(), green); setHtml("<style>" "@media foobar {" @@ -2857,7 +2859,7 @@ void tst_QTextDocumentFragment::screenMedia() "<p>test</p>" ""); fmt = doc->begin().blockFormat(); - QVERIFY(fmt.background().color() != QColor("green")); + QVERIFY(fmt.background().color() != green); setHtml("<style>" "@media sCrEeN {" @@ -2867,7 +2869,7 @@ void tst_QTextDocumentFragment::screenMedia() "<p>test</p>" ""); fmt = doc->begin().blockFormat(); - QVERIFY(fmt.background().color() == QColor("green")); + QCOMPARE(fmt.background().color(), green); } void tst_QTextDocumentFragment::htmlResourceLoading() @@ -2881,7 +2883,7 @@ void tst_QTextDocumentFragment::htmlResourceLoading() doc->clear(); QTextCursor(doc).insertFragment(frag); QTextBlockFormat fmt = doc->begin().blockFormat(); - QVERIFY(fmt.background().color() == QColor("green")); + QCOMPARE(fmt.background().color(), QColor("green")); } void tst_QTextDocumentFragment::someCaseInsensitiveAttributeValues() @@ -2890,7 +2892,7 @@ void tst_QTextDocumentFragment::someCaseInsensitiveAttributeValues() setHtml(QString::fromLatin1(html1)); cursor.movePosition(QTextCursor::End); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListSquare); + QCOMPARE(cursor.currentList()->format().style(), QTextListFormat::ListSquare); const char html2[] = "<div align=ceNTeR><b>Hello World"; setHtml(html2); @@ -2925,7 +2927,7 @@ void tst_QTextDocumentFragment::backgroundImage() doc.testPixmap.fill(Qt::blue); doc.setHtml("<p style=\"background-image: url(testPixmap)\">Hello</p>"); QBrush bg = doc.begin().blockFormat().background(); - QVERIFY(bg.style() == Qt::TexturePattern); + QCOMPARE(bg.style(), Qt::TexturePattern); QCOMPARE(bg.texture().cacheKey(), doc.testPixmap.cacheKey()); } @@ -3109,7 +3111,7 @@ void tst_QTextDocumentFragment::html_tableStrangeNewline() QCOMPARE(table->columns(), 1); const QTextTableCell cell = table->cellAt(0, 0); QCOMPARE(cell.firstCursorPosition().block().text(), QString("Foo")); - QVERIFY(cell.firstCursorPosition().block() == cell.lastCursorPosition().block()); + QCOMPARE(cell.firstCursorPosition().block(), cell.lastCursorPosition().block()); } void tst_QTextDocumentFragment::html_tableStrangeNewline2() @@ -3123,7 +3125,7 @@ void tst_QTextDocumentFragment::html_tableStrangeNewline2() QCOMPARE(table->columns(), 1); const QTextTableCell cell = table->cellAt(0, 0); QCOMPARE(cell.firstCursorPosition().block().text(), QString("Foo")); - QVERIFY(cell.firstCursorPosition().block() == cell.lastCursorPosition().block()); + QCOMPARE(cell.firstCursorPosition().block(), cell.lastCursorPosition().block()); } void tst_QTextDocumentFragment::html_tableStrangeNewline3() @@ -3152,11 +3154,11 @@ void tst_QTextDocumentFragment::html_tableStrangeNewline3() QTextTableCell cell = table->cellAt(0, 0); QCOMPARE(cell.firstCursorPosition().block().text(), QString("Meh")); - QVERIFY(cell.firstCursorPosition().block() == cell.lastCursorPosition().block()); + QCOMPARE(cell.firstCursorPosition().block(), cell.lastCursorPosition().block()); cell = table->cellAt(0, 1); QCOMPARE(cell.firstCursorPosition().block().text(), QString("Foo")); - QVERIFY(cell.firstCursorPosition().block() == cell.lastCursorPosition().block()); + QCOMPARE(cell.firstCursorPosition().block(), cell.lastCursorPosition().block()); } void tst_QTextDocumentFragment::html_caption() @@ -3170,7 +3172,7 @@ void tst_QTextDocumentFragment::html_caption() cursor.movePosition(QTextCursor::NextBlock); QCOMPARE(cursor.block().text(), QString("This is a Caption!")); - QVERIFY(cursor.blockFormat().alignment() == Qt::AlignHCenter); + QCOMPARE(cursor.blockFormat().alignment(), Qt::AlignHCenter); cursor.movePosition(QTextCursor::NextBlock); QTextTable *table = cursor.currentTable(); @@ -3427,7 +3429,7 @@ void tst_QTextDocumentFragment::html_dontInheritAlignmentForFloatingImages() QVERIFY(o); QTextFormat f = o->format(); QVERIFY(f.isFrameFormat()); - QVERIFY(f.toFrameFormat().position() == QTextFrameFormat::InFlow); + QCOMPARE(f.toFrameFormat().position(), QTextFrameFormat::InFlow); } void tst_QTextDocumentFragment::html_verticalImageAlignment() @@ -3437,35 +3439,35 @@ void tst_QTextDocumentFragment::html_verticalImageAlignment() cursor.movePosition(QTextCursor::NextCharacter); QVERIFY(cursor.charFormat().isImageFormat()); QTextImageFormat fmt = cursor.charFormat().toImageFormat(); - QVERIFY(fmt.verticalAlignment() == QTextCharFormat::AlignNormal); + QCOMPARE(fmt.verticalAlignment(), QTextCharFormat::AlignNormal); doc->setHtml("<img src=\"foo\" align=middle />"); cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::NextCharacter); QVERIFY(cursor.charFormat().isImageFormat()); fmt = cursor.charFormat().toImageFormat(); - QVERIFY(fmt.verticalAlignment() == QTextCharFormat::AlignMiddle); + QCOMPARE(fmt.verticalAlignment(), QTextCharFormat::AlignMiddle); doc->setHtml("<img src=\"foo\" style=\"vertical-align: middle\" />"); cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::NextCharacter); QVERIFY(cursor.charFormat().isImageFormat()); fmt = cursor.charFormat().toImageFormat(); - QVERIFY(fmt.verticalAlignment() == QTextCharFormat::AlignMiddle); + QCOMPARE(fmt.verticalAlignment(), QTextCharFormat::AlignMiddle); doc->setHtml("<img src=\"foo\" align=top />"); cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::NextCharacter); QVERIFY(cursor.charFormat().isImageFormat()); fmt = cursor.charFormat().toImageFormat(); - QVERIFY(fmt.verticalAlignment() == QTextCharFormat::AlignTop); + QCOMPARE(fmt.verticalAlignment(), QTextCharFormat::AlignTop); doc->setHtml("<img src=\"foo\" style=\"vertical-align: top\" />"); cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::NextCharacter); QVERIFY(cursor.charFormat().isImageFormat()); fmt = cursor.charFormat().toImageFormat(); - QVERIFY(fmt.verticalAlignment() == QTextCharFormat::AlignTop); + QCOMPARE(fmt.verticalAlignment(), QTextCharFormat::AlignTop); } void tst_QTextDocumentFragment::html_verticalCellAlignment() @@ -3944,11 +3946,11 @@ void tst_QTextDocumentFragment::html_directionWithHtml() block = block.next(); QVERIFY(block.blockFormat().hasProperty(QTextFormat::LayoutDirection)); - QVERIFY(block.blockFormat().layoutDirection() == Qt::RightToLeft); + QCOMPARE(block.blockFormat().layoutDirection(), Qt::RightToLeft); block = block.next(); QVERIFY(block.blockFormat().hasProperty(QTextFormat::LayoutDirection)); - QVERIFY(block.blockFormat().layoutDirection() == Qt::LeftToRight); + QCOMPARE(block.blockFormat().layoutDirection(), Qt::LeftToRight); } void tst_QTextDocumentFragment::html_directionWithRichText() @@ -3961,11 +3963,11 @@ void tst_QTextDocumentFragment::html_directionWithRichText() block = block.next(); QVERIFY(block.blockFormat().hasProperty(QTextFormat::LayoutDirection)); - QVERIFY(block.blockFormat().layoutDirection() == Qt::RightToLeft); + QCOMPARE(block.blockFormat().layoutDirection(), Qt::RightToLeft); block = block.next(); QVERIFY(block.blockFormat().hasProperty(QTextFormat::LayoutDirection)); - QVERIFY(block.blockFormat().layoutDirection() == Qt::LeftToRight); + QCOMPARE(block.blockFormat().layoutDirection(), Qt::LeftToRight); } void tst_QTextDocumentFragment::html_metaInBody() diff --git a/tests/auto/gui/text/qtextdocumentlayout/BLACKLIST b/tests/auto/gui/text/qtextdocumentlayout/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..b13b2497d3d271820159b8d7bdb8f3cdf32fc9c3 --- /dev/null +++ b/tests/auto/gui/text/qtextdocumentlayout/BLACKLIST @@ -0,0 +1,2 @@ +[imageAtRightAlignedTab] +linux diff --git a/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp b/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp index 7c742bc86425f0a0e20fd125e7f4bff74c880462..5a401031e26bf307f244fae3770d7f42b3014e3b 100644 --- a/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp +++ b/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp @@ -101,7 +101,7 @@ void tst_QTextFormat::defaultAlignment() QTextBlockFormat fmt; QVERIFY(!fmt.hasProperty(QTextFormat::BlockAlignment)); QCOMPARE(fmt.intProperty(QTextFormat::BlockAlignment), 0); - QVERIFY(fmt.alignment() == Qt::AlignLeft); + QCOMPARE(fmt.alignment(), Qt::AlignLeft); } void tst_QTextFormat::testUnderlinePropertyPrecedence() @@ -209,7 +209,7 @@ void tst_QTextFormat::resolveFont() QVector<QTextFormat> formats = doc.allFormats(); QCOMPARE(formats.count(), 3); - QVERIFY(formats.at(2).type() == QTextFormat::CharFormat); + QCOMPARE(formats.at(2).type(), int(QTextFormat::CharFormat)); fmt = formats.at(2).toCharFormat(); QVERIFY(!fmt.font().underline()); diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index 105afa9a91ccc2a36341b5c742e3a0afd9abc2c0..b19f90935b17b9ef47ec6b1533cd8489e33832bb 100644 --- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp @@ -1653,6 +1653,7 @@ void tst_QTextLayout::testTabDPIScale() case QPaintDevice::PdmPhysicalDpiY: return 72; case QPaintDevice::PdmDevicePixelRatio: + case QPaintDevice::PdmDevicePixelRatioScaled: ; // fall through } return 0; @@ -1721,7 +1722,7 @@ void tst_QTextLayout::capitalization_allUpperCase() QTextEngine *engine = layout.engine(); engine->itemize(); QCOMPARE(engine->layoutData->items.count(), 1); - QVERIFY(engine->layoutData->items.at(0).analysis.flags == QScriptAnalysis::Uppercase); + QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::Uppercase)); } void tst_QTextLayout::capitalization_allUpperCase_newline() @@ -1741,9 +1742,9 @@ void tst_QTextLayout::capitalization_allUpperCase_newline() QTextEngine *engine = layout.engine(); engine->itemize(); QCOMPARE(engine->layoutData->items.count(), 3); - QVERIFY(engine->layoutData->items.at(0).analysis.flags == QScriptAnalysis::Uppercase); - QVERIFY(engine->layoutData->items.at(1).analysis.flags == QScriptAnalysis::LineOrParagraphSeparator); - QVERIFY(engine->layoutData->items.at(2).analysis.flags == QScriptAnalysis::Uppercase); + QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::Uppercase)); + QCOMPARE(engine->layoutData->items.at(1).analysis.flags, ushort(QScriptAnalysis::LineOrParagraphSeparator)); + QCOMPARE(engine->layoutData->items.at(2).analysis.flags, ushort(QScriptAnalysis::Uppercase)); } void tst_QTextLayout::capitalization_allLowerCase() @@ -1759,7 +1760,7 @@ void tst_QTextLayout::capitalization_allLowerCase() QTextEngine *engine = layout.engine(); engine->itemize(); QCOMPARE(engine->layoutData->items.count(), 1); - QVERIFY(engine->layoutData->items.at(0).analysis.flags == QScriptAnalysis::Lowercase); + QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::Lowercase)); } void tst_QTextLayout::capitalization_smallCaps() @@ -1775,8 +1776,8 @@ void tst_QTextLayout::capitalization_smallCaps() QTextEngine *engine = layout.engine(); engine->itemize(); QCOMPARE(engine->layoutData->items.count(), 2); - QVERIFY(engine->layoutData->items.at(0).analysis.flags == QScriptAnalysis::None); - QVERIFY(engine->layoutData->items.at(1).analysis.flags == QScriptAnalysis::SmallCaps); + QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::None)); + QCOMPARE(engine->layoutData->items.at(1).analysis.flags, ushort(QScriptAnalysis::SmallCaps)); } void tst_QTextLayout::capitalization_capitalize() @@ -1792,11 +1793,11 @@ void tst_QTextLayout::capitalization_capitalize() QTextEngine *engine = layout.engine(); engine->itemize(); QCOMPARE(engine->layoutData->items.count(), 5); - QVERIFY(engine->layoutData->items.at(0).analysis.flags == QScriptAnalysis::Uppercase); - QVERIFY(engine->layoutData->items.at(1).analysis.flags == QScriptAnalysis::None); - QVERIFY(engine->layoutData->items.at(2).analysis.flags == QScriptAnalysis::Tab); - QVERIFY(engine->layoutData->items.at(3).analysis.flags == QScriptAnalysis::Uppercase); - QVERIFY(engine->layoutData->items.at(4).analysis.flags == QScriptAnalysis::None); + QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::Uppercase)); + QCOMPARE(engine->layoutData->items.at(1).analysis.flags, ushort(QScriptAnalysis::None)); + QCOMPARE(engine->layoutData->items.at(2).analysis.flags, ushort(QScriptAnalysis::Tab)); + QCOMPARE(engine->layoutData->items.at(3).analysis.flags, ushort(QScriptAnalysis::Uppercase)); + QCOMPARE(engine->layoutData->items.at(4).analysis.flags, ushort(QScriptAnalysis::None)); } void tst_QTextLayout::longText() @@ -2072,8 +2073,8 @@ void tst_QTextLayout::cursorInNonStopChars() QTextLine line = layout.createLine(); layout.endLayout(); - QVERIFY(line.cursorToX(1) == line.cursorToX(3)); - QVERIFY(line.cursorToX(2) == line.cursorToX(3)); + QCOMPARE(line.cursorToX(1), line.cursorToX(3)); + QCOMPARE(line.cursorToX(2), line.cursorToX(3)); } void tst_QTextLayout::justifyTrailingSpaces() diff --git a/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp b/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp index c57123af6118a795f9d6debd7a76ab777360f9b2..03e557d8dd8734f94536d5961edb6e671a306b84 100644 --- a/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp +++ b/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp @@ -113,11 +113,11 @@ void tst_QTextList::autoNumbering() for (int i = 0; i < 27; ++i) cursor.insertBlock(); - QVERIFY(list->count() == 28); + QCOMPARE(list->count(), 28); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 27); - QVERIFY(cursor.currentList()->itemText(cursor.block()) == "ab."); + QCOMPARE(cursor.currentList()->itemNumber(cursor.block()), 27); + QCOMPARE(cursor.currentList()->itemText(cursor.block()), QLatin1String("ab.")); } void tst_QTextList::autoNumberingPrefixAndSuffix() @@ -132,11 +132,11 @@ void tst_QTextList::autoNumberingPrefixAndSuffix() for (int i = 0; i < 27; ++i) cursor.insertBlock(); - QVERIFY(list->count() == 28); + QCOMPARE(list->count(), 28); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 27); - QVERIFY(cursor.currentList()->itemText(cursor.block()) == "-ab)"); + QCOMPARE(cursor.currentList()->itemNumber(cursor.block()), 27); + QCOMPARE(cursor.currentList()->itemText(cursor.block()), QLatin1String("-ab)")); } void tst_QTextList::autoNumberingPrefixAndSuffixRTL() @@ -154,9 +154,9 @@ void tst_QTextList::autoNumberingPrefixAndSuffixRTL() cursor.insertBlock(); - QVERIFY(list->count() == 2); + QCOMPARE(list->count(), 2); - QVERIFY(cursor.currentList()->itemText(cursor.block()) == "*B-"); + QCOMPARE(cursor.currentList()->itemText(cursor.block()), QLatin1String("*B-")); } void tst_QTextList::autoNumberingPrefixAndSuffixHtmlExportImport() @@ -174,7 +174,7 @@ void tst_QTextList::autoNumberingPrefixAndSuffixHtmlExportImport() for (int i = 0; i < 27; ++i) cursor.insertBlock(); - QVERIFY(list->count() == 28); + QCOMPARE(list->count(), 28); QString htmlExport = doc->toHtml(); QTextDocument importDoc; @@ -185,9 +185,9 @@ void tst_QTextList::autoNumberingPrefixAndSuffixHtmlExportImport() importCursor.movePosition(QTextCursor::NextBlock); QVERIFY(importCursor.currentList()); - QVERIFY(importCursor.currentList()->itemNumber(importCursor.block()) == 27); - QVERIFY(importCursor.currentList()->itemText(importCursor.block()) == "\"ab#"); - QVERIFY(importCursor.currentList()->format().indent() == 10); + QCOMPARE(importCursor.currentList()->itemNumber(importCursor.block()), 27); + QCOMPARE(importCursor.currentList()->itemText(importCursor.block()), QLatin1String("\"ab#")); + QCOMPARE(importCursor.currentList()->format().indent(), 10); } void tst_QTextList::autoNumberingRTL() @@ -203,9 +203,9 @@ void tst_QTextList::autoNumberingRTL() cursor.insertBlock(); - QVERIFY(list->count() == 2); + QCOMPARE(list->count(), 2); - QVERIFY(cursor.currentList()->itemText(cursor.block()) == ".B"); + QCOMPARE(cursor.currentList()->itemText(cursor.block()), QLatin1String(".B")); } void tst_QTextList::romanNumbering() @@ -218,11 +218,11 @@ void tst_QTextList::romanNumbering() for (int i = 0; i < 4998; ++i) cursor.insertBlock(); - QVERIFY(list->count() == 4999); + QCOMPARE(list->count(), 4999); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 4998); - QVERIFY(cursor.currentList()->itemText(cursor.block()) == "MMMMCMXCIX."); + QCOMPARE(cursor.currentList()->itemNumber(cursor.block()), 4998); + QCOMPARE(cursor.currentList()->itemText(cursor.block()), QLatin1String("MMMMCMXCIX.")); } void tst_QTextList::romanNumberingLimit() @@ -235,11 +235,11 @@ void tst_QTextList::romanNumberingLimit() for (int i = 0; i < 4999; ++i) cursor.insertBlock(); - QVERIFY(list->count() == 5000); + QCOMPARE(list->count(), 5000); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 4999); - QVERIFY(cursor.currentList()->itemText(cursor.block()) == "?."); + QCOMPARE(cursor.currentList()->itemNumber(cursor.block()), 4999); + QCOMPARE(cursor.currentList()->itemText(cursor.block()), QLatin1String("?.")); } void tst_QTextList::formatChange() @@ -257,12 +257,12 @@ void tst_QTextList::formatChange() QVERIFY(list && list->count() == 2); QTextBlockFormat bfmt = cursor.blockFormat(); -// QVERIFY(bfmt.object() == list); +// QCOMPARE(bfmt.object(), list); bfmt.setObjectIndex(-1); cursor.setBlockFormat(bfmt); - QVERIFY(firstList->count() == 1); + QCOMPARE(firstList->count(), 1); } void tst_QTextList::cursorNavigation() @@ -282,7 +282,7 @@ void tst_QTextList::cursorNavigation() QVERIFY(cursor.currentList()); cursor.movePosition(QTextCursor::PreviousBlock); QVERIFY(cursor.currentList()); - QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 0); + QCOMPARE(cursor.currentList()->itemNumber(cursor.block()), 0); } void tst_QTextList::partialRemoval() diff --git a/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp b/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp index ae8948a61fcfc7bcc898d64406f22becb03dda21..cd43849729019d8dc973ac39dc418a44fa125c79 100644 --- a/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp +++ b/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp @@ -157,7 +157,7 @@ void tst_QTextPieceTable::insertion3() table->insert(pos, str, charFormatIndex); compare.insert(pos, str); } - QVERIFY(table->plainText() == compare); + QCOMPARE(table->plainText(), compare); } void tst_QTextPieceTable::insertion4() @@ -176,7 +176,7 @@ void tst_QTextPieceTable::insertion4() // exit(12); // } } - QVERIFY(table->plainText() == compare); + QCOMPARE(table->plainText(), compare); } void tst_QTextPieceTable::insertion5() @@ -196,10 +196,10 @@ void tst_QTextPieceTable::insertion5() } compare.insert(pos, str); } - QVERIFY(table->plainText() == compare); + QCOMPARE(table->plainText(), compare); for (QTextBlock it = table->blocksBegin(); it != table->blocksEnd(); it = it.next()) { QTextDocumentPrivate::FragmentIterator fit = table->find(it.position()); - QVERIFY(fit.position() == it.position()); + QCOMPARE(fit.position(), it.position()); } } @@ -260,7 +260,7 @@ void tst_QTextPieceTable::removal3() // exit(12); // } } - QVERIFY(table->plainText() == compare); + QCOMPARE(table->plainText(), compare); } void tst_QTextPieceTable::removal4() @@ -294,7 +294,7 @@ void tst_QTextPieceTable::removal4() // exit(12); // } } - QVERIFY(table->plainText() == compare); + QCOMPARE(table->plainText(), compare); } void tst_QTextPieceTable::undoRedo1() @@ -392,7 +392,7 @@ void tst_QTextPieceTable::undoRedo6() QTextBlockFormat bfmt; bfmt.setAlignment(Qt::AlignHCenter); cursor.setBlockFormat(bfmt); - QVERIFY(cursor.blockFormat().alignment() == Qt::AlignHCenter); + QCOMPARE(cursor.blockFormat().alignment(), Qt::AlignHCenter); QTextCursor range = cursor; range.clearSelection(); @@ -404,11 +404,11 @@ void tst_QTextPieceTable::undoRedo6() range.mergeCharFormat(modifier); cursor.movePosition(QTextCursor::Start); - QVERIFY(cursor.blockFormat().alignment() == Qt::AlignHCenter); + QCOMPARE(cursor.blockFormat().alignment(), Qt::AlignHCenter); doc.undo(); - QVERIFY(cursor.blockFormat().alignment() == Qt::AlignHCenter); + QCOMPARE(cursor.blockFormat().alignment(), Qt::AlignHCenter); } void tst_QTextPieceTable::undoRedo7() @@ -497,13 +497,13 @@ void tst_QTextPieceTable::undoRedo11() } l += remove ? -1 : 2; } - QVERIFY(table->plainText() == compare); + QCOMPARE(table->plainText(), compare); for (int i = 0; i < loops; ++i) table->undo(); - QVERIFY(table->plainText() == QString("")); + QCOMPARE(table->plainText(), QString("")); for (int i = 0; i < loops; ++i) table->redo(); - QVERIFY(table->plainText() == compare); + QCOMPARE(table->plainText(), compare); } @@ -693,9 +693,9 @@ void tst_QTextPieceTable::setBlockFormat() QTextBlock b = table->blocksFind(1); table->setBlockFormat(b, b, newbfmt); - QVERIFY(table->blocksFind(0).blockFormat() == bfmt); - QVERIFY(table->blocksFind(1).blockFormat() == newbfmt); - QVERIFY(table->blocksFind(2).blockFormat() == bfmt); + QCOMPARE(table->blocksFind(0).blockFormat(), bfmt); + QCOMPARE(table->blocksFind(1).blockFormat(), newbfmt); + QCOMPARE(table->blocksFind(2).blockFormat(), bfmt); } @@ -705,19 +705,19 @@ void tst_QTextPieceTable::blockInsertion() fmt.setTopMargin(100); int idx = table->formatCollection()->indexForFormat(fmt); int charFormat = table->formatCollection()->indexForFormat(QTextCharFormat()); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); table->insertBlock(0, idx, charFormat); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(1).blockFormat() == fmt); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(1).blockFormat(), fmt); table->undo(); - QVERIFY(table->blockMap().length() == 1); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); + QCOMPARE(table->blockMap().length(), 1); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); table->redo(); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(1).blockFormat() == fmt); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(1).blockFormat(), fmt); } void tst_QTextPieceTable::blockInsertion2() @@ -755,37 +755,37 @@ void tst_QTextPieceTable::blockRemoval1() table->insertBlock(9, idx2, charFormatIndex); table->insert(10, "0123", charFormatIndex); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == fmt1); - QVERIFY(table->blocksFind(10).blockFormat() == fmt2); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(6).position() == 5); - QVERIFY(table->blocksFind(11).position() == 10); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), fmt1); + QCOMPARE(table->blocksFind(10).blockFormat(), fmt2); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(6).position(), 5); + QCOMPARE(table->blocksFind(11).position(), 10); table->beginEditBlock(); table->remove(5, 5); table->endEditBlock(); - QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == fmt2); - QVERIFY(table->blocksFind(4).position() == 0); - QVERIFY(table->blocksFind(5).position() == 5); + QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), fmt2); + QCOMPARE(table->blocksFind(4).position(), 0); + QCOMPARE(table->blocksFind(5).position(), 5); table->undo(); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == fmt1); - QVERIFY(table->blocksFind(10).blockFormat() == fmt2); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(6).position() == 5); - QVERIFY(table->blocksFind(11).position() == 10); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), fmt1); + QCOMPARE(table->blocksFind(10).blockFormat(), fmt2); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(6).position(), 5); + QCOMPARE(table->blocksFind(11).position(), 10); table->redo(); - QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == fmt2); - QVERIFY(table->blocksFind(4).position() == 0); - QVERIFY(table->blocksFind(5).position() == 5); + QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), fmt2); + QCOMPARE(table->blocksFind(4).position(), 0); + QCOMPARE(table->blocksFind(5).position(), 5); } void tst_QTextPieceTable::blockRemoval2() @@ -803,35 +803,35 @@ void tst_QTextPieceTable::blockRemoval2() table->insertBlock(9, idx2, charFormatIndex); table->insert(10, "0123", charFormatIndex); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == fmt1); - QVERIFY(table->blocksFind(10).blockFormat() == fmt2); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(6).position() == 5); - QVERIFY(table->blocksFind(11).position() == 10); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), fmt1); + QCOMPARE(table->blocksFind(10).blockFormat(), fmt2); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(6).position(), 5); + QCOMPARE(table->blocksFind(11).position(), 10); table->remove(4, 1); - QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(6).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(4).position() == 0); - QVERIFY(table->blocksFind(6).position() == 0); + QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(6).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(4).position(), 0); + QCOMPARE(table->blocksFind(6).position(), 0); table->undo(); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == fmt1); - QVERIFY(table->blocksFind(10).blockFormat() == fmt2); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(6).position() == 5); - QVERIFY(table->blocksFind(11).position() == 10); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), fmt1); + QCOMPARE(table->blocksFind(10).blockFormat(), fmt2); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(6).position(), 5); + QCOMPARE(table->blocksFind(11).position(), 10); table->redo(); - QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(6).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(4).position() == 0); - QVERIFY(table->blocksFind(6).position() == 0); + QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(6).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(4).position(), 0); + QCOMPARE(table->blocksFind(6).position(), 0); } void tst_QTextPieceTable::blockRemoval3() @@ -849,38 +849,38 @@ void tst_QTextPieceTable::blockRemoval3() table->insertBlock(9, idx2, charFormatIndex); table->insert(10, "0123", charFormatIndex); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == fmt1); - QVERIFY(table->blocksFind(10).blockFormat() == fmt2); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(6).position() == 5); - QVERIFY(table->blocksFind(11).position() == 10); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), fmt1); + QCOMPARE(table->blocksFind(10).blockFormat(), fmt2); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(6).position(), 5); + QCOMPARE(table->blocksFind(11).position(), 10); table->beginEditBlock(); table->remove(3, 4); table->endEditBlock(); - QVERIFY(table->blocksFind(1).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(5).position() == 0); + QCOMPARE(table->blocksFind(1).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(5).position(), 0); table->undo(); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == fmt1); - QVERIFY(table->blocksFind(10).blockFormat() == fmt2); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(6).position() == 5); - QVERIFY(table->blocksFind(11).position() == 10); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), fmt1); + QCOMPARE(table->blocksFind(10).blockFormat(), fmt2); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(6).position(), 5); + QCOMPARE(table->blocksFind(11).position(), 10); table->redo(); - QVERIFY(table->blocksFind(1).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(5).position() == 0); + QCOMPARE(table->blocksFind(1).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(5).position(), 0); } void tst_QTextPieceTable::blockRemoval4() @@ -899,35 +899,35 @@ void tst_QTextPieceTable::blockRemoval4() table->insertBlock(9, idx2, charFormatIndex); table->insert(10, "0123", charFormatIndex); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == fmt1); - QVERIFY(table->blocksFind(10).blockFormat() == fmt2); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(6).position() == 5); - QVERIFY(table->blocksFind(11).position() == 10); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), fmt1); + QCOMPARE(table->blocksFind(10).blockFormat(), fmt2); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(6).position(), 5); + QCOMPARE(table->blocksFind(11).position(), 10); table->remove(3, 7); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(5).position() == 0); - QVERIFY(table->blocksFind(1).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == QTextBlockFormat()); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(5).position(), 0); + QCOMPARE(table->blocksFind(1).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), QTextBlockFormat()); table->undo(); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == fmt1); - QVERIFY(table->blocksFind(10).blockFormat() == fmt2); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(6).position() == 5); - QVERIFY(table->blocksFind(11).position() == 10); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), fmt1); + QCOMPARE(table->blocksFind(10).blockFormat(), fmt2); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(6).position(), 5); + QCOMPARE(table->blocksFind(11).position(), 10); table->redo(); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(5).position() == 0); - QVERIFY(table->blocksFind(1).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == QTextBlockFormat()); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(5).position(), 0); + QCOMPARE(table->blocksFind(1).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), QTextBlockFormat()); #endif } @@ -946,38 +946,38 @@ void tst_QTextPieceTable::blockRemoval5() table->insertBlock(9, idx2, charFormatIndex); table->insert(10, "0123", charFormatIndex); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == fmt1); - QVERIFY(table->blocksFind(10).blockFormat() == fmt2); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(6).position() == 5); - QVERIFY(table->blocksFind(11).position() == 10); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), fmt1); + QCOMPARE(table->blocksFind(10).blockFormat(), fmt2); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(6).position(), 5); + QCOMPARE(table->blocksFind(11).position(), 10); table->beginEditBlock(); table->remove(3, 8); table->endEditBlock(); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(5).position() == 0); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(5).position(), 0); table->undo(); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == fmt1); - QVERIFY(table->blocksFind(10).blockFormat() == fmt2); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(6).position() == 5); - QVERIFY(table->blocksFind(11).position() == 10); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), fmt1); + QCOMPARE(table->blocksFind(10).blockFormat(), fmt2); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(6).position(), 5); + QCOMPARE(table->blocksFind(11).position(), 10); table->redo(); - QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(5).blockFormat() == QTextBlockFormat()); - QVERIFY(table->blocksFind(1).position() == 0); - QVERIFY(table->blocksFind(5).position() == 0); + QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(5).blockFormat(), QTextBlockFormat()); + QCOMPARE(table->blocksFind(1).position(), 0); + QCOMPARE(table->blocksFind(5).position(), 0); } @@ -996,66 +996,66 @@ void tst_QTextPieceTable::checkFrames1() QPointer<QTextFrame> frame = table->insertFrame(1, 3, ffmt); QTextFrame *root = table->rootFrame(); - QVERIFY(root == frame->parentFrame()); + QCOMPARE(root, frame->parentFrame()); QVERIFY(root); - QVERIFY(root->parentFrame() == 0); + QVERIFY(!root->parentFrame()); - QVERIFY(root->childFrames().count() == 1); + QCOMPARE(root->childFrames().count(), 1); QVERIFY(frame->format() == ffmt); - QVERIFY(frame->firstPosition() == 2); - QVERIFY(frame->lastPosition() == 4); + QCOMPARE(frame->firstPosition(), 2); + QCOMPARE(frame->lastPosition(), 4); QPointer<QTextFrame> frame2 = table->insertFrame(2, 3, ffmt); - QVERIFY(root->childFrames().count() == 1); - QVERIFY(root->childFrames().at(0) == frame); - QVERIFY(frame->childFrames().count() == 1); - QVERIFY(frame2->childFrames().count() == 0); - QVERIFY(frame2->parentFrame() == frame); - QVERIFY(frame2->firstPosition() == 3); - QVERIFY(frame2->lastPosition() == 4); + QCOMPARE(root->childFrames().count(), 1); + QCOMPARE(root->childFrames().at(0), frame.data()); + QCOMPARE(frame->childFrames().count(), 1); + QCOMPARE(frame2->childFrames().count(), 0); + QCOMPARE(frame2->parentFrame(), frame.data()); + QCOMPARE(frame2->firstPosition(), 3); + QCOMPARE(frame2->lastPosition(), 4); QVERIFY(frame->format() == ffmt); - QVERIFY(frame->firstPosition() == 2); - QVERIFY(frame->lastPosition() == 6); + QCOMPARE(frame->firstPosition(), 2); + QCOMPARE(frame->lastPosition(), 6); table->removeFrame(frame); - QVERIFY(root->childFrames().count() == 1); - QVERIFY(root->childFrames().at(0) == frame2); + QCOMPARE(root->childFrames().count(), 1); + QCOMPARE(root->childFrames().at(0), frame2.data()); QVERIFY(!frame); - QVERIFY(frame2->childFrames().count() == 0); - QVERIFY(frame2->parentFrame() == root); - QVERIFY(frame2->firstPosition() == 2); - QVERIFY(frame2->lastPosition() == 3); + QCOMPARE(frame2->childFrames().count(), 0); + QCOMPARE(frame2->parentFrame(), root); + QCOMPARE(frame2->firstPosition(), 2); + QCOMPARE(frame2->lastPosition(), 3); table->undo(); frame = table->frameAt(2); - QVERIFY(root->childFrames().count() == 1); - QVERIFY(root->childFrames().at(0) == frame); - QVERIFY(frame->childFrames().count() == 1); - QVERIFY(frame->childFrames().at(0) == frame2); - QVERIFY(frame2->childFrames().count() == 0); - QVERIFY(frame2->parentFrame() == frame); - QVERIFY(frame2->firstPosition() == 3); - QVERIFY(frame2->lastPosition() == 4); + QCOMPARE(root->childFrames().count(), 1); + QCOMPARE(root->childFrames().at(0), frame.data()); + QCOMPARE(frame->childFrames().count(), 1); + QCOMPARE(frame->childFrames().at(0), frame2.data()); + QCOMPARE(frame2->childFrames().count(), 0); + QCOMPARE(frame2->parentFrame(), frame.data()); + QCOMPARE(frame2->firstPosition(), 3); + QCOMPARE(frame2->lastPosition(), 4); - QVERIFY(frame->firstPosition() == 2); - QVERIFY(frame->lastPosition() == 6); + QCOMPARE(frame->firstPosition(), 2); + QCOMPARE(frame->lastPosition(), 6); table->undo(); - QVERIFY(root->childFrames().count() == 1); - QVERIFY(root->childFrames().at(0) == frame); - QVERIFY(frame->childFrames().count() == 0); + QCOMPARE(root->childFrames().count(), 1); + QCOMPARE(root->childFrames().at(0), frame.data()); + QCOMPARE(frame->childFrames().count(), 0); QVERIFY(!frame2); - QVERIFY(frame->firstPosition() == 2); - QVERIFY(frame->lastPosition() == 4); + QCOMPARE(frame->firstPosition(), 2); + QCOMPARE(frame->lastPosition(), 4); } void tst_QTextPieceTable::removeFrameDirect() @@ -1065,7 +1065,7 @@ void tst_QTextPieceTable::removeFrameDirect() QTextFrame *frame = table->insertFrame(1, 5, ffmt); - QVERIFY(frame->parentFrame() == table->rootFrame()); + QCOMPARE(frame->parentFrame(), table->rootFrame()); const int start = frame->firstPosition() - 1; const int end = frame->lastPosition(); diff --git a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp index c8d3122e6d6a056b0dbfd3fbf7914348028e3ba6..1c099acc56dde27806929f78ef3ce27440bbaa8e 100644 --- a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp +++ b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp @@ -146,87 +146,87 @@ void tst_QTextTable::variousTableModifications() QTextTableFormat tableFmt; QTextTable *tab = cursor.insertTable(2, 2, tableFmt); - QVERIFY(doc->toPlainText().length() == 5); - QVERIFY(tab == cursor.currentTable()); - QVERIFY(tab->columns() == 2); - QVERIFY(tab->rows() == 2); + QCOMPARE(doc->toPlainText().length(), 5); + QCOMPARE(tab, cursor.currentTable()); + QCOMPARE(tab->columns(), 2); + QCOMPARE(tab->rows(), 2); - QVERIFY(cursor.position() == 1); + QCOMPARE(cursor.position(), 1); QTextCharFormat fmt = cursor.charFormat(); - QVERIFY(fmt.objectIndex() == -1); + QCOMPARE(fmt.objectIndex(), -1); QTextTableCell cell = tab->cellAt(cursor); QVERIFY(cell.isValid()); - QVERIFY(cell.row() == 0); - QVERIFY(cell.column() == 0); + QCOMPARE(cell.row(), 0); + QCOMPARE(cell.column(), 0); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.position() == 2); + QCOMPARE(cursor.position(), 2); fmt = cursor.charFormat(); - QVERIFY(fmt.objectIndex() == -1); + QCOMPARE(fmt.objectIndex(), -1); cell = tab->cellAt(cursor); QVERIFY(cell.isValid()); - QVERIFY(cell.row() == 0); - QVERIFY(cell.column() == 1); + QCOMPARE(cell.row(), 0); + QCOMPARE(cell.column(), 1); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.position() == 3); + QCOMPARE(cursor.position(), 3); fmt = cursor.charFormat(); - QVERIFY(fmt.objectIndex() == -1); + QCOMPARE(fmt.objectIndex(), -1); cell = tab->cellAt(cursor); QVERIFY(cell.isValid()); - QVERIFY(cell.row() == 1); - QVERIFY(cell.column() == 0); + QCOMPARE(cell.row(), 1); + QCOMPARE(cell.column(), 0); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.position() == 4); + QCOMPARE(cursor.position(), 4); fmt = cursor.charFormat(); - QVERIFY(fmt.objectIndex() == -1); + QCOMPARE(fmt.objectIndex(), -1); cell = tab->cellAt(cursor); QVERIFY(cell.isValid()); - QVERIFY(cell.row() == 1); - QVERIFY(cell.column() == 1); + QCOMPARE(cell.row(), 1); + QCOMPARE(cell.column(), 1); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.position() == 5); + QCOMPARE(cursor.position(), 5); fmt = cursor.charFormat(); - QVERIFY(fmt.objectIndex() == -1); + QCOMPARE(fmt.objectIndex(), -1); cell = tab->cellAt(cursor); QVERIFY(!cell.isValid()); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.position() == 5); + QCOMPARE(cursor.position(), 5); // check we can't delete the cells with the cursor cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.position() == 1); + QCOMPARE(cursor.position(), 1); cursor.deleteChar(); - QVERIFY(doc->toPlainText().length() == 5); + QCOMPARE(doc->toPlainText().length(), 5); cursor.movePosition(QTextCursor::NextBlock); - QVERIFY(cursor.position() == 2); + QCOMPARE(cursor.position(), 2); cursor.deleteChar(); - QVERIFY(doc->toPlainText().length() == 5); + QCOMPARE(doc->toPlainText().length(), 5); cursor.deletePreviousChar(); - QVERIFY(cursor.position() == 2); - QVERIFY(doc->toPlainText().length() == 5); + QCOMPARE(cursor.position(), 2); + QCOMPARE(doc->toPlainText().length(), 5); QTextTable *table = cursor.currentTable(); - QVERIFY(table->rows() == 2); - QVERIFY(table->columns() == 2); + QCOMPARE(table->rows(), 2); + QCOMPARE(table->columns(), 2); table->insertRows(2, 1); - QVERIFY(table->rows() == 3); - QVERIFY(table->columns() == 2); - QVERIFY(doc->toPlainText().length() == 7); + QCOMPARE(table->rows(), 3); + QCOMPARE(table->columns(), 2); + QCOMPARE(doc->toPlainText().length(), 7); table->insertColumns(2, 2); - QVERIFY(table->rows() == 3); - QVERIFY(table->columns() == 4); - QVERIFY(doc->toPlainText().length() == 13); + QCOMPARE(table->rows(), 3); + QCOMPARE(table->columns(), 4); + QCOMPARE(doc->toPlainText().length(), 13); table->resize(4, 5); - QVERIFY(table->rows() == 4); - QVERIFY(table->columns() == 5); - QVERIFY(doc->toPlainText().length() == 21); + QCOMPARE(table->rows(), 4); + QCOMPARE(table->columns(), 5); + QCOMPARE(doc->toPlainText().length(), 21); } void tst_QTextTable::tableShrinking() @@ -234,25 +234,25 @@ void tst_QTextTable::tableShrinking() QTextTableFormat tableFmt; cursor.insertTable(3, 4, tableFmt); - QVERIFY(doc->toPlainText().length() == 13); + QCOMPARE(doc->toPlainText().length(), 13); QTextTable *table = cursor.currentTable(); - QVERIFY(table->rows() == 3); - QVERIFY(table->columns() == 4); + QCOMPARE(table->rows(), 3); + QCOMPARE(table->columns(), 4); table->removeRows(1, 1); - QVERIFY(table->rows() == 2); - QVERIFY(table->columns() == 4); - QVERIFY(doc->toPlainText().length() == 9); + QCOMPARE(table->rows(), 2); + QCOMPARE(table->columns(), 4); + QCOMPARE(doc->toPlainText().length(), 9); table->removeColumns(1, 2); - QVERIFY(table->rows() == 2); - QVERIFY(table->columns() == 2); - QVERIFY(doc->toPlainText().length() == 5); + QCOMPARE(table->rows(), 2); + QCOMPARE(table->columns(), 2); + QCOMPARE(doc->toPlainText().length(), 5); table->resize(1, 1); - QVERIFY(table->rows() == 1); - QVERIFY(table->columns() == 1); - QVERIFY(doc->toPlainText().length() == 2); + QCOMPARE(table->rows(), 1); + QCOMPARE(table->columns(), 1); + QCOMPARE(doc->toPlainText().length(), 2); } void tst_QTextTable::spans() @@ -264,12 +264,12 @@ void tst_QTextTable::spans() QTextTable *table = cursor.currentTable(); QVERIFY(table->cellAt(0, 0) != table->cellAt(0, 1)); table->mergeCells(0, 0, 1, 2); - QVERIFY(table->rows() == 2); - QVERIFY(table->columns() == 2); + QCOMPARE(table->rows(), 2); + QCOMPARE(table->columns(), 2); QVERIFY(table->cellAt(0, 0) == table->cellAt(0, 1)); table->mergeCells(0, 0, 2, 2); - QVERIFY(table->rows() == 2); - QVERIFY(table->columns() == 2); + QCOMPARE(table->rows(), 2); + QCOMPARE(table->columns(), 2); } void tst_QTextTable::variousModifications2() @@ -277,45 +277,45 @@ void tst_QTextTable::variousModifications2() QTextTableFormat tableFmt; cursor.insertTable(2, 5, tableFmt); - QVERIFY(doc->toPlainText().length() == 11); + QCOMPARE(doc->toPlainText().length(), 11); QTextTable *table = cursor.currentTable(); - QVERIFY(cursor.position() == 1); - QVERIFY(table->rows() == 2); - QVERIFY(table->columns() == 5); + QCOMPARE(cursor.position(), 1); + QCOMPARE(table->rows(), 2); + QCOMPARE(table->columns(), 5); table->insertColumns(0, 1); - QVERIFY(table->rows() == 2); - QVERIFY(table->columns() == 6); + QCOMPARE(table->rows(), 2); + QCOMPARE(table->columns(), 6); table->insertColumns(6, 1); - QVERIFY(table->rows() == 2); - QVERIFY(table->columns() == 7); + QCOMPARE(table->rows(), 2); + QCOMPARE(table->columns(), 7); table->insertRows(0, 1); - QVERIFY(table->rows() == 3); - QVERIFY(table->columns() == 7); + QCOMPARE(table->rows(), 3); + QCOMPARE(table->columns(), 7); table->insertRows(3, 1); - QVERIFY(table->rows() == 4); - QVERIFY(table->columns() == 7); + QCOMPARE(table->rows(), 4); + QCOMPARE(table->columns(), 7); table->removeRows(0, 1); - QVERIFY(table->rows() == 3); - QVERIFY(table->columns() == 7); + QCOMPARE(table->rows(), 3); + QCOMPARE(table->columns(), 7); table->removeRows(2, 1); - QVERIFY(table->rows() == 2); - QVERIFY(table->columns() == 7); + QCOMPARE(table->rows(), 2); + QCOMPARE(table->columns(), 7); table->removeColumns(0, 1); - QVERIFY(table->rows() == 2); - QVERIFY(table->columns() == 6); + QCOMPARE(table->rows(), 2); + QCOMPARE(table->columns(), 6); table->removeColumns(5, 1); - QVERIFY(table->rows() == 2); - QVERIFY(table->columns() == 5); + QCOMPARE(table->rows(), 2); + QCOMPARE(table->columns(), 5); tableFmt = table->format(); table->insertColumns(2, 1); table->setFormat(tableFmt); table->insertColumns(2, 1); - QVERIFY(table->columns() == 7); + QCOMPARE(table->columns(), 7); } void tst_QTextTable::tableManager_undo() @@ -325,16 +325,16 @@ void tst_QTextTable::tableManager_undo() QTextTable *table = cursor.insertTable(2, 2, fmt); QVERIFY(table); - QVERIFY(table->format().border() == 10); + QCOMPARE(table->format().border(), qreal(10)); fmt.setBorder(20); table->setFormat(fmt); - QVERIFY(table->format().border() == 20); + QCOMPARE(table->format().border(), qreal(20)); doc->undo(); - QVERIFY(table->format().border() == 10); + QCOMPARE(table->format().border(), qreal(10)); } void tst_QTextTable::tableManager_removeCell() @@ -360,10 +360,10 @@ void tst_QTextTable::rowAt() QTextCursor cell20Cursor = table->cellAt(2, 0).firstCursorPosition(); QTextCursor cell21Cursor = table->cellAt(2, 1).firstCursorPosition(); QTextCursor cell30Cursor = table->cellAt(3, 0).firstCursorPosition(); - QVERIFY(table->cellAt(cell00Cursor).firstCursorPosition() == cell00Cursor); - QVERIFY(table->cellAt(cell10Cursor).firstCursorPosition() == cell10Cursor); - QVERIFY(table->cellAt(cell20Cursor).firstCursorPosition() == cell20Cursor); - QVERIFY(table->cellAt(cell30Cursor).firstCursorPosition() == cell30Cursor); + QCOMPARE(table->cellAt(cell00Cursor).firstCursorPosition(), cell00Cursor); + QCOMPARE(table->cellAt(cell10Cursor).firstCursorPosition(), cell10Cursor); + QCOMPARE(table->cellAt(cell20Cursor).firstCursorPosition(), cell20Cursor); + QCOMPARE(table->cellAt(cell30Cursor).firstCursorPosition(), cell30Cursor); table->mergeCells(1, 0, 2, 1); @@ -433,16 +433,16 @@ void tst_QTextTable::insertRows() QVERIFY(cursor == table->cellAt(0, 0).firstCursorPosition()); table->insertRows(0, 1); - QVERIFY(table->rows() == 3); + QCOMPARE(table->rows(), 3); table->insertRows(1, 1); - QVERIFY(table->rows() == 4); + QCOMPARE(table->rows(), 4); table->insertRows(-1, 1); - QVERIFY(table->rows() == 5); + QCOMPARE(table->rows(), 5); table->insertRows(5, 2); - QVERIFY(table->rows() == 7); + QCOMPARE(table->rows(), 7); } @@ -552,9 +552,9 @@ void tst_QTextTable::mergeCells() QTextBlock block = table->cellAt(0, 0).firstCursorPosition().block(); - QVERIFY(block.text() == "Blah Foo"); - QVERIFY(block.next().text() == "Hah"); - QVERIFY(block.next().next().text() == "Bar"); + QCOMPARE(block.text(), QLatin1String("Blah Foo")); + QCOMPARE(block.next().text(), QLatin1String("Hah")); + QCOMPARE(block.next().next().text(), QLatin1String("Bar")); table = create4x4Table(); @@ -580,7 +580,7 @@ void tst_QTextTable::mergeCells() if (table) { cursor = table->cellAt(0, 0).firstCursorPosition(); - QVERIFY(cursor.block().text() == "Test"); + QCOMPARE(cursor.block().text(), QLatin1String("Test")); } table = create2x2Table(); @@ -750,7 +750,7 @@ void tst_QTextTable::setCellFormat() fmt.setTableCellColumnSpan(25); fmt.setTableCellRowSpan(42); cell.setFormat(fmt); - QVERIFY(cell.format().background().color() == QColor(Qt::blue)); + QCOMPARE(cell.format().background().color(), QColor(Qt::blue)); QCOMPARE(cell.format().tableCellColumnSpan(), 1); QCOMPARE(cell.format().tableCellRowSpan(), 1); } @@ -1086,6 +1086,8 @@ public: { if (PdmDevicePixelRatio == metric) return 1; + if (PdmDevicePixelRatioScaled == metric) + return 1 * QPaintDevice::devicePixelRatioFScale(); if (PdmDpiY == metric) return 96; if (PdmDpiX == metric) diff --git a/tests/auto/gui/text/qzip/tst_qzip.cpp b/tests/auto/gui/text/qzip/tst_qzip.cpp index 90e93881b9c3b1e58256473a1f5e93e122f8f252..8381c93bc285d74cb7cff6f4dc5aa29f80298c4e 100644 --- a/tests/auto/gui/text/qzip/tst_qzip.cpp +++ b/tests/auto/gui/text/qzip/tst_qzip.cpp @@ -39,9 +39,6 @@ class tst_QZip : public QObject { Q_OBJECT -public slots: - void init(); - void cleanup(); private slots: void basicUnpack(); @@ -50,18 +47,10 @@ private slots: void createArchive(); }; -void tst_QZip::init() -{ -} - -void tst_QZip::cleanup() -{ -} - void tst_QZip::basicUnpack() { QZipReader zip(QFINDTESTDATA("/testdata/test.zip"), QIODevice::ReadOnly); - QList<QZipReader::FileInfo> files = zip.fileInfoList(); + QVector<QZipReader::FileInfo> files = zip.fileInfoList(); QCOMPARE(files.count(), 2); QZipReader::FileInfo fi = files.at(0); @@ -97,7 +86,7 @@ void tst_QZip::basicUnpack() void tst_QZip::symlinks() { QZipReader zip(QFINDTESTDATA("/testdata/symlink.zip"), QIODevice::ReadOnly); - QList<QZipReader::FileInfo> files = zip.fileInfoList(); + QVector<QZipReader::FileInfo> files = zip.fileInfoList(); QCOMPARE(files.count(), 2); QZipReader::FileInfo fi = files.at(0); @@ -120,7 +109,7 @@ void tst_QZip::symlinks() void tst_QZip::readTest() { QZipReader zip("foobar.zip", QIODevice::ReadOnly); // non existing file. - QList<QZipReader::FileInfo> files = zip.fileInfoList(); + QVector<QZipReader::FileInfo> files = zip.fileInfoList(); QCOMPARE(files.count(), 0); QByteArray b = zip.fileData("foobar"); QCOMPARE(b.size(), 0); @@ -139,7 +128,7 @@ void tst_QZip::createArchive() QBuffer buffer2(&zipFile); QZipReader zip2(&buffer2); - QList<QZipReader::FileInfo> files = zip2.fileInfoList(); + QVector<QZipReader::FileInfo> files = zip2.fileInfoList(); QCOMPARE(files.count(), 1); QZipReader::FileInfo file = files.at(0); QCOMPARE(file.filePath, QString("My Filename")); diff --git a/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp b/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp index c2833d9e676a1925f859a4f8dbd36afbc7d9e65f..78ab769137dbf618b8d9c0ffcce148a3f5602513 100644 --- a/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp +++ b/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp @@ -256,41 +256,41 @@ void tst_QDoubleValidator::notifySignals() dv.setTop(0.8); QCOMPARE(topSpy.count(), 1); QCOMPARE(changedSpy.count(), 1); - QVERIFY(dv.top() == 0.8); + QCOMPARE(dv.top(), 0.8); dv.setBottom(0.2); QCOMPARE(bottomSpy.count(), 1); QCOMPARE(changedSpy.count(), 2); - QVERIFY(dv.bottom() == 0.2); + QCOMPARE(dv.bottom(), 0.2); dv.setRange(0.2, 0.7); QCOMPARE(topSpy.count(), 2); QCOMPARE(bottomSpy.count(), 1); QCOMPARE(decSpy.count(), 1); QCOMPARE(changedSpy.count(), 3); - QVERIFY(dv.bottom() == 0.2); - QVERIFY(dv.top() == 0.7); - QVERIFY(dv.decimals() == 0.); + QCOMPARE(dv.bottom(), 0.2); + QCOMPARE(dv.top(), 0.7); + QCOMPARE(dv.decimals(), 0); dv.setRange(0.3, 0.7); QCOMPARE(topSpy.count(), 2); QCOMPARE(bottomSpy.count(), 2); QCOMPARE(changedSpy.count(), 4); - QVERIFY(dv.bottom() == 0.3); - QVERIFY(dv.top() == 0.7); - QVERIFY(dv.decimals() == 0.); + QCOMPARE(dv.bottom(), 0.3); + QCOMPARE(dv.top(), 0.7); + QCOMPARE(dv.decimals(), 0); dv.setRange(0.4, 0.6); QCOMPARE(topSpy.count(), 3); QCOMPARE(bottomSpy.count(), 3); QCOMPARE(changedSpy.count(), 5); - QVERIFY(dv.bottom() == 0.4); - QVERIFY(dv.top() == 0.6); - QVERIFY(dv.decimals() == 0.); + QCOMPARE(dv.bottom(), 0.4); + QCOMPARE(dv.top(), 0.6); + QCOMPARE(dv.decimals(), 0); dv.setDecimals(10); QCOMPARE(decSpy.count(), 2); QCOMPARE(changedSpy.count(), 6); - QVERIFY(dv.decimals() == 10.); + QCOMPARE(dv.decimals(), 10); dv.setRange(0.4, 0.6, 100); @@ -298,14 +298,14 @@ void tst_QDoubleValidator::notifySignals() QCOMPARE(bottomSpy.count(), 3); QCOMPARE(decSpy.count(), 3); QCOMPARE(changedSpy.count(), 7); - QVERIFY(dv.bottom() == 0.4); - QVERIFY(dv.top() == 0.6); - QVERIFY(dv.decimals() == 100.); + QCOMPARE(dv.bottom(), 0.4); + QCOMPARE(dv.top(), 0.6); + QCOMPARE(dv.decimals(), 100); dv.setNotation(QDoubleValidator::StandardNotation); QCOMPARE(notSpy.count(), 1); QCOMPARE(changedSpy.count(), 8); - QVERIFY(dv.notation() == QDoubleValidator::StandardNotation); + QCOMPARE(dv.notation(), QDoubleValidator::StandardNotation); dv.setRange(dv.bottom(), dv.top(), dv.decimals()); QCOMPARE(topSpy.count(), 3); diff --git a/tests/auto/gui/util/qintvalidator/tst_qintvalidator.cpp b/tests/auto/gui/util/qintvalidator/tst_qintvalidator.cpp index 43f7b5843931a8e501fed7b318e346d04312a529..a683d903df0a7bdbbb47fd91a19a6d7122edb9b1 100644 --- a/tests/auto/gui/util/qintvalidator/tst_qintvalidator.cpp +++ b/tests/auto/gui/util/qintvalidator/tst_qintvalidator.cpp @@ -239,32 +239,32 @@ void tst_QIntValidator::notifySignals() iv.setTop(9); QCOMPARE(topSpy.count(), 1); QCOMPARE(changedSpy.count(), 1); - QVERIFY(iv.top() == 9); + QCOMPARE(iv.top(), 9); iv.setBottom(1); QCOMPARE(bottomSpy.count(), 1); QCOMPARE(changedSpy.count(), 2); - QVERIFY(iv.bottom() == 1); + QCOMPARE(iv.bottom(), 1); iv.setRange(1, 8); QCOMPARE(topSpy.count(), 2); QCOMPARE(bottomSpy.count(), 1); QCOMPARE(changedSpy.count(), 3); - QVERIFY(iv.top() == 8); - QVERIFY(iv.bottom() == 1); + QCOMPARE(iv.top(), 8); + QCOMPARE(iv.bottom(), 1); iv.setRange(2, 8); QCOMPARE(topSpy.count(), 2); QCOMPARE(bottomSpy.count(), 2); QCOMPARE(changedSpy.count(), 4); - QVERIFY(iv.top() == 8); - QVERIFY(iv.bottom() == 2); + QCOMPARE(iv.top(), 8); + QCOMPARE(iv.bottom(), 2); iv.setRange(3, 7); QCOMPARE(topSpy.count(), 3); QCOMPARE(bottomSpy.count(), 3); QCOMPARE(changedSpy.count(), 5); - QVERIFY(iv.top() == 7); - QVERIFY(iv.bottom() == 3); + QCOMPARE(iv.top(), 7); + QCOMPARE(iv.bottom(), 3); iv.setRange(3, 7); QCOMPARE(topSpy.count(), 3); diff --git a/tests/auto/network/access/qabstractnetworkcache/BLACKLIST b/tests/auto/network/access/qabstractnetworkcache/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..3bd3350e4b6e9a32610156f14bb55918b7efccc2 --- /dev/null +++ b/tests/auto/network/access/qabstractnetworkcache/BLACKLIST @@ -0,0 +1,9 @@ +[cacheControl] +windows +osx +[expires] +osx +[etag] +osx +[lastModified] +osx diff --git a/tests/auto/network/access/qftp/BLACKLIST b/tests/auto/network/access/qftp/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..a67c22265c0492db42f6e1a08e57b9e41cd1900f --- /dev/null +++ b/tests/auto/network/access/qftp/BLACKLIST @@ -0,0 +1,11 @@ +# QTBUG-15111 + +[activeMode:WithoutProxy] +opensuse-13.1 64bit +redhatenterpriselinuxworkstation-6.6 +osx-10.10 + +[activeMode:WithoutProxyWithSession] +opensuse-13.1 64bit +redhatenterpriselinuxworkstation-6.6 +osx-10.10 diff --git a/tests/auto/network/access/qftp/qftp.pro b/tests/auto/network/access/qftp/qftp.pro index 44161f4e1e4ed3dd645bb6260f1da00e725fd092..4294f27e749411c898ac9eb7fbb1b36c3b265a95 100644 --- a/tests/auto/network/access/qftp/qftp.pro +++ b/tests/auto/network/access/qftp/qftp.pro @@ -5,10 +5,9 @@ SOURCES += tst_qftp.cpp requires(contains(QT_CONFIG,private_tests)) QT = core network network-private testlib -wince*: { +wince { addFiles.files = rfc3252.txt addFiles.path = . DEPLOYMENT += addFiles } -CONFIG+=insignificant_test # QTBUG-15111: uses live qt-test-server, inherently unstable diff --git a/tests/auto/network/access/qftp/tst_qftp.cpp b/tests/auto/network/access/qftp/tst_qftp.cpp index 7ea1859938d44a8746325ff0884a7d6301256321..795548ccc8fbab6958a769a1efea5abe4e4ff4cd 100644 --- a/tests/auto/network/access/qftp/tst_qftp.cpp +++ b/tests/auto/network/access/qftp/tst_qftp.cpp @@ -390,8 +390,7 @@ void tst_QFtp::connectToUnresponsiveHost() a lot of other stuff in QFtp, so we just expect this test to fail on Windows. */ QEXPECT_FAIL("", "timeout not working due to strange Windows socket behaviour (see source file of this test for explanation)", Abort); -#else - QEXPECT_FAIL("", "QTBUG-20687", Abort); + #endif QVERIFY2(! QTestEventLoop::instance().timeout(), "Network timeout longer than expected (should have been 60 seconds)"); diff --git a/tests/auto/network/access/qnetworkcookie/tst_qnetworkcookie.cpp b/tests/auto/network/access/qnetworkcookie/tst_qnetworkcookie.cpp index 1d04921c9a96b613c1cbe198022d6e2af6964fe7..be3e839725e3332bfa5229b279fd3775d100868e 100644 --- a/tests/auto/network/access/qnetworkcookie/tst_qnetworkcookie.cpp +++ b/tests/auto/network/access/qnetworkcookie/tst_qnetworkcookie.cpp @@ -83,7 +83,7 @@ void tst_QNetworkCookie::getterSetter() QNetworkCookie cookie; QNetworkCookie otherCookie; - QVERIFY(cookie == otherCookie); + QCOMPARE(cookie, otherCookie); QCOMPARE(cookie, otherCookie); QVERIFY(!(cookie != otherCookie)); @@ -133,7 +133,7 @@ void tst_QNetworkCookie::getterSetter() cookie.setSecure(false); QVERIFY(!cookie.isSecure()); - QVERIFY(cookie == otherCookie); + QCOMPARE(cookie, otherCookie); } void tst_QNetworkCookie::parseSingleCookie_data() diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index 54dcff071edd1eec4cff6b9ec622a93c758562d4..7c9b8db3c3e0006ae893750f74a403bc2bdf1ada 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -1,3 +1,4 @@ +osx [ioGetFromBuiltinHttp:http+limited] osx ubuntu-14.04 diff --git a/tests/auto/network/access/qnetworkreply/qnetworkreply.pro b/tests/auto/network/access/qnetworkreply/qnetworkreply.pro index 885e7f15b679c58721d561f71684bb184e8b10ad..7cb6fddbaf065a4059e9c48a579017752bcee8d0 100644 --- a/tests/auto/network/access/qnetworkreply/qnetworkreply.pro +++ b/tests/auto/network/access/qnetworkreply/qnetworkreply.pro @@ -1,5 +1,5 @@ TEMPLATE = subdirs -!wince*:SUBDIRS += echo +!wince: SUBDIRS += echo test.depends += $$SUBDIRS SUBDIRS += test diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 666bedc8c21a4b07a75545b29ca3607411125b90..9833e1005db8a41c50192f9da429f001cfd5bd8d 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -1678,7 +1678,7 @@ void tst_QNetworkReply::getFromFile() static const char fileData[] = "This is some data that is in the file.\r\n"; QByteArray data = QByteArray::fromRawData(fileData, sizeof fileData - 1); - QVERIFY(file.write(data) == data.size()); + QCOMPARE(file.write(data), data.size()); file.flush(); QCOMPARE(file.size(), qint64(data.size())); @@ -2926,9 +2926,9 @@ void tst_QNetworkReply::connectToIPv6Address() //qDebug() << server.receivedData; QByteArray hostinfo = "\r\nHost: " + hostfield + ":" + QByteArray::number(server.serverPort()) + "\r\n"; QVERIFY(server.receivedData.contains(hostinfo)); - QVERIFY(content == dataToSend); + QCOMPARE(content, dataToSend); QCOMPARE(reply->url(), request.url()); - QVERIFY(reply->error() == error); + QCOMPARE(reply->error(), error); } void tst_QNetworkReply::sendCustomRequestToHttp_data() @@ -3060,7 +3060,7 @@ void tst_QNetworkReply::ioGetFromFile() QVERIFY(file.open()); QFETCH(QByteArray, data); - QVERIFY(file.write(data) == data.size()); + QCOMPARE(file.write(data), data.size()); file.flush(); QCOMPARE(file.size(), qint64(data.size())); @@ -3130,8 +3130,8 @@ void tst_QNetworkReply::ioGetFromFtpWithReuse() DataReader reader2(reply2); QSignalSpy spy(reply1.data(), SIGNAL(finished())); - QVERIFY(waitForFinish(reply1) == Success); - QVERIFY(waitForFinish(reply2) == Success); + QCOMPARE(waitForFinish(reply1), int(Success)); + QCOMPARE(waitForFinish(reply2), int(Success)); QCOMPARE(reply1->url(), request.url()); QCOMPARE(reply2->url(), request.url()); @@ -3181,8 +3181,8 @@ void tst_QNetworkReply::ioGetFromHttpWithReuseParallel() DataReader reader2(reply2); QSignalSpy spy(reply1.data(), SIGNAL(finished())); - QVERIFY(waitForFinish(reply2) == Success); - QVERIFY(waitForFinish(reply1) == Success); + QCOMPARE(waitForFinish(reply2), int(Success)); + QCOMPARE(waitForFinish(reply1), int(Success)); QCOMPARE(reply1->url(), request.url()); QCOMPARE(reply2->url(), request.url()); @@ -3284,8 +3284,8 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth() connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); - QVERIFY(waitForFinish(reply2) == Success); - QVERIFY(waitForFinish(reply1) == Success); + QCOMPARE(waitForFinish(reply2), int(Success)); + QCOMPARE(waitForFinish(reply1), int(Success)); manager.disconnect(SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); @@ -3414,8 +3414,8 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuth() connect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - QVERIFY(waitForFinish(reply2) == Success); - QVERIFY(waitForFinish(reply1) == Success); + QCOMPARE(waitForFinish(reply2), int(Success)); + QCOMPARE(waitForFinish(reply1), int(Success)); manager.disconnect(SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); @@ -3537,7 +3537,7 @@ void tst_QNetworkReply::ioGetFromHttpWithSocksProxy() connect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - QVERIFY(waitForFinish(reply) == Failure); + QCOMPARE(waitForFinish(reply), int(Failure)); manager.disconnect(SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); @@ -3625,7 +3625,7 @@ void tst_QNetworkReply::ioGetFromHttpsWithSslHandshakeError() QSignalSpy sslspy(&manager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>))); connect(reply, SIGNAL(metaDataChanged()), SLOT(storeSslConfiguration())); - QVERIFY(waitForFinish(reply) == Failure); + QCOMPARE(waitForFinish(reply), int(Failure)); QCOMPARE(reply->error(), QNetworkReply::SslHandshakeFailedError); QCOMPARE(sslspy.count(), 0); @@ -3683,7 +3683,7 @@ void tst_QNetworkReply::ioGetFromHttpBrokenServer() QNetworkReplyPtr reply(manager.get(request)); QSignalSpy spy(reply.data(), SIGNAL(error(QNetworkReply::NetworkError))); - QVERIFY(waitForFinish(reply) == Failure); + QCOMPARE(waitForFinish(reply), int(Failure)); QCOMPARE(reply->url(), request.url()); QCOMPARE(spy.count(), 1); @@ -4734,7 +4734,7 @@ void tst_QNetworkReply::ioPostToHttpNoBufferFlag() connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); - QVERIFY(waitForFinish(reply) == Failure); + QCOMPARE(waitForFinish(reply), int(Failure)); disconnect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); @@ -5104,7 +5104,7 @@ void tst_QNetworkReply::ioPostToHttpEmptyUploadProgress() QVERIFY(!QTestEventLoop::instance().timeout()); // final check: only 1 uploadProgress has been emitted - QVERIFY(spy.length() == 1); + QCOMPARE(spy.length(), 1); QList<QVariant> args = spy.last(); QVERIFY(!args.isEmpty()); QCOMPARE(args.at(0).toLongLong(), buffer.size()); @@ -5348,7 +5348,7 @@ void tst_QNetworkReply::chaining() QVERIFY(sourceFile.open()); QFETCH(QByteArray, data); - QVERIFY(sourceFile.write(data) == data.size()); + QCOMPARE(sourceFile.write(data), data.size()); sourceFile.flush(); QCOMPARE(sourceFile.size(), qint64(data.size())); @@ -5360,7 +5360,7 @@ void tst_QNetworkReply::chaining() request.setUrl(url); QNetworkReplyPtr putReply(manager.put(request, getReply.data())); - QVERIFY(waitForFinish(putReply) == Success); + QCOMPARE(waitForFinish(putReply), int(Success)); QCOMPARE(getReply->url(), QUrl::fromLocalFile(sourceFile.fileName())); QCOMPARE(getReply->error(), QNetworkReply::NoError); @@ -5767,7 +5767,7 @@ void tst_QNetworkReply::proxyChange() // verify that the replies succeeded QCOMPARE(reply1->error(), QNetworkReply::NoError); QCOMPARE(reply1->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); - QVERIFY(reply1->size() == 1); + QCOMPARE(reply1->size(), 1); QCOMPARE(reply2->error(), QNetworkReply::NoError); QCOMPARE(reply2->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); @@ -5784,7 +5784,7 @@ void tst_QNetworkReply::proxyChange() manager.setProxy(dummyProxy); QNetworkReplyPtr reply3(manager.get(req)); - QVERIFY(waitForFinish(reply3) == Failure); + QCOMPARE(waitForFinish(reply3), int(Failure)); QVERIFY(int(reply3->error()) > 0); } @@ -5820,7 +5820,7 @@ void tst_QNetworkReply::authorizationError() QSignalSpy errorSpy(reply.data(), SIGNAL(error(QNetworkReply::NetworkError))); QSignalSpy finishedSpy(reply.data(), SIGNAL(finished())); // now run the request: - QVERIFY(waitForFinish(reply) == Failure); + QCOMPARE(waitForFinish(reply), int(Failure)); QFETCH(int, errorSignalCount); QCOMPARE(errorSpy.count(), errorSignalCount); @@ -5995,7 +5995,7 @@ public slots: QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender()); QVERIFY(!reply->error()); - QVERIFY(reply->bytesAvailable() == 27906); + QCOMPARE(reply->bytesAvailable(), 27906); if (requestsFinishedCount == 60) { QTestEventLoop::instance().exitLoop(); @@ -6513,7 +6513,7 @@ public: void finishedSlot() { // We should have already received all readyRead QVERIFY(!bytesAvailableList.isEmpty()); - QVERIFY(bytesAvailableList.last() == uploadSize); + QCOMPARE(bytesAvailableList.last(), uploadSize); } }; @@ -6596,7 +6596,7 @@ void tst_QNetworkReply::ioGetFromHttpWithoutContentLength() QCOMPARE(reply->url(), request.url()); QVERIFY(reply->isFinished()); - QVERIFY(reply->error() == QNetworkReply::NoError); + QCOMPARE(reply->error(), QNetworkReply::NoError); } // Is handled somewhere else too, introduced this special test to have it more accessible @@ -6663,7 +6663,7 @@ void tst_QNetworkReply::compressedHttpReplyBrokenGzip() QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); QNetworkReplyPtr reply(manager.get(request)); - QVERIFY(waitForFinish(reply) == Failure); + QCOMPARE(waitForFinish(reply), int(Failure)); QCOMPARE(reply->error(), QNetworkReply::ProtocolFailure); } @@ -6676,7 +6676,7 @@ void tst_QNetworkReply::getFromUnreachableIp() QNetworkRequest request(QUrl("http://255.255.255.255/42/23/narf/narf/narf")); QNetworkReplyPtr reply(manager.get(request)); - QVERIFY(waitForFinish(reply) == Failure); + QCOMPARE(waitForFinish(reply), int(Failure)); QVERIFY(reply->error() != QNetworkReply::NoError); } @@ -7465,7 +7465,7 @@ void tst_QNetworkReply::httpAbort() QNetworkRequest request3("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"); QNetworkReplyPtr reply3(manager.get(request3)); - QVERIFY(waitForFinish(reply3) == Success); + QCOMPARE(waitForFinish(reply3), int(Success)); QVERIFY(reply3->isFinished()); reply3->abort(); @@ -8095,11 +8095,11 @@ void tst_QNetworkReply::ioHttpChangeMaxRedirects() QSignalSpy redSpy(reply.data(), SIGNAL(redirected(QUrl))); QSignalSpy spy(reply.data(), SIGNAL(error(QNetworkReply::NetworkError))); - QVERIFY(waitForFinish(reply) == Failure); + QCOMPARE(waitForFinish(reply), int(Failure)); QCOMPARE(redSpy.count(), request.maximumRedirectsAllowed()); QCOMPARE(spy.count(), 1); - QVERIFY(reply->error() == QNetworkReply::TooManyRedirectsError); + QCOMPARE(reply->error(), QNetworkReply::TooManyRedirectsError); // Increase max redirects to allow successful completion request.setMaximumRedirectsAllowed(3); @@ -8111,7 +8111,7 @@ void tst_QNetworkReply::ioHttpChangeMaxRedirects() QCOMPARE(redSpy2.count(), 2); QCOMPARE(reply2->url(), server3Url); - QVERIFY(reply2->error() == QNetworkReply::NoError); + QCOMPARE(reply2->error(), QNetworkReply::NoError); } void tst_QNetworkReply::ioHttpRedirectErrors_data() @@ -8151,10 +8151,10 @@ void tst_QNetworkReply::ioHttpRedirectErrors() reply.data()->ignoreSslErrors(); QSignalSpy spy(reply.data(), SIGNAL(error(QNetworkReply::NetworkError))); - QVERIFY(waitForFinish(reply) == Failure); + QCOMPARE(waitForFinish(reply), int(Failure)); QCOMPARE(spy.count(), 1); - QVERIFY(reply->error() == error); + QCOMPARE(reply->error(), error); } #ifndef QT_NO_SSL diff --git a/tests/auto/network/access/spdy/BLACKLIST b/tests/auto/network/access/spdy/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..b13eae1000895a58bc59f62528e738b8f4410816 --- /dev/null +++ b/tests/auto/network/access/spdy/BLACKLIST @@ -0,0 +1,4 @@ +[download] +linux +[upload] +linux diff --git a/tests/auto/network/access/spdy/spdy.pro b/tests/auto/network/access/spdy/spdy.pro index 6bfc6d84e09be81cd5cf51ee45775cb1c45b3e95..23efa85b471e8573f329a629f7c21a2cb7e983e6 100644 --- a/tests/auto/network/access/spdy/spdy.pro +++ b/tests/auto/network/access/spdy/spdy.pro @@ -5,3 +5,5 @@ SOURCES += tst_spdy.cpp QT = core core-private network network-private testlib DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +win32:CONFIG += insignificant_test # QTBUG-47128 diff --git a/tests/auto/network/bearer/qnetworkconfiguration/tst_qnetworkconfiguration.cpp b/tests/auto/network/bearer/qnetworkconfiguration/tst_qnetworkconfiguration.cpp index 7dfc02463e666e95ba7c3ba03ac427d4cc0651be..09ccff496889079cba2c79b9ca7a428e55ae833b 100644 --- a/tests/auto/network/bearer/qnetworkconfiguration/tst_qnetworkconfiguration.cpp +++ b/tests/auto/network/bearer/qnetworkconfiguration/tst_qnetworkconfiguration.cpp @@ -68,7 +68,7 @@ void tst_QNetworkConfiguration::invalidPoint() QVERIFY(pt.name().isEmpty()); QVERIFY(!pt.isValid()); - QVERIFY(pt.type() == QNetworkConfiguration::Invalid); + QCOMPARE(pt.type(), QNetworkConfiguration::Invalid); QVERIFY(!(pt.state() & QNetworkConfiguration::Defined)); QVERIFY(!(pt.state() & QNetworkConfiguration::Discovered)); QVERIFY(!(pt.state() & QNetworkConfiguration::Active)); @@ -77,7 +77,7 @@ void tst_QNetworkConfiguration::invalidPoint() QNetworkConfiguration pt2(pt); QVERIFY(pt2.name().isEmpty()); QVERIFY(!pt2.isValid()); - QVERIFY(pt2.type() == QNetworkConfiguration::Invalid); + QCOMPARE(pt2.type(), QNetworkConfiguration::Invalid); QVERIFY(!(pt2.state() & QNetworkConfiguration::Defined)); QVERIFY(!(pt2.state() & QNetworkConfiguration::Discovered)); QVERIFY(!(pt2.state() & QNetworkConfiguration::Active)); @@ -91,27 +91,27 @@ void tst_QNetworkConfiguration::comparison() //compare invalid connection points QNetworkConfiguration pt1; QVERIFY(!pt1.isValid()); - QVERIFY(pt1.type() == QNetworkConfiguration::Invalid); + QCOMPARE(pt1.type(), QNetworkConfiguration::Invalid); QNetworkConfiguration pt2(pt1); QVERIFY(pt1==pt2); QVERIFY(!(pt1!=pt2)); - QVERIFY(pt1.name() == pt2.name()); - QVERIFY(pt1.isValid() == pt2.isValid()); - QVERIFY(pt1.type() == pt2.type()); - QVERIFY(pt1.state() == pt2.state()); - QVERIFY(pt1.purpose() == pt2.purpose()); + QCOMPARE(pt1.name(), pt2.name()); + QCOMPARE(pt1.isValid(), pt2.isValid()); + QCOMPARE(pt1.type(), pt2.type()); + QCOMPARE(pt1.state(), pt2.state()); + QCOMPARE(pt1.purpose(), pt2.purpose()); QNetworkConfiguration pt3; pt3 = pt1; QVERIFY(pt1==pt3); QVERIFY(!(pt1!=pt3)); - QVERIFY(pt1.name() == pt3.name()); - QVERIFY(pt1.isValid() == pt3.isValid()); - QVERIFY(pt1.type() == pt3.type()); - QVERIFY(pt1.state() == pt3.state()); - QVERIFY(pt1.purpose() == pt3.purpose()); + QCOMPARE(pt1.name(), pt3.name()); + QCOMPARE(pt1.isValid(), pt3.isValid()); + QCOMPARE(pt1.type(), pt3.type()); + QCOMPARE(pt1.state(), pt3.state()); + QCOMPARE(pt1.purpose(), pt3.purpose()); //test case must run on machine that has valid connection points QNetworkConfigurationManager manager; @@ -131,11 +131,11 @@ void tst_QNetworkConfiguration::comparison() pt3 = defaultConfig; QVERIFY(defaultConfig==pt3); QVERIFY(!(defaultConfig!=pt3)); - QVERIFY(defaultConfig.name() == pt3.name()); - QVERIFY(defaultConfig.isValid() == pt3.isValid()); - QVERIFY(defaultConfig.type() == pt3.type()); - QVERIFY(defaultConfig.state() == pt3.state()); - QVERIFY(defaultConfig.purpose() == pt3.purpose()); + QCOMPARE(defaultConfig.name(), pt3.name()); + QCOMPARE(defaultConfig.isValid(), pt3.isValid()); + QCOMPARE(defaultConfig.type(), pt3.type()); + QCOMPARE(defaultConfig.state(), pt3.state()); + QCOMPARE(defaultConfig.purpose(), pt3.purpose()); } void tst_QNetworkConfiguration::children() @@ -178,7 +178,7 @@ void tst_QNetworkConfiguration::isRoamingAvailable() if ( c.children().count() <= 1 ) QVERIFY(!c.isRoamingAvailable()); foreach(QNetworkConfiguration child, c.children()) { - QVERIFY(QNetworkConfiguration::InternetAccessPoint == child.type()); + QCOMPARE(QNetworkConfiguration::InternetAccessPoint, child.type()); QCOMPARE(child.children().count(), 0); } } else { diff --git a/tests/auto/network/bearer/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp b/tests/auto/network/bearer/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp index afe1fc274e1948e560ef600f38b78482ef5a6b4b..94c4d903b2d040bbb166c3a241f41fb92d09a3f4 100644 --- a/tests/auto/network/bearer/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp +++ b/tests/auto/network/bearer/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp @@ -168,7 +168,7 @@ void tst_QNetworkConfigurationManager::defaultConfiguration() QVERIFY(!defaultConfig.isRoamingAvailable()); QCOMPARE(defaultConfig.state(), QNetworkConfiguration::Discovered); QNetworkConfiguration copy = manager.configurationFromIdentifier(defaultConfig.identifier()); - QVERIFY(copy == defaultConfig); + QCOMPARE(copy, defaultConfig); } } @@ -190,7 +190,7 @@ void tst_QNetworkConfigurationManager::configurationFromIdentifier() QNetworkConfiguration direct = manager.configurationFromIdentifier(c.identifier()); QVERIFY(direct.isValid()); - QVERIFY(direct == c); + QCOMPARE(direct, c); } //assume that there is no item with identifier 'FooBar' diff --git a/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp b/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp index 2fd80b3e713c19451969806663dbb59bc8ca5579..cd510ddfa80166a930b0b4d1a66b0f35eb292364 100644 --- a/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp +++ b/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp @@ -187,19 +187,19 @@ void tst_QNetworkSession::invalidSession() // 1. Verify that session created with invalid configuration remains in invalid state QNetworkSession session(QNetworkConfiguration(), 0); QVERIFY(!session.isOpen()); - QVERIFY(session.state() == QNetworkSession::Invalid); - QVERIFY(session.error() == QNetworkSession::InvalidConfigurationError); + QCOMPARE(session.state(), QNetworkSession::Invalid); + QCOMPARE(session.error(), QNetworkSession::InvalidConfigurationError); // 2. Verify that opening session with invalid configuration both 1) emits invalidconfigurationerror and 2) sets session's state as invalid. QSignalSpy errorSpy(&session, SIGNAL(error(QNetworkSession::SessionError))); session.open(); session.waitForOpened(1000); // Should bail out right away - QVERIFY(errorSpy.count() == 1); + QCOMPARE(errorSpy.count(), 1); QNetworkSession::SessionError error = qvariant_cast<QNetworkSession::SessionError> (errorSpy.first().at(0)); - QVERIFY(error == QNetworkSession::InvalidConfigurationError); - QVERIFY(session.error() == QNetworkSession::InvalidConfigurationError); - QVERIFY(session.state() == QNetworkSession::Invalid); + QCOMPARE(error, QNetworkSession::InvalidConfigurationError); + QCOMPARE(session.error(), QNetworkSession::InvalidConfigurationError); + QCOMPARE(session.state(), QNetworkSession::Invalid); #ifdef QNETWORKSESSION_MANUAL_TESTS @@ -210,7 +210,7 @@ void tst_QNetworkSession::invalidSession() qDebug() << "Delete the WLAN IAP from phone now (waiting 60 seconds): " << invalidatedConfig.name(); QTest::qWait(60000); QVERIFY(!invalidatedConfig.isValid()); - QVERIFY(invalidatedSession.state() == QNetworkSession::Invalid); + QCOMPARE(invalidatedSession.state(), QNetworkSession::Invalid); qDebug() << "Add the WLAN IAP back (waiting 60 seconds): " << invalidatedConfig.name(); QTest::qWait(60000); } @@ -235,11 +235,11 @@ void tst_QNetworkSession::invalidSession() QVERIFY(definedSession.state() == QNetworkSession::NotAvailable); // State is not available because WLAN is not in coverage QVERIFY(!errorSpy.isEmpty()); // Session tells with error about invalidated configuration sessionError = qvariant_cast<QNetworkSession::SessionError> (errorSpy.first().at(0)); - QVERIFY(sessionError == QNetworkSession::InvalidConfigurationError); + QCOMPARE(sessionError, QNetworkSession::InvalidConfigurationError); qDebug() << "Turn the WLAN IAP back on (waiting 60 seconds): " << definedConfig.name(); QTest::qWait(60000); updateConfigurations(); - QVERIFY(definedConfig.state() == QNetworkConfiguration::Discovered); + QCOMPARE(definedConfig.state(), QNetworkConfiguration::Discovered); } #endif } @@ -260,7 +260,7 @@ void tst_QNetworkSession::sessionProperties() { QFETCH(QNetworkConfiguration, configuration); QNetworkSession session(configuration); - QVERIFY(session.configuration() == configuration); + QCOMPARE(session.configuration(), configuration); QStringList validBearerNames = QStringList() << QLatin1String("Unknown") << QLatin1String("Ethernet") << QLatin1String("WLAN") @@ -303,10 +303,10 @@ void tst_QNetworkSession::sessionProperties() } else { switch (configuration.state()) { case QNetworkConfiguration::Undefined: - QVERIFY(session.state() == QNetworkSession::NotAvailable); + QCOMPARE(session.state(), QNetworkSession::NotAvailable); break; case QNetworkConfiguration::Defined: - QVERIFY(session.state() == QNetworkSession::NotAvailable); + QCOMPARE(session.state(), QNetworkSession::NotAvailable); break; case QNetworkConfiguration::Discovered: QVERIFY(session.state() == QNetworkSession::Connecting || @@ -372,12 +372,12 @@ void tst_QNetworkSession::userChoiceSession() { QFETCH(QNetworkConfiguration, configuration); - QVERIFY(configuration.type() == QNetworkConfiguration::UserChoice); + QCOMPARE(configuration.type(), QNetworkConfiguration::UserChoice); QNetworkSession session(configuration); // Check that configuration was really set - QVERIFY(session.configuration() == configuration); + QCOMPARE(session.configuration(), configuration); QVERIFY(!session.isOpen()); @@ -431,7 +431,7 @@ void tst_QNetworkSession::userChoiceSession() if (expectStateChange) QTRY_VERIFY_WITH_TIMEOUT(!stateChangedSpy.isEmpty(), TestTimeOut); - QVERIFY(session.state() == QNetworkSession::Connected); + QCOMPARE(session.state(), QNetworkSession::Connected); #ifndef QT_NO_NETWORKINTERFACE QVERIFY(session.interface().isValid()); #endif @@ -462,16 +462,16 @@ void tst_QNetworkSession::userChoiceSession() manager.configurationFromIdentifier(activeIdentifier); QVERIFY(activeConfiguration.isValid()); - QVERIFY(activeConfiguration.type() == QNetworkConfiguration::InternetAccessPoint); + QCOMPARE(activeConfiguration.type(), QNetworkConfiguration::InternetAccessPoint); //resetting ActiveConfiguration is ignored (read only property) session.setSessionProperty("ActiveConfiguration", testIdentifier); QVERIFY(session.sessionProperty("ActiveConfiguration").toString() != testIdentifier); if (userChoiceConfiguration.type() == QNetworkConfiguration::InternetAccessPoint) { - QVERIFY(userChoiceConfiguration == activeConfiguration); + QCOMPARE(userChoiceConfiguration, activeConfiguration); } else { - QVERIFY(userChoiceConfiguration.type() == QNetworkConfiguration::ServiceNetwork); + QCOMPARE(userChoiceConfiguration.type(), QNetworkConfiguration::ServiceNetwork); QVERIFY(userChoiceConfiguration.children().contains(activeConfiguration)); } } else { @@ -500,18 +500,21 @@ void tst_QNetworkSession::sessionOpenCloseStop() { QFETCH(QNetworkConfiguration, configuration); QFETCH(bool, forceSessionStop); +#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) + QSKIP("Deadlocks on Linux due to QTBUG-45655"); +#endif QNetworkSession session(configuration); // Test initial state of the session. { - QVERIFY(session.configuration() == configuration); + QCOMPARE(session.configuration(), configuration); QVERIFY(!session.isOpen()); // session may be invalid if configuration is removed between when // sessionOpenCloseStop_data() is called and here. QVERIFY((configuration.isValid() && (session.state() != QNetworkSession::Invalid)) || (!configuration.isValid() && (session.state() == QNetworkSession::Invalid))); - QVERIFY(session.error() == QNetworkSession::UnknownSessionError); + QCOMPARE(session.error(), QNetworkSession::UnknownSessionError); } // The remaining tests require the session to be not NotAvailable. @@ -541,7 +544,7 @@ void tst_QNetworkSession::sessionOpenCloseStop() QNetworkSession::SessionError error = qvariant_cast<QNetworkSession::SessionError>(errorSpy.first().at(0)); - QVERIFY(session.state() == previousState); + QCOMPARE(session.state(), previousState); if (error == QNetworkSession::OperationNotSupportedError) { // The session needed to bring up the interface, @@ -571,13 +574,13 @@ void tst_QNetworkSession::sessionOpenCloseStop() QNetworkSession::State state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(0).at(0)); - QVERIFY(state == QNetworkSession::Connecting); + QCOMPARE(state, QNetworkSession::Connecting); state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(1).at(0)); - QVERIFY(state == QNetworkSession::Connected); + QCOMPARE(state, QNetworkSession::Connected); } - QVERIFY(session.state() == QNetworkSession::Connected); + QCOMPARE(session.state(), QNetworkSession::Connected); #ifndef QT_NO_NETWORKINTERFACE QVERIFY(session.interface().isValid()); #endif @@ -600,10 +603,10 @@ void tst_QNetworkSession::sessionOpenCloseStop() // Test opening a second session. { - QVERIFY(session2.configuration() == configuration); + QCOMPARE(session2.configuration(), configuration); QVERIFY(!session2.isOpen()); - QVERIFY(session2.state() == QNetworkSession::Connected); - QVERIFY(session.error() == QNetworkSession::UnknownSessionError); + QCOMPARE(session2.state(), QNetworkSession::Connected); + QCOMPARE(session.error(), QNetworkSession::UnknownSessionError); session2.open(); @@ -611,10 +614,10 @@ void tst_QNetworkSession::sessionOpenCloseStop() if (errorSpy2.isEmpty()) { QVERIFY(session2.isOpen()); - QVERIFY(session2.state() == QNetworkSession::Connected); + QCOMPARE(session2.state(), QNetworkSession::Connected); } QVERIFY(session.isOpen()); - QVERIFY(session.state() == QNetworkSession::Connected); + QCOMPARE(session.state(), QNetworkSession::Connected); #ifndef QT_NO_NETWORKINTERFACE QVERIFY(session.interface().isValid()); if (errorSpy2.isEmpty()) { @@ -648,8 +651,8 @@ void tst_QNetworkSession::sessionOpenCloseStop() QNetworkSession::SessionError error2 = qvariant_cast<QNetworkSession::SessionError>(errorSpy2.first().at(0)); - QVERIFY(error == QNetworkSession::SessionAbortedError); - QVERIFY(error2 == QNetworkSession::SessionAbortedError); + QCOMPARE(error, QNetworkSession::SessionAbortedError); + QCOMPARE(error2, QNetworkSession::SessionAbortedError); QCOMPARE(errorSpy.count(), 1); QCOMPARE(errorSpy2.count(), 1); @@ -668,8 +671,8 @@ void tst_QNetworkSession::sessionOpenCloseStop() QTRY_VERIFY_WITH_TIMEOUT(stateChangedSpy2.count() >= 1 || !errorSpy2.isEmpty(), TestTimeOut); if (!errorSpy2.isEmpty()) { - QVERIFY(session2.state() == previousState); - QVERIFY(session.state() == previousState); + QCOMPARE(session2.state(), previousState); + QCOMPARE(session.state(), previousState); QNetworkSession::SessionError error = qvariant_cast<QNetworkSession::SessionError>(errorSpy2.first().at(0)); @@ -697,22 +700,22 @@ void tst_QNetworkSession::sessionOpenCloseStop() QNetworkSession::State state; if (stateChangedSpy2.count() == 4) { state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(0).at(0)); - QVERIFY(state == QNetworkSession::Connecting); + QCOMPARE(state, QNetworkSession::Connecting); state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(1).at(0)); - QVERIFY(state == QNetworkSession::Connected); + QCOMPARE(state, QNetworkSession::Connected); state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(2).at(0)); - QVERIFY(state == QNetworkSession::Closing); + QCOMPARE(state, QNetworkSession::Closing); state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(3).at(0)); - QVERIFY(state == QNetworkSession::Disconnected); + QCOMPARE(state, QNetworkSession::Disconnected); } else if (stateChangedSpy2.count() == 2) { state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(0).at(0)); - QVERIFY(state == QNetworkSession::Closing); + QCOMPARE(state, QNetworkSession::Closing); state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(1).at(0)); - QVERIFY(state == QNetworkSession::Disconnected); + QCOMPARE(state, QNetworkSession::Disconnected); } else { QFAIL("Unexpected amount of state changes when roaming."); } @@ -748,7 +751,7 @@ void tst_QNetworkSession::sessionOpenCloseStop() if (stateChangedSpy.count() > 1) { state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(stateChangedSpy.count() - 2).at(0)); - QVERIFY(state == QNetworkSession::Roaming); + QCOMPARE(state, QNetworkSession::Roaming); } roamedSuccessfully = true; } @@ -776,9 +779,9 @@ void tst_QNetworkSession::sessionOpenCloseStop() if (stateChangedSpy2.count() == 2) { QNetworkSession::State state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(0).at(0)); - QVERIFY(state == QNetworkSession::Closing); + QCOMPARE(state, QNetworkSession::Closing); state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(1).at(0)); - QVERIFY(state == QNetworkSession::Disconnected); + QCOMPARE(state, QNetworkSession::Disconnected); } else { QVERIFY(stateChangedSpy2.count() >= 1); @@ -791,7 +794,7 @@ void tst_QNetworkSession::sessionOpenCloseStop() QNetworkSession::State state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(stateChangedSpy2.count() - 1).at(0)); - QVERIFY(state == QNetworkSession::Disconnected); + QCOMPARE(state, QNetworkSession::Disconnected); } } @@ -818,14 +821,14 @@ void tst_QNetworkSession::sessionOpenCloseStop() session2.close(); QTRY_VERIFY_WITH_TIMEOUT(!sessionClosedSpy2.isEmpty(), TestTimeOut); - QVERIFY(stateChangedSpy2.count() == stateChangedCountBeforeClose); + QCOMPARE(stateChangedSpy2.count(), stateChangedCountBeforeClose); QVERIFY(sessionClosedSpy.isEmpty()); QVERIFY(session.isOpen()); QVERIFY(!session2.isOpen()); - QVERIFY(session.state() == QNetworkSession::Connected); - QVERIFY(session2.state() == QNetworkSession::Connected); + QCOMPARE(session.state(), QNetworkSession::Connected); + QCOMPARE(session2.state(), QNetworkSession::Connected); #ifndef QT_NO_NETWORKINTERFACE QVERIFY(session.interface().isValid()); QCOMPARE(session.interface().hardwareAddress(), session2.interface().hardwareAddress()); @@ -1233,7 +1236,7 @@ void tst_QNetworkSession::sessionAutoClose() QNetworkSession session(configuration); - QVERIFY(session.configuration() == configuration); + QCOMPARE(session.configuration(), configuration); QVariant autoCloseSession = session.sessionProperty(QLatin1String("AutoCloseSessionTimeout")); @@ -1259,7 +1262,7 @@ void tst_QNetworkSession::sessionAutoClose() QVERIFY(!session.isOpen()); - QVERIFY(session.configuration() == configuration); + QCOMPARE(session.configuration(), configuration); autoCloseSession = session.sessionProperty(QLatin1String("AutoCloseSessionTimeout")); diff --git a/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp b/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp index f6b7dfa3af52cdd2feb3a314768e5696b525c572..026a2a2722306c6f610e5d122230d03026c3658a 100644 --- a/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp +++ b/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp @@ -82,7 +82,7 @@ void tst_QAuthenticator::basicAuth() QAuthenticator auth; auth.detach(); QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(auth); - QVERIFY(priv->phase == QAuthenticatorPrivate::Start); + QCOMPARE(priv->phase, QAuthenticatorPrivate::Start); QList<QPair<QByteArray, QByteArray> > headers; headers << qMakePair<QByteArray, QByteArray>(QByteArray("WWW-Authenticate"), "Basic " + data.toUtf8()); @@ -94,7 +94,7 @@ void tst_QAuthenticator::basicAuth() auth.setUser(user); auth.setPassword(password); - QVERIFY(priv->phase == QAuthenticatorPrivate::Start); + QCOMPARE(priv->phase, QAuthenticatorPrivate::Start); QCOMPARE(priv->calculateResponse("GET", "/").constData(), QByteArray("Basic " + expectedReply).constData()); } @@ -125,7 +125,7 @@ void tst_QAuthenticator::ntlmAuth() auth.detach(); QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(auth); - QVERIFY(priv->phase == QAuthenticatorPrivate::Start); + QCOMPARE(priv->phase, QAuthenticatorPrivate::Start); QList<QPair<QByteArray, QByteArray> > headers; diff --git a/tests/auto/network/kernel/qhostaddress/qhostaddress.pro b/tests/auto/network/kernel/qhostaddress/qhostaddress.pro index 421685d8552069659a2d490bf2b724d9cbb691c6..f349cab976938bd34a884f1cb82df92ac01fc6ae 100644 --- a/tests/auto/network/kernel/qhostaddress/qhostaddress.pro +++ b/tests/auto/network/kernel/qhostaddress/qhostaddress.pro @@ -7,7 +7,7 @@ SOURCES += tst_qhostaddress.cpp QT = core network testlib win32: { -wince*: { +wince { LIBS += -lws2 } else { LIBS += -lws2_32 diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp index ef24cbf3c8d7d2c5907bed9e82052b024d64c860..e074ecae1d16327697a5dbf8e183d6ce02b25f64 100644 --- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp @@ -234,7 +234,7 @@ void tst_QHostAddress::setAddress_QString() QFETCH(int, protocol); QHostAddress hostAddr; - QVERIFY(hostAddr.setAddress(address) == ok); + QCOMPARE(hostAddr.setAddress(address), ok); if (ok) QTEST(hostAddr.toString(), "resAddr"); @@ -316,7 +316,7 @@ void tst_QHostAddress::compare_data() QTest::newRow("6") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << false; QTest::newRow("7") << QHostAddress() << QHostAddress(QHostAddress::LocalHostIPv6) << false; - Q_IPV6ADDR localhostv4mapped = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1 }; + Q_IPV6ADDR localhostv4mapped = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1 } }; QTest::newRow("v4-v4mapped") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("::ffff:127.0.0.1") << false; QTest::newRow("v4-v4mapped-2") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(localhostv4mapped) << false; } @@ -330,7 +330,7 @@ void tst_QHostAddress::compare() QCOMPARE(first == second, result); QCOMPARE(second == first, result); if (result == true) - QVERIFY(qHash(first) == qHash(second)); + QCOMPARE(qHash(first), qHash(second)); } void tst_QHostAddress::assignment() @@ -399,11 +399,11 @@ void tst_QHostAddress::streaming() QByteArray ba; QDataStream ds1(&ba, QIODevice::WriteOnly); ds1 << address; - QVERIFY(ds1.status() == QDataStream::Ok); + QCOMPARE(ds1.status(), QDataStream::Ok); QDataStream ds2(&ba, QIODevice::ReadOnly); QHostAddress address2; ds2 >> address2; - QVERIFY(ds2.status() == QDataStream::Ok); + QCOMPARE(ds2.status(), QDataStream::Ok); QCOMPARE(address, address2); } diff --git a/tests/auto/network/kernel/qhostinfo/qhostinfo.pro b/tests/auto/network/kernel/qhostinfo/qhostinfo.pro index 4fca7950dd3509bf167daa03e90b060eb85d1067..c9b795d0988ef68442b7f16d6888fc28bf9def78 100644 --- a/tests/auto/network/kernel/qhostinfo/qhostinfo.pro +++ b/tests/auto/network/kernel/qhostinfo/qhostinfo.pro @@ -6,7 +6,7 @@ SOURCES += tst_qhostinfo.cpp requires(contains(QT_CONFIG,private_tests)) QT = core-private network-private testlib -wince*: { +wince { LIBS += ws2.lib } else { win32:LIBS += -lws2_32 diff --git a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp index 599e475bebdf3011cb55cf9784a64813dfd8d0fd..5f0addba98b4eb39c137ba3feaeec6571ee2fde6 100644 --- a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp @@ -561,13 +561,13 @@ void tst_QHostInfo::cache() QHostInfo result = qt_qhostinfo_lookup("localhost", this, SLOT(resultsReady(QHostInfo)), &valid, &id); QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); - QVERIFY(valid == false); + QVERIFY(!valid); QVERIFY(result.addresses().isEmpty()); // loopkup second time, result should come directly valid = false; result = qt_qhostinfo_lookup("localhost", this, SLOT(resultsReady(QHostInfo)), &valid, &id); - QVERIFY(valid == true); + QVERIFY(valid); QVERIFY(!result.addresses().isEmpty()); // clear the cache @@ -578,7 +578,7 @@ void tst_QHostInfo::cache() result = qt_qhostinfo_lookup("localhost", this, SLOT(resultsReady(QHostInfo)), &valid, &id); QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); - QVERIFY(valid == false); + QVERIFY(!valid); QVERIFY(result.addresses().isEmpty()); // the slot should have been called 2 times. diff --git a/tests/auto/network/kernel/qnetworkaddressentry/tst_qnetworkaddressentry.cpp b/tests/auto/network/kernel/qnetworkaddressentry/tst_qnetworkaddressentry.cpp index d88b2e222c6d910465f9984d39dd318dc8f176ea..cca670e13a0e82d35ed1ca4943eaac03e4d94357 100644 --- a/tests/auto/network/kernel/qnetworkaddressentry/tst_qnetworkaddressentry.cpp +++ b/tests/auto/network/kernel/qnetworkaddressentry/tst_qnetworkaddressentry.cpp @@ -76,7 +76,7 @@ void tst_QNetworkAddressEntry::getSetCheck() entry = entry2; QCOMPARE(entry, entry2); - QVERIFY(entry == entry); + QCOMPARE(entry, entry); QVERIFY(!(entry != entry2)); } diff --git a/tests/auto/network/kernel/qnetworkinterface/BLACKLIST b/tests/auto/network/kernel/qnetworkinterface/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..23bb688d9a270e22183eec40df53b287f0c7ee0e --- /dev/null +++ b/tests/auto/network/kernel/qnetworkinterface/BLACKLIST @@ -0,0 +1,2 @@ +[localAddress] +linux diff --git a/tests/auto/network/socket/platformsocketengine/BLACKLIST b/tests/auto/network/socket/platformsocketengine/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..8e1a55995ee061d80a8c62a725bc30ab9974f154 --- /dev/null +++ b/tests/auto/network/socket/platformsocketengine/BLACKLIST @@ -0,0 +1 @@ +windows diff --git a/tests/auto/network/socket/platformsocketengine/platformsocketengine.pri b/tests/auto/network/socket/platformsocketengine/platformsocketengine.pri index 15f31fdbb54b688f1d1370d66849985bd11767e0..a3b4e894506569ef17023465a6798c5c204768b5 100644 --- a/tests/auto/network/socket/platformsocketengine/platformsocketengine.pri +++ b/tests/auto/network/socket/platformsocketengine/platformsocketengine.pri @@ -5,7 +5,7 @@ QNETWORK_SRC = $$QT_SOURCE_TREE/src/network INCLUDEPATH += $$QNETWORK_SRC win32 { - wince*: { + wince { LIBS += -lws2 } else { LIBS += -lws2_32 diff --git a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp index 9bd89cdf4f8e1d1453701733c1e59594101d140c..44081d474f59bac90805df4f1db19c2a680328be 100644 --- a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp +++ b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp @@ -130,18 +130,18 @@ void tst_PlatformSocketEngine::construction() // Initialize device QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); QVERIFY(socketDevice.isValid()); - QVERIFY(socketDevice.protocol() == QAbstractSocket::IPv4Protocol); - QVERIFY(socketDevice.socketType() == QAbstractSocket::TcpSocket); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.protocol(), QAbstractSocket::IPv4Protocol); + QCOMPARE(socketDevice.socketType(), QAbstractSocket::TcpSocket); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); QVERIFY(socketDevice.socketDescriptor() != -1); - QVERIFY(socketDevice.localAddress() == QHostAddress()); - QVERIFY(socketDevice.localPort() == 0); - QVERIFY(socketDevice.peerAddress() == QHostAddress()); - QVERIFY(socketDevice.peerPort() == 0); - QVERIFY(socketDevice.error() == QAbstractSocket::UnknownSocketError); + QCOMPARE(socketDevice.localAddress(), QHostAddress()); + QCOMPARE(socketDevice.localPort(), quint16(0)); + QCOMPARE(socketDevice.peerAddress(), QHostAddress()); + QCOMPARE(socketDevice.peerPort(), quint16(0)); + QCOMPARE(socketDevice.error(), QAbstractSocket::UnknownSocketError); QTest::ignoreMessage(QtWarningMsg, PLATFORMSOCKETENGINESTRING "::bytesAvailable() was called in QAbstractSocket::UnconnectedState"); - QVERIFY(socketDevice.bytesAvailable() == -1); + QCOMPARE(socketDevice.bytesAvailable(), -1); QTest::ignoreMessage(QtWarningMsg, PLATFORMSOCKETENGINESTRING "::hasPendingDatagrams() was called in QAbstractSocket::UnconnectedState"); QVERIFY(!socketDevice.hasPendingDatagrams()); @@ -154,16 +154,16 @@ void tst_PlatformSocketEngine::simpleConnectToIMAP() // Initialize device QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); const bool isConnected = socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143); if (!isConnected) { - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectingState); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); QVERIFY(socketDevice.waitForWrite()); - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState); } - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState); - QVERIFY(socketDevice.peerAddress() == QtNetworkSettings::serverIP()); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState); + QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::serverIP()); // Wait for the greeting QVERIFY(socketDevice.waitForRead()); @@ -200,8 +200,8 @@ void tst_PlatformSocketEngine::simpleConnectToIMAP() QVERIFY(socketDevice.waitForRead()); char c; QVERIFY(socketDevice.read(&c, sizeof(c)) == -1); - QVERIFY(socketDevice.error() == QAbstractSocket::RemoteHostClosedError); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.error(), QAbstractSocket::RemoteHostClosedError); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); } //--------------------------------------------------------------------------- @@ -213,13 +213,13 @@ void tst_PlatformSocketEngine::udpLoopbackTest() QVERIFY(udpSocket.initialize(QAbstractSocket::UdpSocket)); QVERIFY(udpSocket.isValid()); QVERIFY(udpSocket.socketDescriptor() != -1); - QVERIFY(udpSocket.protocol() == QAbstractSocket::IPv4Protocol); - QVERIFY(udpSocket.socketType() == QAbstractSocket::UdpSocket); - QVERIFY(udpSocket.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(udpSocket.protocol(), QAbstractSocket::IPv4Protocol); + QCOMPARE(udpSocket.socketType(), QAbstractSocket::UdpSocket); + QCOMPARE(udpSocket.state(), QAbstractSocket::UnconnectedState); // Bind #1 to localhost QVERIFY(udpSocket.bind(QHostAddress("127.0.0.1"), 0)); - QVERIFY(udpSocket.state() == QAbstractSocket::BoundState); + QCOMPARE(udpSocket.state(), QAbstractSocket::BoundState); quint16 port = udpSocket.localPort(); QVERIFY(port != 0); @@ -229,7 +229,7 @@ void tst_PlatformSocketEngine::udpLoopbackTest() // Connect device #2 to #1 QVERIFY(udpSocket2.connectToHost(QHostAddress("127.0.0.1"), port)); - QVERIFY(udpSocket2.state() == QAbstractSocket::ConnectedState); + QCOMPARE(udpSocket2.state(), QAbstractSocket::ConnectedState); // Write a message to #1 QByteArray message1 = "hei der"; @@ -248,7 +248,7 @@ void tst_PlatformSocketEngine::udpLoopbackTest() QVERIFY(udpSocket.readDatagram(answer.data(), answer.size(), &senderAddress, &senderPort) == message1.size()); - QVERIFY(senderAddress == QHostAddress("127.0.0.1")); + QCOMPARE(senderAddress, QHostAddress("127.0.0.1")); QVERIFY(senderPort != 0); } @@ -261,13 +261,13 @@ void tst_PlatformSocketEngine::udpIPv6LoopbackTest() bool init = udpSocket.initialize(QAbstractSocket::UdpSocket, QAbstractSocket::IPv6Protocol); if (!init) { - QVERIFY(udpSocket.error() == QAbstractSocket::UnsupportedSocketOperationError); + QCOMPARE(udpSocket.error(), QAbstractSocket::UnsupportedSocketOperationError); } else { - QVERIFY(udpSocket.protocol() == QAbstractSocket::IPv6Protocol); + QCOMPARE(udpSocket.protocol(), QAbstractSocket::IPv6Protocol); // Bind #1 to localhost QVERIFY(udpSocket.bind(QHostAddress("::1"), 0)); - QVERIFY(udpSocket.state() == QAbstractSocket::BoundState); + QCOMPARE(udpSocket.state(), QAbstractSocket::BoundState); quint16 port = udpSocket.localPort(); QVERIFY(port != 0); @@ -277,7 +277,7 @@ void tst_PlatformSocketEngine::udpIPv6LoopbackTest() // Connect device #2 to #1 QVERIFY(udpSocket2.connectToHost(QHostAddress("::1"), port)); - QVERIFY(udpSocket2.state() == QAbstractSocket::ConnectedState); + QCOMPARE(udpSocket2.state(), QAbstractSocket::ConnectedState); // Write a message to #1 QByteArray message1 = "hei der"; @@ -296,7 +296,7 @@ void tst_PlatformSocketEngine::udpIPv6LoopbackTest() QVERIFY(udpSocket.readDatagram(answer.data(), answer.size(), &senderAddress, &senderPort) == message1.size()); - QVERIFY(senderAddress == QHostAddress("::1")); + QCOMPARE(senderAddress, QHostAddress("::1")); QVERIFY(senderPort != 0); } } @@ -314,7 +314,7 @@ void tst_PlatformSocketEngine::broadcastTest() // Bind to any port on all interfaces QVERIFY(broadcastSocket.bind(QHostAddress::Any, 0)); - QVERIFY(broadcastSocket.state() == QAbstractSocket::BoundState); + QCOMPARE(broadcastSocket.state(), QAbstractSocket::BoundState); quint16 port = broadcastSocket.localPort(); QVERIFY(port > 0); @@ -354,20 +354,20 @@ void tst_PlatformSocketEngine::serverTest() // Bind to any port on all interfaces QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0)); - QVERIFY(server.state() == QAbstractSocket::BoundState); + QCOMPARE(server.state(), QAbstractSocket::BoundState); quint16 port = server.localPort(); // Listen for incoming connections QVERIFY(server.listen()); - QVERIFY(server.state() == QAbstractSocket::ListeningState); + QCOMPARE(server.state(), QAbstractSocket::ListeningState); // Initialize a Tcp socket PLATFORMSOCKETENGINE client; QVERIFY(client.initialize(QAbstractSocket::TcpSocket)); if (!client.connectToHost(QHostAddress("127.0.0.1"), port)) { - QVERIFY(client.state() == QAbstractSocket::ConnectingState); + QCOMPARE(client.state(), QAbstractSocket::ConnectingState); QVERIFY(client.waitForWrite()); - QVERIFY(client.state() == QAbstractSocket::ConnectedState); + QCOMPARE(client.state(), QAbstractSocket::ConnectedState); } // The server accepts the connection @@ -378,7 +378,7 @@ void tst_PlatformSocketEngine::serverTest() // socket descriptor from accept(). It's pre-connected. PLATFORMSOCKETENGINE serverSocket; QVERIFY(serverSocket.initialize(socketDescriptor)); - QVERIFY(serverSocket.state() == QAbstractSocket::ConnectedState); + QCOMPARE(serverSocket.state(), QAbstractSocket::ConnectedState); // The server socket sends a greeting to the clietn QByteArray greeting = "Greetings!"; @@ -407,13 +407,13 @@ void tst_PlatformSocketEngine::udpLoopbackPerformance() QVERIFY(udpSocket.initialize(QAbstractSocket::UdpSocket)); QVERIFY(udpSocket.isValid()); QVERIFY(udpSocket.socketDescriptor() != -1); - QVERIFY(udpSocket.protocol() == QAbstractSocket::IPv4Protocol); - QVERIFY(udpSocket.socketType() == QAbstractSocket::UdpSocket); - QVERIFY(udpSocket.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(udpSocket.protocol(), QAbstractSocket::IPv4Protocol); + QCOMPARE(udpSocket.socketType(), QAbstractSocket::UdpSocket); + QCOMPARE(udpSocket.state(), QAbstractSocket::UnconnectedState); // Bind #1 to localhost QVERIFY(udpSocket.bind(QHostAddress("127.0.0.1"), 0)); - QVERIFY(udpSocket.state() == QAbstractSocket::BoundState); + QCOMPARE(udpSocket.state(), QAbstractSocket::BoundState); quint16 port = udpSocket.localPort(); QVERIFY(port != 0); @@ -423,7 +423,7 @@ void tst_PlatformSocketEngine::udpLoopbackPerformance() // Connect device #2 to #1 QVERIFY(udpSocket2.connectToHost(QHostAddress("127.0.0.1"), port)); - QVERIFY(udpSocket2.state() == QAbstractSocket::ConnectedState); + QCOMPARE(udpSocket2.state(), QAbstractSocket::ConnectedState); const int messageSize = 8192; QByteArray message1(messageSize, '@'); @@ -459,12 +459,12 @@ void tst_PlatformSocketEngine::tcpLoopbackPerformance() // Bind to any port on all interfaces QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0)); - QVERIFY(server.state() == QAbstractSocket::BoundState); + QCOMPARE(server.state(), QAbstractSocket::BoundState); quint16 port = server.localPort(); // Listen for incoming connections QVERIFY(server.listen()); - QVERIFY(server.state() == QAbstractSocket::ListeningState); + QCOMPARE(server.state(), QAbstractSocket::ListeningState); // Initialize a Tcp socket PLATFORMSOCKETENGINE client; @@ -472,9 +472,9 @@ void tst_PlatformSocketEngine::tcpLoopbackPerformance() // Connect to our server if (!client.connectToHost(QHostAddress("127.0.0.1"), port)) { - QVERIFY(client.state() == QAbstractSocket::ConnectingState); + QCOMPARE(client.state(), QAbstractSocket::ConnectingState); QVERIFY(client.waitForWrite()); - QVERIFY(client.state() == QAbstractSocket::ConnectedState); + QCOMPARE(client.state(), QAbstractSocket::ConnectedState); } // The server accepts the connection @@ -485,7 +485,7 @@ void tst_PlatformSocketEngine::tcpLoopbackPerformance() // socket descriptor from accept(). It's pre-connected. PLATFORMSOCKETENGINE serverSocket; QVERIFY(serverSocket.initialize(socketDescriptor)); - QVERIFY(serverSocket.state() == QAbstractSocket::ConnectedState); + QCOMPARE(serverSocket.state(), QAbstractSocket::ConnectedState); const int messageSize = 1024 * 256; QByteArray message1(messageSize, '@'); @@ -562,7 +562,7 @@ void tst_PlatformSocketEngine::bind() PLATFORMSOCKETENGINE binder; QVERIFY(binder.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); QVERIFY(!binder.bind(QHostAddress::AnyIPv4, 82)); - QVERIFY(binder.error() == QAbstractSocket::SocketAccessError); + QCOMPARE(binder.error(), QAbstractSocket::SocketAccessError); #endif PLATFORMSOCKETENGINE binder2; @@ -572,7 +572,7 @@ void tst_PlatformSocketEngine::bind() PLATFORMSOCKETENGINE binder3; QVERIFY(binder3.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); QVERIFY(!binder3.bind(QHostAddress::AnyIPv4, 31180)); - QVERIFY(binder3.error() == QAbstractSocket::AddressInUseError); + QCOMPARE(binder3.error(), QAbstractSocket::AddressInUseError); if (QtNetworkSettings::hasIPv6()) { PLATFORMSOCKETENGINE binder4; @@ -582,7 +582,7 @@ void tst_PlatformSocketEngine::bind() PLATFORMSOCKETENGINE binder5; QVERIFY(binder5.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv6Protocol)); QVERIFY(!binder5.bind(QHostAddress::AnyIPv6, 31180)); - QVERIFY(binder5.error() == QAbstractSocket::AddressInUseError); + QCOMPARE(binder5.error(), QAbstractSocket::AddressInUseError); } PLATFORMSOCKETENGINE binder6; @@ -599,11 +599,11 @@ void tst_PlatformSocketEngine::networkError() const bool isConnected = client.connectToHost(QtNetworkSettings::serverIP(), 143); if (!isConnected) { - QVERIFY(client.state() == QAbstractSocket::ConnectingState); + QCOMPARE(client.state(), QAbstractSocket::ConnectingState); QVERIFY(client.waitForWrite()); - QVERIFY(client.state() == QAbstractSocket::ConnectedState); + QCOMPARE(client.state(), QAbstractSocket::ConnectedState); } - QVERIFY(client.state() == QAbstractSocket::ConnectedState); + QCOMPARE(client.state(), QAbstractSocket::ConnectedState); // An unexpected network error! #ifdef Q_OS_WINRT @@ -650,19 +650,19 @@ void tst_PlatformSocketEngine::receiveUrgentData() // Bind to any port on all interfaces QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0)); - QVERIFY(server.state() == QAbstractSocket::BoundState); + QCOMPARE(server.state(), QAbstractSocket::BoundState); quint16 port = server.localPort(); QVERIFY(server.listen()); - QVERIFY(server.state() == QAbstractSocket::ListeningState); + QCOMPARE(server.state(), QAbstractSocket::ListeningState); PLATFORMSOCKETENGINE client; QVERIFY(client.initialize(QAbstractSocket::TcpSocket)); if (!client.connectToHost(QHostAddress("127.0.0.1"), port)) { - QVERIFY(client.state() == QAbstractSocket::ConnectingState); + QCOMPARE(client.state(), QAbstractSocket::ConnectingState); QVERIFY(client.waitForWrite()); - QVERIFY(client.state() == QAbstractSocket::ConnectedState); + QCOMPARE(client.state(), QAbstractSocket::ConnectedState); } int socketDescriptor = server.accept(); @@ -670,7 +670,7 @@ void tst_PlatformSocketEngine::receiveUrgentData() PLATFORMSOCKETENGINE serverSocket; QVERIFY(serverSocket.initialize(socketDescriptor)); - QVERIFY(serverSocket.state() == QAbstractSocket::ConnectedState); + QCOMPARE(serverSocket.state(), QAbstractSocket::ConnectedState); char msg; int available; diff --git a/tests/auto/network/socket/qhttpsocketengine/BLACKLIST b/tests/auto/network/socket/qhttpsocketengine/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..8e1a55995ee061d80a8c62a725bc30ab9974f154 --- /dev/null +++ b/tests/auto/network/socket/qhttpsocketengine/BLACKLIST @@ -0,0 +1 @@ +windows diff --git a/tests/auto/network/socket/qhttpsocketengine/tst_qhttpsocketengine.cpp b/tests/auto/network/socket/qhttpsocketengine/tst_qhttpsocketengine.cpp index 10e8c95fc01ed732c56b920752048622a2364e60..179cdb76bc06e4ee8a6b4ba8da69953eeea5c854 100644 --- a/tests/auto/network/socket/qhttpsocketengine/tst_qhttpsocketengine.cpp +++ b/tests/auto/network/socket/qhttpsocketengine/tst_qhttpsocketengine.cpp @@ -164,18 +164,18 @@ void tst_QHttpSocketEngine::construction() // Initialize device QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); QVERIFY(socketDevice.isValid()); - QVERIFY(socketDevice.protocol() == QAbstractSocket::IPv4Protocol); - QVERIFY(socketDevice.socketType() == QAbstractSocket::TcpSocket); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.protocol(), QAbstractSocket::IPv4Protocol); + QCOMPARE(socketDevice.socketType(), QAbstractSocket::TcpSocket); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); // QVERIFY(socketDevice.socketDescriptor() != -1); - QVERIFY(socketDevice.localAddress() == QHostAddress()); - QVERIFY(socketDevice.localPort() == 0); - QVERIFY(socketDevice.peerAddress() == QHostAddress()); - QVERIFY(socketDevice.peerPort() == 0); - QVERIFY(socketDevice.error() == QAbstractSocket::UnknownSocketError); + QCOMPARE(socketDevice.localAddress(), QHostAddress()); + QCOMPARE(socketDevice.localPort(), quint16(0)); + QCOMPARE(socketDevice.peerAddress(), QHostAddress()); + QCOMPARE(socketDevice.peerPort(), quint16(0)); + QCOMPARE(socketDevice.error(), QAbstractSocket::UnknownSocketError); //QTest::ignoreMessage(QtWarningMsg, "QSocketLayer::bytesAvailable() was called in QAbstractSocket::UnconnectedState"); - QVERIFY(socketDevice.bytesAvailable() == 0); + QCOMPARE(socketDevice.bytesAvailable(), 0); //QTest::ignoreMessage(QtWarningMsg, "QSocketLayer::hasPendingDatagrams() was called in QAbstractSocket::UnconnectedState"); QVERIFY(!socketDevice.hasPendingDatagrams()); @@ -299,15 +299,15 @@ void tst_QHttpSocketEngine::simpleConnectToIMAP() // Initialize device QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128)); QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143)); - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectingState); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); QVERIFY(socketDevice.waitForWrite()); - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState); - QVERIFY(socketDevice.peerAddress() == QtNetworkSettings::serverIP()); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState); + QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::serverIP()); QVERIFY(!socketDevice.localAddress().isNull()); QVERIFY(socketDevice.localPort() > 0); @@ -345,8 +345,8 @@ void tst_QHttpSocketEngine::simpleConnectToIMAP() QVERIFY(socketDevice.waitForRead()); char c; QCOMPARE(socketDevice.read(&c, sizeof(c)), (qint64) -1); - QVERIFY(socketDevice.error() == QAbstractSocket::RemoteHostClosedError); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.error(), QAbstractSocket::RemoteHostClosedError); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); } //--------------------------------------------------------------------------- @@ -360,14 +360,14 @@ void tst_QHttpSocketEngine::simpleErrorsAndStates() socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128)); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); QVERIFY(!socketDevice.connectToHost(QHostAddress(QtNetworkSettings::serverName()), 8088)); - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectingState); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); if (socketDevice.waitForWrite(30000)) { QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState || socketDevice.state() == QAbstractSocket::UnconnectedState); } else { - QVERIFY(socketDevice.error() == QAbstractSocket::SocketTimeoutError); + QCOMPARE(socketDevice.error(), QAbstractSocket::SocketTimeoutError); } } @@ -381,12 +381,12 @@ void tst_QHttpSocketEngine::tcpLoopbackPerformance() // Bind to any port on all interfaces QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0)); - QVERIFY(server.state() == QAbstractSocket::BoundState); + QCOMPARE(server.state(), QAbstractSocket::BoundState); quint16 port = server.localPort(); // Listen for incoming connections QVERIFY(server.listen()); - QVERIFY(server.state() == QAbstractSocket::ListeningState); + QCOMPARE(server.state(), QAbstractSocket::ListeningState); // Initialize a Tcp socket QHttpSocketEngine client; @@ -408,7 +408,7 @@ void tst_QHttpSocketEngine::tcpLoopbackPerformance() // socket descriptor from accept(). It's pre-connected. QSocketLayer serverSocket; QVERIFY(serverSocket.initialize(socketDescriptor)); - QVERIFY(serverSocket.state() == QAbstractSocket::ConnectedState); + QCOMPARE(serverSocket.state(), QAbstractSocket::ConnectedState); const int messageSize = 1024 * 256; QByteArray message1(messageSize, '@'); @@ -544,7 +544,7 @@ void tst_QHttpSocketEngine::tcpSocketNonBlockingTest() QFAIL("Timed out"); } - QVERIFY(tcpSocketNonBlocking_totalWritten == 8); + QCOMPARE(tcpSocketNonBlocking_totalWritten, 8); QTestEventLoop::instance().enterLoop(30); @@ -569,7 +569,7 @@ void tst_QHttpSocketEngine::tcpSocketNonBlockingTest() QFAIL("Timed out"); } - QVERIFY(tcpSocketNonBlocking_totalWritten == 10); + QCOMPARE(tcpSocketNonBlocking_totalWritten, 10); // Wait for greeting QTestEventLoop::instance().enterLoop(30); @@ -637,7 +637,7 @@ void tst_QHttpSocketEngine::downloadBigFile() QFAIL("Network operation timed out"); QByteArray hostName = QtNetworkSettings::serverName().toLatin1(); - QVERIFY(tmpSocket->state() == QAbstractSocket::ConnectedState); + QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState); QVERIFY(tmpSocket->write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0); QVERIFY(tmpSocket->write("Host: ") > 0); QVERIFY(tmpSocket->write(hostName.data()) > 0); @@ -659,7 +659,7 @@ void tst_QHttpSocketEngine::downloadBigFile() QVERIFY(bytesAvailable >= 10000000); - QVERIFY(tmpSocket->state() == QAbstractSocket::ConnectedState); + QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState); qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s", bytesAvailable / (1024.0 * 1024.0), @@ -689,15 +689,15 @@ void tst_QHttpSocketEngine::passwordAuth() // Initialize device QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128, "qsockstest", "password")); QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143)); - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectingState); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); QVERIFY(socketDevice.waitForWrite()); - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState); - QVERIFY(socketDevice.peerAddress() == QtNetworkSettings::serverIP()); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState); + QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::serverIP()); // Wait for the greeting QVERIFY(socketDevice.waitForRead()); @@ -733,8 +733,8 @@ void tst_QHttpSocketEngine::passwordAuth() QVERIFY(socketDevice.waitForRead()); char c; QVERIFY(socketDevice.read(&c, sizeof(c)) == -1); - QVERIFY(socketDevice.error() == QAbstractSocket::RemoteHostClosedError); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.error(), QAbstractSocket::RemoteHostClosedError); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); } //---------------------------------------------------------------------------------- diff --git a/tests/auto/network/socket/qlocalsocket/BLACKLIST b/tests/auto/network/socket/qlocalsocket/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..11ddef30a589284e0f0ab7b77e0f5f5bf0f11cd4 --- /dev/null +++ b/tests/auto/network/socket/qlocalsocket/BLACKLIST @@ -0,0 +1,2 @@ +[processConnection:1 client] +windows diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp index 4881d869371340dfbeed72bab65161c648ceea73..847e065aa8b5d2e76aad31e77c16f12e7d69a17b 100644 --- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp @@ -246,8 +246,8 @@ void tst_QLocalSocket::socket_basic() QCOMPARE(socket.serverName(), QString()); QCOMPARE(socket.fullServerName(), QString()); socket.abort(); - QVERIFY(socket.bytesAvailable() == 0); - QVERIFY(socket.bytesToWrite() == 0); + QCOMPARE(socket.bytesAvailable(), 0); + QCOMPARE(socket.bytesToWrite(), 0); QCOMPARE(socket.canReadLine(), false); socket.close(); socket.disconnectFromServer(); @@ -255,7 +255,7 @@ void tst_QLocalSocket::socket_basic() QVERIFY(!socket.errorString().isEmpty()); QCOMPARE(socket.flush(), false); QCOMPARE(socket.isValid(), false); - QVERIFY(socket.readBufferSize() == 0); + QCOMPARE(socket.readBufferSize(), 0); socket.setReadBufferSize(0); //QCOMPARE(socket.socketDescriptor(), (qintptr)-1); QCOMPARE(socket.state(), QLocalSocket::UnconnectedState); @@ -375,13 +375,13 @@ void tst_QLocalSocket::listenAndConnect() QVERIFY(!socket->errorString().isEmpty()); QVERIFY(socket->error() != QLocalSocket::UnknownSocketError); QCOMPARE(socket->state(), QLocalSocket::UnconnectedState); - //QVERIFY(socket->socketDescriptor() == -1); + //QCOMPARE(socket->socketDescriptor(), -1); QCOMPARE(qvariant_cast<QLocalSocket::LocalSocketError>(spyError.first()[0]), QLocalSocket::ServerNotFoundError); } - QVERIFY(socket->bytesAvailable() == 0); - QVERIFY(socket->bytesToWrite() == 0); + QCOMPARE(socket->bytesAvailable(), 0); + QCOMPARE(socket->bytesToWrite(), 0); QCOMPARE(socket->canReadLine(), false); QCOMPARE(socket->flush(), false); QCOMPARE(socket->isValid(), canListen); @@ -432,7 +432,7 @@ void tst_QLocalSocket::listenAndConnect() } else { QVERIFY(server.serverName().isEmpty()); QVERIFY(server.fullServerName().isEmpty()); - QVERIFY(server.nextPendingConnection() == (QLocalSocket*)0); + QCOMPARE(server.nextPendingConnection(), (QLocalSocket*)0); QCOMPARE(spyNewConnection.count(), 0); QCOMPARE(server.hits.count(), 0); QVERIFY(!server.errorString().isEmpty()); @@ -616,7 +616,7 @@ void tst_QLocalSocket::readBufferOverflow() QVERIFY(client.waitForReadyRead()); QCOMPARE(client.read(buffer, readBufferSize), qint64(readBufferSize)); // no more bytes available - QVERIFY(client.bytesAvailable() == 0); + QCOMPARE(client.bytesAvailable(), 0); } // QLocalSocket/Server can take a name or path, check that it works as expected @@ -912,7 +912,7 @@ void tst_QLocalSocket::waitForDisconnectByServer() QLocalSocket *serverSocket = server.nextPendingConnection(); QVERIFY(serverSocket); serverSocket->close(); - QVERIFY(serverSocket->state() == QLocalSocket::UnconnectedState); + QCOMPARE(serverSocket->state(), QLocalSocket::UnconnectedState); QVERIFY(socket.waitForDisconnected(3000)); QCOMPARE(spy.count(), 1); } @@ -1197,11 +1197,12 @@ void tst_QLocalSocket::verifyListenWithDescriptor() QVERIFY2(server.listen(listenSocket), "failed to start create QLocalServer with local socket"); #ifdef Q_OS_LINUX + const QChar at(QLatin1Char('@')); if (!bound) { - QVERIFY(server.serverName().at(0) == QLatin1Char('@')); - QVERIFY(server.fullServerName().at(0) == QLatin1Char('@')); + QCOMPARE(server.serverName().at(0), at); + QCOMPARE(server.fullServerName().at(0), at); } else if (abstract) { - QVERIFY2(server.fullServerName().at(0) == QLatin1Char('@'), "abstract sockets should start with a '@'"); + QVERIFY2(server.fullServerName().at(0) == at, "abstract sockets should start with a '@'"); } else { QCOMPARE(server.fullServerName(), path); if (path.contains(QLatin1String("/"))) { diff --git a/tests/auto/network/socket/qsocks5socketengine/BLACKLIST b/tests/auto/network/socket/qsocks5socketengine/BLACKLIST index bf4afa8c450c06715a5ad929c912d26e529de13d..2a32a326d0700cff50718de824795717f4523c30 100644 --- a/tests/auto/network/socket/qsocks5socketengine/BLACKLIST +++ b/tests/auto/network/socket/qsocks5socketengine/BLACKLIST @@ -2,3 +2,5 @@ * [passwordAuth] * +[serverTest] +windows diff --git a/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp b/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp index 0ae9887773018c74ebddbb5309bb5a68e76a9f72..66fd74017eb87048d52c456bc3c5bf86289dc990 100644 --- a/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp +++ b/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp @@ -193,18 +193,18 @@ void tst_QSocks5SocketEngine::construction() // Initialize device QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); QVERIFY(socketDevice.isValid()); - QVERIFY(socketDevice.protocol() == QAbstractSocket::IPv4Protocol); - QVERIFY(socketDevice.socketType() == QAbstractSocket::TcpSocket); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.protocol(), QAbstractSocket::IPv4Protocol); + QCOMPARE(socketDevice.socketType(), QAbstractSocket::TcpSocket); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); // QVERIFY(socketDevice.socketDescriptor() != -1); - QVERIFY(socketDevice.localAddress() == QHostAddress()); - QVERIFY(socketDevice.localPort() == 0); - QVERIFY(socketDevice.peerAddress() == QHostAddress()); - QVERIFY(socketDevice.peerPort() == 0); - QVERIFY(socketDevice.error() == QAbstractSocket::UnknownSocketError); + QCOMPARE(socketDevice.localAddress(), QHostAddress()); + QCOMPARE(socketDevice.localPort(), quint16(0)); + QCOMPARE(socketDevice.peerAddress(), QHostAddress()); + QCOMPARE(socketDevice.peerPort(), quint16(0)); + QCOMPARE(socketDevice.error(), QAbstractSocket::UnknownSocketError); //QTest::ignoreMessage(QtWarningMsg, "QSocketLayer::bytesAvailable() was called in QAbstractSocket::UnconnectedState"); - QVERIFY(socketDevice.bytesAvailable() == 0); + QCOMPARE(socketDevice.bytesAvailable(), 0); //QTest::ignoreMessage(QtWarningMsg, "QSocketLayer::hasPendingDatagrams() was called in QAbstractSocket::UnconnectedState"); QVERIFY(!socketDevice.hasPendingDatagrams()); @@ -334,15 +334,15 @@ void tst_QSocks5SocketEngine::simpleConnectToIMAP() // Initialize device QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); socketDevice.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080)); QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143)); - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectingState); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); QVERIFY(socketDevice.waitForWrite()); - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState); - QVERIFY(socketDevice.peerAddress() == QtNetworkSettings::serverIP()); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState); + QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::serverIP()); // Wait for the greeting QVERIFY(socketDevice.waitForRead()); @@ -377,8 +377,8 @@ void tst_QSocks5SocketEngine::simpleConnectToIMAP() QVERIFY(socketDevice.waitForRead()); char c; QVERIFY(socketDevice.read(&c, sizeof(c)) == -1); - QVERIFY(socketDevice.error() == QAbstractSocket::RemoteHostClosedError); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.error(), QAbstractSocket::RemoteHostClosedError); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); } //--------------------------------------------------------------------------- @@ -392,14 +392,14 @@ void tst_QSocks5SocketEngine::simpleErrorsAndStates() socketDevice.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080)); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); QVERIFY(!socketDevice.connectToHost(QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first(), 8088)); - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectingState); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); if (socketDevice.waitForWrite(15000)) { QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState || socketDevice.state() == QAbstractSocket::ConnectedState); } else { - QVERIFY(socketDevice.error() == QAbstractSocket::SocketTimeoutError); + QCOMPARE(socketDevice.error(), QAbstractSocket::SocketTimeoutError); } } @@ -413,12 +413,12 @@ void tst_QSocks5SocketEngine::tcpLoopbackPerformance() // Bind to any port on all interfaces QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0)); - QVERIFY(server.state() == QAbstractSocket::BoundState); + QCOMPARE(server.state(), QAbstractSocket::BoundState); quint16 port = server.localPort(); // Listen for incoming connections QVERIFY(server.listen()); - QVERIFY(server.state() == QAbstractSocket::ListeningState); + QCOMPARE(server.state(), QAbstractSocket::ListeningState); // Initialize a Tcp socket QSocks5SocketEngine client; @@ -440,7 +440,7 @@ void tst_QSocks5SocketEngine::tcpLoopbackPerformance() // socket descriptor from accept(). It's pre-connected. QSocketLayer serverSocket; QVERIFY(serverSocket.initialize(socketDescriptor)); - QVERIFY(serverSocket.state() == QAbstractSocket::ConnectedState); + QCOMPARE(serverSocket.state(), QAbstractSocket::ConnectedState); const int messageSize = 1024 * 256; QByteArray message1(messageSize, '@'); @@ -482,11 +482,11 @@ void tst_QSocks5SocketEngine::serverTest() // Bind to any port on all interfaces QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0)); - QVERIFY(server.state() == QAbstractSocket::BoundState); + QCOMPARE(server.state(), QAbstractSocket::BoundState); // Listen for incoming connections QVERIFY(server.listen()); - QVERIFY(server.state() == QAbstractSocket::ListeningState); + QCOMPARE(server.state(), QAbstractSocket::ListeningState); // Initialize a Tcp socket QSocks5SocketEngine client; @@ -501,7 +501,7 @@ void tst_QSocks5SocketEngine::serverTest() if (!client.connectToHost(server.localAddress(), server.localPort())) { QVERIFY(client.waitForWrite()); // QTest::wait(100); // ### timing problem on win32 - QVERIFY(client.state() == QAbstractSocket::ConnectedState); + QCOMPARE(client.state(), QAbstractSocket::ConnectedState); //QTest::wait(100); } @@ -516,14 +516,14 @@ void tst_QSocks5SocketEngine::serverTest() QSocks5SocketEngine serverSocket; QVERIFY(serverSocket.initialize(socketDescriptor)); - QVERIFY(serverSocket.state() == QAbstractSocket::ConnectedState); + QCOMPARE(serverSocket.state(), QAbstractSocket::ConnectedState); - QVERIFY(serverSocket.localAddress() == client.peerAddress()); - QVERIFY(serverSocket.localPort() == client.peerPort()); + QCOMPARE(serverSocket.localAddress(), client.peerAddress()); + QCOMPARE(serverSocket.localPort(), client.peerPort()); // this seems depends on the socks server implementation, especially // when connecting /to/ the socks server /through/ the same socks server - //QVERIFY(serverSocket.peerAddress() == client.localAddress()); - //QVERIFY(serverSocket.peerPort() == client.localPort()); + //QCOMPARE(serverSocket.peerAddress(), client.localAddress()); + //QCOMPARE(serverSocket.peerPort(), client.localPort()); // The server socket sends a greeting to the client QByteArray greeting = "Greetings!"; @@ -557,16 +557,16 @@ void tst_QSocks5SocketEngine::udpTest() udpSocket.setProxy(proxy); - QVERIFY(udpSocket.protocol() == QAbstractSocket::IPv4Protocol); - QVERIFY(udpSocket.socketType() == QAbstractSocket::UdpSocket); - QVERIFY(udpSocket.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(udpSocket.protocol(), QAbstractSocket::IPv4Protocol); + QCOMPARE(udpSocket.socketType(), QAbstractSocket::UdpSocket); + QCOMPARE(udpSocket.state(), QAbstractSocket::UnconnectedState); // Bind #1 bool bindSuccessful = udpSocket.bind(QHostAddress("0.0.0.0"), 0); if (!bindSuccessful) QEXPECT_FAIL("", "QTBUG-23380 / QTBUG-35490: Fails on some Ubuntu 11.10 x64 configurations and on new network test server", Abort); QVERIFY(bindSuccessful); - QVERIFY(udpSocket.state() == QAbstractSocket::BoundState); + QCOMPARE(udpSocket.state(), QAbstractSocket::BoundState); QVERIFY(udpSocket.localPort() != 0); // Initialize device #2 @@ -577,7 +577,7 @@ void tst_QSocks5SocketEngine::udpTest() // Connect device #2 to #1 QVERIFY(udpSocket2.connectToHost(udpSocket.localAddress(), udpSocket.localPort())); - QVERIFY(udpSocket2.state() == QAbstractSocket::ConnectedState); + QCOMPARE(udpSocket2.state(), QAbstractSocket::ConnectedState); // Write a message to #1 QByteArray message1 = "hei der"; @@ -596,8 +596,8 @@ void tst_QSocks5SocketEngine::udpTest() QVERIFY(udpSocket.readDatagram(answer.data(), answer.size(), &senderAddress, &senderPort) == message1.size()); - QVERIFY(senderAddress == udpSocket2.localAddress()); - QVERIFY(senderPort == udpSocket2.localPort()); + QCOMPARE(senderAddress, udpSocket2.localAddress()); + QCOMPARE(senderPort, udpSocket2.localPort()); } void tst_QSocks5SocketEngine::tcpSocketBlockingTest() @@ -705,7 +705,7 @@ void tst_QSocks5SocketEngine::tcpSocketNonBlockingTest() QFAIL("Timed out"); } - QVERIFY(tcpSocketNonBlocking_totalWritten == 8); + QCOMPARE(tcpSocketNonBlocking_totalWritten, 8); QTestEventLoop::instance().enterLoop(30); @@ -729,7 +729,7 @@ void tst_QSocks5SocketEngine::tcpSocketNonBlockingTest() QFAIL("Timed out"); } - QVERIFY(tcpSocketNonBlocking_totalWritten == 10); + QCOMPARE(tcpSocketNonBlocking_totalWritten, 10); // Wait for greeting QTestEventLoop::instance().enterLoop(30); @@ -797,7 +797,7 @@ void tst_QSocks5SocketEngine::downloadBigFile() QFAIL("Network operation timed out"); QByteArray hostName = QtNetworkSettings::serverName().toLatin1(); - QVERIFY(tmpSocket->state() == QAbstractSocket::ConnectedState); + QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState); QVERIFY(tmpSocket->write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0); QVERIFY(tmpSocket->write("HOST: ") > 0); QVERIFY(tmpSocket->write(hostName.data()) > 0); @@ -819,7 +819,7 @@ void tst_QSocks5SocketEngine::downloadBigFile() QCOMPARE(bytesAvailable, qint64(10000000)); - QVERIFY(tmpSocket->state() == QAbstractSocket::ConnectedState); + QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState); /*qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s", bytesAvailable / (1024.0 * 1024.0), @@ -852,19 +852,19 @@ void tst_QSocks5SocketEngine::passwordAuth() // Initialize device QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); socketDevice.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080, "qsockstest", "password")); // Connect to imap.trolltech.com's IP QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143)); - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectingState); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); QVERIFY(socketDevice.waitForWrite()); if (!socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143)) { qDebug("%d, %s", socketDevice.error(), socketDevice.errorString().toLatin1().constData()); } - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState); - QVERIFY(socketDevice.peerAddress() == QtNetworkSettings::serverIP()); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState); + QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::serverIP()); // Wait for the greeting QVERIFY(socketDevice.waitForRead()); @@ -899,8 +899,8 @@ void tst_QSocks5SocketEngine::passwordAuth() QVERIFY(socketDevice.waitForRead()); char c; QVERIFY(socketDevice.read(&c, sizeof(c)) == -1); - QVERIFY(socketDevice.error() == QAbstractSocket::RemoteHostClosedError); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.error(), QAbstractSocket::RemoteHostClosedError); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); } //---------------------------------------------------------------------------------- @@ -918,21 +918,21 @@ void tst_QSocks5SocketEngine::passwordAuth2() // Initialize device QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); socketDevice.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081)); socketDevice.setReceiver(this); QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143)); - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectingState); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); while (socketDevice.state() == QAbstractSocket::ConnectingState) { QVERIFY(socketDevice.waitForWrite()); socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143); } if (socketDevice.state() != QAbstractSocket::ConnectedState) qDebug("%d, %s", socketDevice.error(), socketDevice.errorString().toLatin1().constData()); - QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState); - QVERIFY(socketDevice.peerAddress() == QtNetworkSettings::serverIP()); + QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState); + QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::serverIP()); // Wait for the greeting QVERIFY(socketDevice.waitForRead()); @@ -967,8 +967,8 @@ void tst_QSocks5SocketEngine::passwordAuth2() QVERIFY(socketDevice.waitForRead()); char c; QVERIFY(socketDevice.read(&c, sizeof(c)) == -1); - QVERIFY(socketDevice.error() == QAbstractSocket::RemoteHostClosedError); - QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socketDevice.error(), QAbstractSocket::RemoteHostClosedError); + QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); } void tst_QSocks5SocketEngine::fragmentation_data() @@ -1017,7 +1017,7 @@ void tst_QSocks5SocketEngine::fragmentation() QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(socket.localAddress() == QHostAddress("1.2.3.4") || socket.localAddress() == QHostAddress("0123:4567:89ab:cdef:0123:4567:89ab:cdef")); - QVERIFY(socket.localPort() == 0x0506); + QCOMPARE(socket.localPort(), quint16(0x0506)); } void tst_QSocks5SocketEngine::incomplete_data() diff --git a/tests/auto/network/socket/qtcpserver/BLACKLIST b/tests/auto/network/socket/qtcpserver/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..f8b61808cc5a7ee1de25311328ec37a304da7e16 --- /dev/null +++ b/tests/auto/network/socket/qtcpserver/BLACKLIST @@ -0,0 +1,13 @@ +windows +[linkLocal] +linux +[listenWhileListening:WithSocks5Proxy] +linux +windows +[ipv6Server:WithoutProxy] +windows +osx +[clientServerLoop:WithSocks5Proxy] +linux +[crashTests:WithSocks5Proxy] +linux diff --git a/tests/auto/network/socket/qtcpserver/test/test.pro b/tests/auto/network/socket/qtcpserver/test/test.pro index 4daa9963ce7267a87b5b309948bb285a96929800..f0abfbc085503c6c7d9e339e32c08e7d9da336ad 100644 --- a/tests/auto/network/socket/qtcpserver/test/test.pro +++ b/tests/auto/network/socket/qtcpserver/test/test.pro @@ -2,7 +2,7 @@ CONFIG += testcase SOURCES += ../tst_qtcpserver.cpp win32: { -wince*: { +wince { LIBS += -lws2 crashApp.files = ../crashingServer/crashingServer.exe crashApp.path = crashingServer diff --git a/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp b/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp index e0a6e3699d0774fe99a1d5552a3ce89a9cacc158..5df5432cdd830bb0c0a2ad3ad00738aa7c65c93d 100644 --- a/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp +++ b/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp @@ -265,11 +265,11 @@ void tst_QTcpServer::ipv6Server() //### need to enter the event loop for the server to get the connection ?? ( windows) QTcpServer server; if (!server.listen(QHostAddress::LocalHostIPv6, 8944)) { - QVERIFY(server.serverError() == QAbstractSocket::UnsupportedSocketOperationError); + QCOMPARE(server.serverError(), QAbstractSocket::UnsupportedSocketOperationError); return; } - QVERIFY(server.serverPort() == 8944); + QCOMPARE(server.serverPort(), quint16(8944)); QVERIFY(server.serverAddress() == QHostAddress::LocalHostIPv6); QTcpSocket client; @@ -835,17 +835,17 @@ void tst_QTcpServer::qtbug14268_peek() client.write("abc\n"); QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); - QVERIFY(helper.lastDataPeeked == QByteArray("6162630a")); + QCOMPARE(helper.lastDataPeeked, QByteArray("6162630a")); client.write("def\n"); QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); - QVERIFY(helper.lastDataPeeked == QByteArray("6162630a6465660a")); + QCOMPARE(helper.lastDataPeeked, QByteArray("6162630a6465660a")); client.write("ghi\n"); QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); - QVERIFY(helper.lastDataPeeked == QByteArray("6162630a6465660a6768690a")); + QCOMPARE(helper.lastDataPeeked, QByteArray("6162630a6465660a6768690a")); } void tst_QTcpServer::serverAddress_data() diff --git a/tests/auto/network/socket/qtcpsocket/qtcpsocket.pro b/tests/auto/network/socket/qtcpsocket/qtcpsocket.pro index 347359f508f1ab5cab97b8f803bd55b2de87baec..fe6042b8a7d22008d8d973860c71a6be0750e30c 100644 --- a/tests/auto/network/socket/qtcpsocket/qtcpsocket.pro +++ b/tests/auto/network/socket/qtcpsocket/qtcpsocket.pro @@ -1,7 +1,6 @@ TEMPLATE = subdirs - -!wince*: SUBDIRS = test stressTest -wince*|vxworks* : SUBDIRS = test +SUBDIRS = test +!wince:!vxworks: SUBDIRS += stressTest requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/network/socket/qtcpsocket/test/test.pro b/tests/auto/network/socket/qtcpsocket/test/test.pro index 6c6697bfdc35d709893377cfd6541231089ee7fd..325abcaab8156b8ad17404174a87bb40c6447b03 100644 --- a/tests/auto/network/socket/qtcpsocket/test/test.pro +++ b/tests/auto/network/socket/qtcpsocket/test/test.pro @@ -3,7 +3,7 @@ CONFIG += testcase QT = core-private network-private testlib SOURCES += ../tst_qtcpsocket.cpp win32: { -wince*: { +wince { LIBS += -lws2 } else { LIBS += -lws2_32 @@ -21,3 +21,5 @@ win32 { } else { DESTDIR = ../ } + +win32: CONFIG += insignificant_test # Hangs in release builds diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 109e48ed7419c2487437ec33fb81dbe0b7685493..abbc560414d241aea1ab2b22975695b214818b8a 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -242,7 +242,6 @@ private: mutable int proxyAuthCalled; - int numConnections; static int loopLevel; SocketPair *earlyConstructedSockets; @@ -484,9 +483,9 @@ void tst_QTcpSocket::constructing() QCOMPARE(socket->readLine(), QByteArray()); QCOMPARE(socket->socketDescriptor(), (qintptr)-1); QCOMPARE((int) socket->localPort(), 0); - QVERIFY(socket->localAddress() == QHostAddress()); + QCOMPARE(socket->localAddress(), QHostAddress()); QCOMPARE((int) socket->peerPort(), 0); - QVERIFY(socket->peerAddress() == QHostAddress()); + QCOMPARE(socket->peerAddress(), QHostAddress()); QCOMPARE(socket->error(), QTcpSocket::UnknownSocketError); QCOMPARE(socket->errorString(), QString("Unknown error")); @@ -756,7 +755,7 @@ void tst_QTcpSocket::socketDescriptor() QVERIFY(socket->state() == QAbstractSocket::HostLookupState || socket->state() == QAbstractSocket::ConnectingState); QVERIFY(socket->waitForConnected(10000)); - QVERIFY(socket->state() == QAbstractSocket::ConnectedState); + QCOMPARE(socket->state(), QAbstractSocket::ConnectedState); QVERIFY(socket->socketDescriptor() != -1); delete socket; @@ -937,7 +936,7 @@ void tst_QTcpSocket::nonBlockingIMAP() QFAIL("Timed out"); } - QVERIFY(nonBlockingIMAP_totalWritten == 8); + QCOMPARE(nonBlockingIMAP_totalWritten, 8); enterLoop(30); @@ -962,7 +961,7 @@ void tst_QTcpSocket::nonBlockingIMAP() QFAIL("Timed out"); } - QVERIFY(nonBlockingIMAP_totalWritten == 10); + QCOMPARE(nonBlockingIMAP_totalWritten, 10); // Wait for greeting enterLoop(30); @@ -1087,7 +1086,7 @@ void tst_QTcpSocket::partialRead() QTcpSocket *socket = newSocket(); socket->connectToHost(QtNetworkSettings::serverName(), 143); QVERIFY(socket->waitForConnected(10000)); - QVERIFY(socket->state() == QTcpSocket::ConnectedState); + QCOMPARE(socket->state(), QTcpSocket::ConnectedState); char buf[512]; QByteArray greeting = expectedReplyIMAP(); @@ -1111,7 +1110,7 @@ void tst_QTcpSocket::unget() QTcpSocket *socket = newSocket(); socket->connectToHost(QtNetworkSettings::serverName(), 143); QVERIFY(socket->waitForConnected(10000)); - QVERIFY(socket->state() == QTcpSocket::ConnectedState); + QCOMPARE(socket->state(), QTcpSocket::ConnectedState); char buf[512]; QByteArray greeting = expectedReplyIMAP(); @@ -1169,7 +1168,7 @@ void tst_QTcpSocket::openCloseOpenClose() QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen)); QVERIFY(socket->isSequential()); QVERIFY(!socket->isOpen()); - QVERIFY(socket->socketType() == QTcpSocket::TcpSocket); + QCOMPARE(socket->socketType(), QTcpSocket::TcpSocket); char c; QCOMPARE(socket->getChar(&c), false); @@ -1178,13 +1177,13 @@ void tst_QTcpSocket::openCloseOpenClose() QCOMPARE(socket->readLine(), QByteArray()); QCOMPARE(socket->socketDescriptor(), (qintptr)-1); QCOMPARE((int) socket->localPort(), 0); - QVERIFY(socket->localAddress() == QHostAddress()); + QCOMPARE(socket->localAddress(), QHostAddress()); QCOMPARE((int) socket->peerPort(), 0); - QVERIFY(socket->peerAddress() == QHostAddress()); + QCOMPARE(socket->peerAddress(), QHostAddress()); QCOMPARE(socket->error(), QTcpSocket::UnknownSocketError); QCOMPARE(socket->errorString(), QString("Unknown error")); - QVERIFY(socket->state() == QTcpSocket::UnconnectedState); + QCOMPARE(socket->state(), QTcpSocket::UnconnectedState); socket->connectToHost(QtNetworkSettings::serverName(), 143); QVERIFY(socket->waitForConnected(10000)); @@ -1201,7 +1200,7 @@ void tst_QTcpSocket::connectDisconnectConnectDisconnect() for (int i = 0; i < 3; ++i) { QCOMPARE(socket->state(), QTcpSocket::UnconnectedState); - QVERIFY(socket->socketType() == QTcpSocket::TcpSocket); + QCOMPARE(socket->socketType(), QTcpSocket::TcpSocket); socket->connectToHost(QtNetworkSettings::serverName(), 143); QVERIFY(socket->waitForReadyRead(10000)); @@ -1261,7 +1260,7 @@ void tst_QTcpSocket::disconnectWhileConnecting() connect(socket, SIGNAL(disconnected()), SLOT(exitLoopSlot())); enterLoop(10); QVERIFY2(!timeout(), "Network timeout"); - QVERIFY(socket->state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState); if (!closeDirectly) { QCOMPARE(int(socket->openMode()), int(QIODevice::ReadWrite)); socket->close(); @@ -1273,7 +1272,7 @@ void tst_QTcpSocket::disconnectWhileConnecting() QTcpSocket *othersocket = server.nextPendingConnection(); if (othersocket->state() != QAbstractSocket::UnconnectedState) QVERIFY2(othersocket->waitForDisconnected(10000), "Network timeout"); - QVERIFY(othersocket->state() == QAbstractSocket::UnconnectedState); + QCOMPARE(othersocket->state(), QAbstractSocket::UnconnectedState); QCOMPARE(othersocket->readAll(), data); delete socket; @@ -1376,7 +1375,7 @@ void tst_QTcpSocket::disconnectWhileConnectingNoEventLoop() } QVERIFY2(socket->waitForDisconnected(10000), "Network timeout"); - QVERIFY(socket->state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState); if (!closeDirectly) { QCOMPARE(int(socket->openMode()), int(QIODevice::ReadWrite)); socket->close(); @@ -1415,10 +1414,10 @@ void tst_QTcpSocket::disconnectWhileLookingUp() QFETCH(bool, doClose); if (doClose) { socket->close(); - QVERIFY(socket->openMode() == QIODevice::NotOpen); + QCOMPARE(socket->openMode(), QIODevice::NotOpen); } else { socket->disconnectFromHost(); - QVERIFY(socket->openMode() == QIODevice::ReadWrite); + QCOMPARE(socket->openMode(), QIODevice::ReadWrite); QVERIFY(socket->waitForDisconnected(5000)); } @@ -1429,12 +1428,12 @@ void tst_QTcpSocket::disconnectWhileLookingUp() // recheck if (doClose) { - QVERIFY(socket->openMode() == QIODevice::NotOpen); + QCOMPARE(socket->openMode(), QIODevice::NotOpen); } else { - QVERIFY(socket->openMode() == QIODevice::ReadWrite); + QCOMPARE(socket->openMode(), QIODevice::ReadWrite); } - QVERIFY(socket->state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState); } //---------------------------------------------------------------------------------- @@ -1458,7 +1457,7 @@ void tst_QTcpSocket::downloadBigFile() } QByteArray hostName = QtNetworkSettings::serverName().toLatin1(); - QVERIFY(tmpSocket->state() == QAbstractSocket::ConnectedState); + QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState); QVERIFY(tmpSocket->write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0); QVERIFY(tmpSocket->write("HOST: ") > 0); QVERIFY(tmpSocket->write(hostName.data()) > 0); @@ -1831,7 +1830,6 @@ private slots: } #endif // !QT_NO_NETWORKPROXY private: - int exitCode; QTcpSocket *socket; QByteArray socketData; }; @@ -2687,12 +2685,12 @@ void tst_QTcpSocket::taskQtBug7054TimeoutErrorResetting() socket->connectToHost(QtNetworkSettings::serverName(), 443); QVERIFY(socket->waitForConnected(5*1000)); - QVERIFY(socket->error() == QAbstractSocket::UnknownSocketError); + QCOMPARE(socket->error(), QAbstractSocket::UnknownSocketError); // We connected to the HTTPS port. Wait two seconds to receive data. We will receive // nothing because we would need to start the SSL handshake QVERIFY(!socket->waitForReadyRead(2*1000)); - QVERIFY(socket->error() == QAbstractSocket::SocketTimeoutError); + QCOMPARE(socket->error(), QAbstractSocket::SocketTimeoutError); // Now write some crap to make the server disconnect us. 4 lines are enough. socket->write("a\r\nb\r\nc\r\nd\r\n"); @@ -2702,7 +2700,7 @@ void tst_QTcpSocket::taskQtBug7054TimeoutErrorResetting() // should get a better error since the server disconnected us QVERIFY(!socket->waitForReadyRead(2*1000)); // It must NOT be the SocketTimeoutError that had been set before - QVERIFY(socket->error() == QAbstractSocket::RemoteHostClosedError); + QCOMPARE(socket->error(), QAbstractSocket::RemoteHostClosedError); } #ifndef QT_NO_NETWORKPROXY @@ -2896,25 +2894,25 @@ void tst_QTcpSocket::qtbug14268_peek() QTcpSocket *outgoing = socketPair.endPoints[0]; QTcpSocket *incoming = socketPair.endPoints[1]; - QVERIFY(incoming->state() == QTcpSocket::ConnectedState); - QVERIFY(outgoing->state() == QTcpSocket::ConnectedState); + QCOMPARE(incoming->state(), QTcpSocket::ConnectedState); + QCOMPARE(outgoing->state(), QTcpSocket::ConnectedState); outgoing->write("abc\n"); QVERIFY(outgoing->waitForBytesWritten(2000)); QVERIFY(incoming->waitForReadyRead(2000)); - QVERIFY(incoming->peek(128*1024) == QByteArray("abc\n")); + QCOMPARE(incoming->peek(128*1024), QByteArray("abc\n")); outgoing->write("def\n"); QVERIFY(outgoing->waitForBytesWritten(2000)); QVERIFY(incoming->waitForReadyRead(2000)); - QVERIFY(incoming->peek(128*1024) == QByteArray("abc\ndef\n")); + QCOMPARE(incoming->peek(128*1024), QByteArray("abc\ndef\n")); outgoing->write("ghi\n"); QVERIFY(outgoing->waitForBytesWritten(2000)); QVERIFY(incoming->waitForReadyRead(2000)); - QVERIFY(incoming->peek(128*1024) == QByteArray("abc\ndef\nghi\n")); + QCOMPARE(incoming->peek(128*1024), QByteArray("abc\ndef\nghi\n")); - QVERIFY(incoming->read(128*1024) == QByteArray("abc\ndef\nghi\n")); + QCOMPARE(incoming->read(128*1024), QByteArray("abc\ndef\nghi\n")); } void tst_QTcpSocket::setSocketOption() @@ -2928,8 +2926,8 @@ void tst_QTcpSocket::setSocketOption() QTcpSocket *outgoing = socketPair.endPoints[0]; QTcpSocket *incoming = socketPair.endPoints[1]; - QVERIFY(incoming->state() == QTcpSocket::ConnectedState); - QVERIFY(outgoing->state() == QTcpSocket::ConnectedState); + QCOMPARE(incoming->state(), QTcpSocket::ConnectedState); + QCOMPARE(outgoing->state(), QTcpSocket::ConnectedState); outgoing->setSocketOption(QAbstractSocket::LowDelayOption, true); QVariant v = outgoing->socketOption(QAbstractSocket::LowDelayOption); @@ -3009,7 +3007,7 @@ void tst_QTcpSocket::serverDisconnectWithBuffered() delete newConnection; QVERIFY(socket->waitForConnected(5000)); // ready for write - QVERIFY(socket->state() == QAbstractSocket::ConnectedState); + QCOMPARE(socket->state(), QAbstractSocket::ConnectedState); QSignalSpy spyStateChanged(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState))); QSignalSpy spyDisconnected(socket, SIGNAL(disconnected())); @@ -3019,10 +3017,10 @@ void tst_QTcpSocket::serverDisconnectWithBuffered() QCOMPARE(socket->read(buf, sizeof(buf)), Q_INT64_C(1)); if (socket->state() != QAbstractSocket::UnconnectedState) { QVERIFY(socket->waitForDisconnected(5000)); - QVERIFY(socket->state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState); } // Test signal emitting - QVERIFY(spyDisconnected.count() == 1); + QCOMPARE(spyDisconnected.count(), 1); QVERIFY(spyStateChanged.count() > 0); QVERIFY(qvariant_cast<QAbstractSocket::SocketState>(spyStateChanged.last().first()) == QAbstractSocket::UnconnectedState); diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 8de9987ed1380bf8d89a0b3f1f8bbe3ca6a1e080..5b27b7d2b4d8eac7b808e8155293b8e3dab80d3f 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -223,7 +223,7 @@ void tst_QUdpSocket::constructing() QVERIFY(socket.isSequential()); QVERIFY(!socket.isOpen()); - QVERIFY(socket.socketType() == QUdpSocket::UdpSocket); + QCOMPARE(socket.socketType(), QUdpSocket::UdpSocket); QCOMPARE((int) socket.bytesAvailable(), 0); QCOMPARE(socket.canReadLine(), false); QCOMPARE(socket.readLine(), QByteArray()); @@ -749,7 +749,7 @@ void tst_QUdpSocket::writeDatagram() QCOMPARE(client.error(), QUdpSocket::DatagramTooLargeError); break; } - QVERIFY(bytesspy.count() == 1); + QCOMPARE(bytesspy.count(), 1); QCOMPARE(*static_cast<const qint64 *>(bytesspy.at(0).at(0).constData()), qint64(i * 1024)); QCOMPARE(errorspy.count(), 0); diff --git a/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro b/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro index f2d6589410e17073abdb37a78713591801d7c3c5..26d6424a9737fd156875479751599a4f4cd77b52 100644 --- a/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro +++ b/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro @@ -2,7 +2,7 @@ CONFIG += testcase CONFIG += parallel_test SOURCES += tst_qsslcertificate.cpp -!wince*:win32:LIBS += -lws2_32 +!wince:win32:LIBS += -lws2_32 QT = core network testlib TARGET = tst_qsslcertificate diff --git a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp index 604c0ef782277c7319cb6c5b7b83b72a3f9d1bee..623ecdd923f9d0efa64461609a6696da4e55426a 100644 --- a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp @@ -767,7 +767,7 @@ void tst_QSslCertificate::certInfo() QVERIFY(cert.expiryDate() < QDateTime::currentDateTime()); // cert has expired QSslCertificate copy = cert; - QVERIFY(cert == copy); + QCOMPARE(cert, copy); QVERIFY(!(cert != copy)); QCOMPARE(cert, QSslCertificate(pem, QSsl::Pem)); @@ -1061,7 +1061,7 @@ void tst_QSslCertificate::extensions() QSslCertificate cert = certList[0]; QList<QSslCertificateExtension> extensions = cert.extensions(); - QVERIFY(extensions.count() == 9); + QCOMPARE(extensions.count(), 9); int unknown_idx = -1; int authority_info_idx = -1; @@ -1093,8 +1093,8 @@ void tst_QSslCertificate::extensions() // Unknown QSslCertificateExtension unknown = extensions[unknown_idx]; - QVERIFY(unknown.oid() == QStringLiteral("1.3.6.1.5.5.7.1.12")); - QVERIFY(unknown.name() == QStringLiteral("1.3.6.1.5.5.7.1.12")); + QCOMPARE(unknown.oid(), QStringLiteral("1.3.6.1.5.5.7.1.12")); + QCOMPARE(unknown.name(), QStringLiteral("1.3.6.1.5.5.7.1.12")); QVERIFY(!unknown.isCritical()); QVERIFY(!unknown.isSupported()); @@ -1106,8 +1106,8 @@ void tst_QSslCertificate::extensions() // Authority Info Access QSslCertificateExtension aia = extensions[authority_info_idx]; - QVERIFY(aia.oid() == QStringLiteral("1.3.6.1.5.5.7.1.1")); - QVERIFY(aia.name() == QStringLiteral("authorityInfoAccess")); + QCOMPARE(aia.oid(), QStringLiteral("1.3.6.1.5.5.7.1.1")); + QCOMPARE(aia.name(), QStringLiteral("authorityInfoAccess")); QVERIFY(!aia.isCritical()); QVERIFY(aia.isSupported()); @@ -1116,32 +1116,32 @@ void tst_QSslCertificate::extensions() QString ocsp = aiaValue[QStringLiteral("OCSP")].toString(); QString caIssuers = aiaValue[QStringLiteral("caIssuers")].toString(); - QVERIFY(ocsp == QStringLiteral("http://EVIntl-ocsp.verisign.com")); - QVERIFY(caIssuers == QStringLiteral("http://EVIntl-aia.verisign.com/EVIntl2006.cer")); + QCOMPARE(ocsp, QStringLiteral("http://EVIntl-ocsp.verisign.com")); + QCOMPARE(caIssuers, QStringLiteral("http://EVIntl-aia.verisign.com/EVIntl2006.cer")); // Basic constraints QSslCertificateExtension basic = extensions[basic_constraints_idx]; - QVERIFY(basic.oid() == QStringLiteral("2.5.29.19")); - QVERIFY(basic.name() == QStringLiteral("basicConstraints")); + QCOMPARE(basic.oid(), QStringLiteral("2.5.29.19")); + QCOMPARE(basic.name(), QStringLiteral("basicConstraints")); QVERIFY(!basic.isCritical()); QVERIFY(basic.isSupported()); QVariantMap basicValue = basic.value().toMap(); QCOMPARE(basicValue.keys(), QList<QString>() << QStringLiteral("ca")); - QVERIFY(basicValue[QStringLiteral("ca")].toBool() == false); + QVERIFY(!basicValue[QStringLiteral("ca")].toBool()); // Subject key identifier QSslCertificateExtension subjectKey = extensions[subject_key_idx]; - QVERIFY(subjectKey.oid() == QStringLiteral("2.5.29.14")); - QVERIFY(subjectKey.name() == QStringLiteral("subjectKeyIdentifier")); + QCOMPARE(subjectKey.oid(), QStringLiteral("2.5.29.14")); + QCOMPARE(subjectKey.name(), QStringLiteral("subjectKeyIdentifier")); QVERIFY(!subjectKey.isCritical()); QVERIFY(subjectKey.isSupported()); - QVERIFY(subjectKey.value().toString() == QStringLiteral("5F:90:23:CD:24:CA:52:C9:36:29:F0:7E:9D:B1:FE:08:E0:EE:69:F0")); + QCOMPARE(subjectKey.value().toString(), QStringLiteral("5F:90:23:CD:24:CA:52:C9:36:29:F0:7E:9D:B1:FE:08:E0:EE:69:F0")); // Authority key identifier QSslCertificateExtension authKey = extensions[auth_key_idx]; - QVERIFY(authKey.oid() == QStringLiteral("2.5.29.35")); - QVERIFY(authKey.name() == QStringLiteral("authorityKeyIdentifier")); + QCOMPARE(authKey.oid(), QStringLiteral("2.5.29.35")); + QCOMPARE(authKey.name(), QStringLiteral("authorityKeyIdentifier")); QVERIFY(!authKey.isCritical()); QVERIFY(authKey.isSupported()); @@ -1159,7 +1159,7 @@ void tst_QSslCertificate::extensionsCritical() QSslCertificate cert = certList[0]; QList<QSslCertificateExtension> extensions = cert.extensions(); - QVERIFY(extensions.count() == 9); + QCOMPARE(extensions.count(), 9); int basic_constraints_idx = -1; int key_usage_idx = -1; @@ -1178,19 +1178,19 @@ void tst_QSslCertificate::extensionsCritical() // Basic constraints QSslCertificateExtension basic = extensions[basic_constraints_idx]; - QVERIFY(basic.oid() == QStringLiteral("2.5.29.19")); - QVERIFY(basic.name() == QStringLiteral("basicConstraints")); + QCOMPARE(basic.oid(), QStringLiteral("2.5.29.19")); + QCOMPARE(basic.name(), QStringLiteral("basicConstraints")); QVERIFY(basic.isCritical()); QVERIFY(basic.isSupported()); QVariantMap basicValue = basic.value().toMap(); QCOMPARE(basicValue.keys(), QList<QString>() << QStringLiteral("ca")); - QVERIFY(basicValue[QStringLiteral("ca")].toBool() == false); + QVERIFY(!basicValue[QStringLiteral("ca")].toBool()); // Key Usage QSslCertificateExtension keyUsage = extensions[key_usage_idx]; - QVERIFY(keyUsage.oid() == QStringLiteral("2.5.29.15")); - QVERIFY(keyUsage.name() == QStringLiteral("keyUsage")); + QCOMPARE(keyUsage.oid(), QStringLiteral("2.5.29.15")); + QCOMPARE(keyUsage.name(), QStringLiteral("keyUsage")); QVERIFY(keyUsage.isCritical()); QVERIFY(!keyUsage.isSupported()); } @@ -1249,21 +1249,21 @@ void tst_QSslCertificate::threadSafeConstMethods() t2.start(); QVERIFY(t1.wait(5000)); QVERIFY(t2.wait(5000)); - QVERIFY(t1.cert == t2.cert); - QVERIFY(t1.effectiveDate == t2.effectiveDate); - QVERIFY(t1.expiryDate == t2.expiryDate); + QCOMPARE(t1.cert, t2.cert); + QCOMPARE(t1.effectiveDate, t2.effectiveDate); + QCOMPARE(t1.expiryDate, t2.expiryDate); //QVERIFY(t1.extensions == t2.extensions); // no equality operator, so not tested - QVERIFY(t1.isBlacklisted == t2.isBlacklisted); - QVERIFY(t1.issuerInfo == t2.issuerInfo); - QVERIFY(t1.issuerInfoAttributes == t2.issuerInfoAttributes); - QVERIFY(t1.publicKey == t2.publicKey); - QVERIFY(t1.serialNumber == t2.serialNumber); - QVERIFY(t1.subjectInfo == t2.subjectInfo); - QVERIFY(t1.subjectInfoAttributes == t2.subjectInfoAttributes); - QVERIFY(t1.toDer == t2.toDer); - QVERIFY(t1.toPem == t2.toPem); - QVERIFY(t1.toText == t2.toText); - QVERIFY(t1.version == t2.version); + QCOMPARE(t1.isBlacklisted, t2.isBlacklisted); + QCOMPARE(t1.issuerInfo, t2.issuerInfo); + QCOMPARE(t1.issuerInfoAttributes, t2.issuerInfoAttributes); + QCOMPARE(t1.publicKey, t2.publicKey); + QCOMPARE(t1.serialNumber, t2.serialNumber); + QCOMPARE(t1.subjectInfo, t2.subjectInfo); + QCOMPARE(t1.subjectInfoAttributes, t2.subjectInfoAttributes); + QCOMPARE(t1.toDer, t2.toDer); + QCOMPARE(t1.toPem, t2.toPem); + QCOMPARE(t1.toText, t2.toText); + QCOMPARE(t1.version, t2.version); } diff --git a/tests/auto/network/ssl/qsslcipher/qsslcipher.pro b/tests/auto/network/ssl/qsslcipher/qsslcipher.pro index a091bd018421208f55a5b45a166f0d1f7f5138bd..36e3c29b31faf3b3e87957de43b33b4d4975c853 100644 --- a/tests/auto/network/ssl/qsslcipher/qsslcipher.pro +++ b/tests/auto/network/ssl/qsslcipher/qsslcipher.pro @@ -2,7 +2,7 @@ CONFIG += testcase CONFIG += parallel_test SOURCES += tst_qsslcipher.cpp -!wince*:win32:LIBS += -lws2_32 +win32:!wince: LIBS += -lws2_32 QT = core network testlib TARGET = tst_qsslcipher diff --git a/tests/auto/network/ssl/qsslellipticcurve/qsslellipticcurve.pro b/tests/auto/network/ssl/qsslellipticcurve/qsslellipticcurve.pro index d9a771a0809379e1a35c13a8785ee0327f316c0e..747bb55adeb0224c07d667d1bd0c35c8c369ed74 100644 --- a/tests/auto/network/ssl/qsslellipticcurve/qsslellipticcurve.pro +++ b/tests/auto/network/ssl/qsslellipticcurve/qsslellipticcurve.pro @@ -2,7 +2,7 @@ CONFIG += testcase CONFIG += parallel_test SOURCES += tst_qsslellipticcurve.cpp -!wince*:win32:LIBS += -lws2_32 +win32:!wince: LIBS += -lws2_32 QT = core network testlib TARGET = tst_qsslellipticcurve diff --git a/tests/auto/network/ssl/qsslellipticcurve/tst_qsslellipticcurve.cpp b/tests/auto/network/ssl/qsslellipticcurve/tst_qsslellipticcurve.cpp index c97b46a512267c2586633eb92b156f9f35e8a141..685d354cc9e383da1e062d65bbbd2c3e14e76a0e 100644 --- a/tests/auto/network/ssl/qsslellipticcurve/tst_qsslellipticcurve.cpp +++ b/tests/auto/network/ssl/qsslellipticcurve/tst_qsslellipticcurve.cpp @@ -34,7 +34,7 @@ #include <QtTest/QtTest> #include <QSslEllipticCurve> -#include <QSslSocket> +#include <QSslConfiguration> class tst_QSslEllipticCurve : public QObject { @@ -84,7 +84,7 @@ void tst_QSslEllipticCurve::fromShortName_data() QTest::newRow("QString()") << QString() << QSslEllipticCurve() << false; QTest::newRow("\"\"") << QString("") << QSslEllipticCurve() << false; QTest::newRow("does-not-exist") << QStringLiteral("does-not-exist") << QSslEllipticCurve() << false; - Q_FOREACH (QSslEllipticCurve ec, QSslSocket::supportedEllipticCurves()) { + Q_FOREACH (QSslEllipticCurve ec, QSslConfiguration::supportedEllipticCurves()) { const QString sN = ec.shortName(); QTest::newRow(qPrintable("supported EC \"" + sN + '"')) << sN << ec << true; // At least in the OpenSSL impl, the short name is case-sensitive. That feels odd. @@ -117,7 +117,7 @@ void tst_QSslEllipticCurve::fromLongName_data() QTest::newRow("QString()") << QString() << QSslEllipticCurve() << false; QTest::newRow("\"\"") << QString("") << QSslEllipticCurve() << false; QTest::newRow("does-not-exist") << QStringLiteral("does-not-exist") << QSslEllipticCurve() << false; - Q_FOREACH (QSslEllipticCurve ec, QSslSocket::supportedEllipticCurves()) { + Q_FOREACH (QSslEllipticCurve ec, QSslConfiguration::supportedEllipticCurves()) { const QString lN = ec.longName(); QTest::newRow(qPrintable("supported EC \"" + lN + '"')) << lN << ec << true; } diff --git a/tests/auto/network/ssl/qsslerror/qsslerror.pro b/tests/auto/network/ssl/qsslerror/qsslerror.pro index 85a5046923251fa70ef11995c4531734fd0daeb9..6b7090db994108f88d959ef113559fe0d7ca8ec7 100644 --- a/tests/auto/network/ssl/qsslerror/qsslerror.pro +++ b/tests/auto/network/ssl/qsslerror/qsslerror.pro @@ -2,7 +2,7 @@ CONFIG += testcase CONFIG += parallel_test SOURCES += tst_qsslerror.cpp -!wince*:win32:LIBS += -lws2_32 +win32:!wince: LIBS += -lws2_32 QT = core network testlib TARGET = tst_qsslerror diff --git a/tests/auto/network/ssl/qsslkey/BLACKLIST b/tests/auto/network/ssl/qsslkey/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..a08e1f35eb7c510c1d29584d7edc575339876a01 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/BLACKLIST @@ -0,0 +1 @@ +linux diff --git a/tests/auto/network/ssl/qsslkey/qsslkey.pro b/tests/auto/network/ssl/qsslkey/qsslkey.pro index 4ec4f27e6fc11978aa2aca87b306d9157fb856ee..a74f432890c612c73b31bac4dd678659304a9d6f 100644 --- a/tests/auto/network/ssl/qsslkey/qsslkey.pro +++ b/tests/auto/network/ssl/qsslkey/qsslkey.pro @@ -2,7 +2,7 @@ CONFIG += testcase CONFIG += parallel_test SOURCES += tst_qsslkey.cpp -!wince*:win32:LIBS += -lws2_32 +win32:!wince: LIBS += -lws2_32 QT = core network testlib contains(QT_CONFIG, private_tests) { QT += core-private network-private diff --git a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp index d5700370150db588f4586cb6b6d87d2ae546e793..a7957d32888fdcf9ecb4cd6d928d648d502202a2 100644 --- a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp +++ b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp @@ -39,7 +39,7 @@ #include <QtNetwork/qhostaddress.h> #include <QtNetwork/qnetworkproxy.h> -#if !defined(QT_NO_SSL) && defined(QT_NO_OPENSSL) && defined(QT_BUILD_INTERNAL) +#if !defined(QT_NO_SSL) && defined(QT_BUILD_INTERNAL) #include "private/qsslkey_p.h" #define TEST_CRYPTO #endif diff --git a/tests/auto/network/ssl/qsslsocket/BLACKLIST b/tests/auto/network/ssl/qsslsocket/BLACKLIST index 17b606e2be49b3535fec52efe9cf0264755b00fb..4146a352e98b532a82159587510f33216c1d3e5e 100644 --- a/tests/auto/network/ssl/qsslsocket/BLACKLIST +++ b/tests/auto/network/ssl/qsslsocket/BLACKLIST @@ -1,2 +1,3 @@ +windows [waitForConnectedEncryptedReadyRead:WithSocks5ProxyAuth] * diff --git a/tests/auto/network/ssl/qsslsocket/qsslsocket.pro b/tests/auto/network/ssl/qsslsocket/qsslsocket.pro index 07774d1847f9aa73408255975833c69932119419..de2be8e126f6b6648f9aee58f35b1c5452655b72 100644 --- a/tests/auto/network/ssl/qsslsocket/qsslsocket.pro +++ b/tests/auto/network/ssl/qsslsocket/qsslsocket.pro @@ -1,7 +1,7 @@ CONFIG += testcase SOURCES += tst_qsslsocket.cpp -!wince*:win32:LIBS += -lws2_32 +win32:!wince: LIBS += -lws2_32 QT = core core-private network-private testlib TARGET = tst_qsslsocket diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index b823b8712561b8e4473c3c08a77d69b078942b18..64288f50e1ad546718947ff8f2c85c1bd86e2ec1 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -820,7 +820,7 @@ void tst_QSslSocket::peerCertificateChain() this->socket = socket.data(); QList<QSslCertificate> caCertificates = QSslCertificate::fromPath(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem")); - QVERIFY(caCertificates.count() == 1); + QCOMPARE(caCertificates.count(), 1); socket->addCaCertificates(caCertificates); #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)), @@ -866,7 +866,7 @@ void tst_QSslSocket::peerCertificateChain() QSKIP("Skipping flaky test - See QTBUG-29941"); QCOMPARE(socket->peerCertificateChain().first(), socket->peerCertificate()); - QVERIFY(socket->peerCertificateChain() == certChain); + QCOMPARE(socket->peerCertificateChain(), certChain); socket->disconnectFromHost(); QVERIFY(socket->waitForDisconnected()); @@ -1733,7 +1733,7 @@ void tst_QSslSocket::spontaneousWrite() QSslSocket *sender = server.socket; QVERIFY(sender); - QVERIFY(sender->state() == QAbstractSocket::ConnectedState); + QCOMPARE(sender->state(), QAbstractSocket::ConnectedState); receiver->setObjectName("receiver"); sender->setObjectName("sender"); receiver->ignoreSslErrors(); @@ -1778,7 +1778,7 @@ void tst_QSslSocket::setReadBufferSize() QSslSocket *sender = server.socket; QVERIFY(sender); - QVERIFY(sender->state() == QAbstractSocket::ConnectedState); + QCOMPARE(sender->state(), QAbstractSocket::ConnectedState); receiver->setObjectName("receiver"); sender->setObjectName("sender"); receiver->ignoreSslErrors(); @@ -2332,7 +2332,7 @@ void tst_QSslSocket::readFromClosedSocket() socket->close(); QVERIFY(!socket->bytesAvailable()); QVERIFY(!socket->bytesToWrite()); - QVERIFY(socket->state() == QAbstractSocket::UnconnectedState); + QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState); } void tst_QSslSocket::writeBigChunk() @@ -2359,7 +2359,7 @@ void tst_QSslSocket::writeBigChunk() QString errorBefore = socket->errorString(); int ret = socket->write(data.constData(), data.size()); - QVERIFY(data.size() == ret); + QCOMPARE(data.size(), ret); // spin the event loop once so QSslSocket::transmit() gets called QCoreApplication::processEvents(); @@ -2376,7 +2376,7 @@ void tst_QSslSocket::writeBigChunk() QByteArray("unexpected error: ").append(qPrintable(errorAfter))); // check that everything has been written to OpenSSL - QVERIFY(socket->bytesToWrite() == 0); + QCOMPARE(socket->bytesToWrite(), 0); socket->close(); } @@ -2400,7 +2400,7 @@ void tst_QSslSocket::blacklistedCertificates() QSslSocket *sender = server.socket; QVERIFY(sender); - QVERIFY(sender->state() == QAbstractSocket::ConnectedState); + QCOMPARE(sender->state(), QAbstractSocket::ConnectedState); receiver->setObjectName("receiver"); sender->setObjectName("sender"); receiver->startClientEncryption(); @@ -2726,9 +2726,9 @@ void tst_QSslSocket::qtbug18498_peek2() while (client->bytesAvailable() < 7 && stopwatch.elapsed() < 5000) QTest::qWait(100); char c; - QVERIFY(client->peek(&c,1) == 1); + QCOMPARE(client->peek(&c,1), 1); QCOMPARE(c, 'H'); - QVERIFY(client->read(&c,1) == 1); + QCOMPARE(client->read(&c,1), 1); QCOMPARE(c, 'H'); QByteArray b = client->peek(2); QCOMPARE(b, QByteArray("EL")); @@ -2764,7 +2764,7 @@ void tst_QSslSocket::qtbug18498_peek2() // ### Qt5 use QTRY_VERIFY while (server->bytesAvailable() < 10 && stopwatch.elapsed() < 5000) QTest::qWait(100); - QVERIFY(server->peek(&c,1) == 1); + QCOMPARE(server->peek(&c,1), 1); QCOMPARE(c, 'S'); b = server->peek(3); QCOMPARE(b, QByteArray("STA")); @@ -2800,9 +2800,9 @@ void tst_QSslSocket::qtbug18498_peek2() while (client->bytesAvailable() < 7 && stopwatch.elapsed() < 5000) QTest::qWait(100); QVERIFY(server->mode() == QSslSocket::SslServerMode && client->mode() == QSslSocket::SslClientMode); - QVERIFY(client->peek(&c,1) == 1); + QCOMPARE(client->peek(&c,1), 1); QCOMPARE(c, 'h'); - QVERIFY(client->read(&c,1) == 1); + QCOMPARE(client->read(&c,1), 1); QCOMPARE(c, 'h'); b = client->peek(2); QCOMPARE(b, QByteArray("el")); @@ -2812,7 +2812,7 @@ void tst_QSslSocket::qtbug18498_peek2() stopwatch.start(); while (server->bytesAvailable() < 9 && stopwatch.elapsed() < 5000) QTest::qWait(100); - QVERIFY(server->peek(&c,1) == 1); + QCOMPARE(server->peek(&c,1), 1); QCOMPARE(c, 'g'); QCOMPARE(server->readAll(), QByteArray("goodbye\r\n")); client->disconnectFromHost(); @@ -2846,7 +2846,7 @@ void tst_QSslSocket::dhServer() client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort()); loop.exec(); - QVERIFY(client->state() == QAbstractSocket::ConnectedState); + QCOMPARE(client->state(), QAbstractSocket::ConnectedState); } void tst_QSslSocket::ecdhServer() @@ -2876,7 +2876,7 @@ void tst_QSslSocket::ecdhServer() client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort()); loop.exec(); - QVERIFY(client->state() == QAbstractSocket::ConnectedState); + QCOMPARE(client->state(), QAbstractSocket::ConnectedState); } void tst_QSslSocket::verifyClientCertificate_data() diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/BLACKLIST b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..c9b628d79b21089eafe87071b81279ea0ea9d34e --- /dev/null +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/BLACKLIST @@ -0,0 +1,2 @@ +[onDemandRootCertLoadingMemberMethods] +linux diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro index 9b1278508152ddf5b22c14fca0f2dbdf8f9d44c0..4f216ebb37e7d0c154fedd53f547cdf75b28a3fa 100644 --- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro @@ -3,7 +3,7 @@ CONFIG += parallel_test testcase.timeout = 300 # this test is slow SOURCES += tst_qsslsocket_onDemandCertificates_member.cpp -!wince*:win32:LIBS += -lws2_32 +win32:!wince: LIBS += -lws2_32 QT = core core-private network-private testlib TARGET = tst_qsslsocket_onDemandCertificates_member diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/BLACKLIST b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..52bd2bc86dafbdd34d289853b18dfd75e0624a85 --- /dev/null +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/BLACKLIST @@ -0,0 +1,2 @@ +[onDemandRootCertLoadingStaticMethods:WithSocks5ProxyAuth] +windows diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro index c4d56436d0d6f61d648c204ecb9a4e36ba7261d2..96a6162ce646085a574938fd13f9a9cf0882ac26 100644 --- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro @@ -2,7 +2,7 @@ CONFIG += testcase CONFIG += parallel_test SOURCES += tst_qsslsocket_onDemandCertificates_static.cpp -!wince*:win32:LIBS += -lws2_32 +win32:!wince: LIBS += -lws2_32 QT = core core-private network-private testlib TARGET = tst_qsslsocket_onDemandCertificates_static diff --git a/tests/auto/opengl/qgl/BLACKLIST b/tests/auto/opengl/qgl/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..fa7c829b30e39ca930863fae618cbe420a9b96e6 --- /dev/null +++ b/tests/auto/opengl/qgl/BLACKLIST @@ -0,0 +1,16 @@ +[glWidgetRendering] +windows +[glFBORendering] +windows +[multipleFBOInterleavedRendering] +windows +[glPBufferRendering] +windows +[replaceClipping] +windows +[clipTest] +windows +[graphicsViewClipping] +windows +[glFBOUseInGLWidget] +windows diff --git a/tests/auto/opengl/qgl/tst_qgl.cpp b/tests/auto/opengl/qgl/tst_qgl.cpp index 9bd82559b79ec5afee4f703761d09b912cc9f546..797072535522155b9d6f4d0000d04bc8a2c2d097 100644 --- a/tests/auto/opengl/qgl/tst_qgl.cpp +++ b/tests/auto/opengl/qgl/tst_qgl.cpp @@ -459,113 +459,113 @@ void tst_QGL::getSetCheck() QGLFormat format1; QGLFormat format2; - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); format1.setDoubleBuffer(false); QVERIFY(!(format1 == format2)); QVERIFY(format1 != format2); format2.setDoubleBuffer(false); - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); format1.setDepthBufferSize(8); QVERIFY(!(format1 == format2)); QVERIFY(format1 != format2); format2.setDepthBufferSize(8); - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); format1.setAccumBufferSize(8); QVERIFY(!(format1 == format2)); QVERIFY(format1 != format2); format2.setAccumBufferSize(8); - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); format1.setRedBufferSize(8); QVERIFY(!(format1 == format2)); QVERIFY(format1 != format2); format2.setRedBufferSize(8); - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); format1.setGreenBufferSize(8); QVERIFY(!(format1 == format2)); QVERIFY(format1 != format2); format2.setGreenBufferSize(8); - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); format1.setBlueBufferSize(8); QVERIFY(!(format1 == format2)); QVERIFY(format1 != format2); format2.setBlueBufferSize(8); - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); format1.setAlphaBufferSize(8); QVERIFY(!(format1 == format2)); QVERIFY(format1 != format2); format2.setAlphaBufferSize(8); - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); format1.setStencilBufferSize(8); QVERIFY(!(format1 == format2)); QVERIFY(format1 != format2); format2.setStencilBufferSize(8); - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); format1.setSamples(8); QVERIFY(!(format1 == format2)); QVERIFY(format1 != format2); format2.setSamples(8); - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); format1.setSwapInterval(8); QVERIFY(!(format1 == format2)); QVERIFY(format1 != format2); format2.setSwapInterval(8); - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); format1.setPlane(8); QVERIFY(!(format1 == format2)); QVERIFY(format1 != format2); format2.setPlane(8); - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); format1.setVersion(3, 2); QVERIFY(!(format1 == format2)); QVERIFY(format1 != format2); format2.setVersion(3, 2); - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); format1.setProfile(QGLFormat::CoreProfile); QVERIFY(!(format1 == format2)); QVERIFY(format1 != format2); format2.setProfile(QGLFormat::CoreProfile); - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); format1.setOption(QGL::NoDeprecatedFunctions); QVERIFY(!(format1 == format2)); QVERIFY(format1 != format2); format2.setOption(QGL::NoDeprecatedFunctions); - QVERIFY(format1 == format2); + QCOMPARE(format1, format2); QVERIFY(!(format1 != format2)); // Copy constructor and assignment for QGLFormat. QGLFormat format3(format1); QGLFormat format4; - QVERIFY(format1 == format3); + QCOMPARE(format1, format3); QVERIFY(format1 != format4); format4 = format1; - QVERIFY(format1 == format4); + QCOMPARE(format1, format4); // Check that modifying a copy doesn't affect the original. format3.setRedBufferSize(16); @@ -584,15 +584,15 @@ void tst_QGL::getSetCheck() QCOMPARE(format5.plane(), 3); // The default format should be the same as QGLFormat(). - QVERIFY(QGLFormat::defaultFormat() == QGLFormat()); + QCOMPARE(QGLFormat::defaultFormat(), QGLFormat()); // Modify the default format and check that it was changed. QGLFormat::setDefaultFormat(format1); - QVERIFY(QGLFormat::defaultFormat() == format1); + QCOMPARE(QGLFormat::defaultFormat(), format1); // Restore the default format. QGLFormat::setDefaultFormat(QGLFormat()); - QVERIFY(QGLFormat::defaultFormat() == QGLFormat()); + QCOMPARE(QGLFormat::defaultFormat(), QGLFormat()); // Check the default overlay format's expected values. QGLFormat overlay(QGLFormat::defaultOverlayFormat()); @@ -618,11 +618,11 @@ void tst_QGL::getSetCheck() // Modify the default overlay format and check that it was changed. QGLFormat::setDefaultOverlayFormat(format1); - QVERIFY(QGLFormat::defaultOverlayFormat() == format1); + QCOMPARE(QGLFormat::defaultOverlayFormat(), format1); // Restore the default overlay format. QGLFormat::setDefaultOverlayFormat(overlay); - QVERIFY(QGLFormat::defaultOverlayFormat() == overlay); + QCOMPARE(QGLFormat::defaultOverlayFormat(), overlay); MyGLContext obj2(obj1); // bool QGLContext::windowCreated() @@ -1512,9 +1512,9 @@ void tst_QGL::colormap() QGLColormap cmap1; QVERIFY(cmap1.isEmpty()); QCOMPARE(cmap1.size(), 0); - QVERIFY(cmap1.entryRgb(0) == 0); - QVERIFY(cmap1.entryRgb(-1) == 0); - QVERIFY(cmap1.entryRgb(100) == 0); + QCOMPARE(cmap1.entryRgb(0), QRgb(0)); + QCOMPARE(cmap1.entryRgb(-1), QRgb(0)); + QCOMPARE(cmap1.entryRgb(100), QRgb(0)); QVERIFY(!cmap1.entryColor(0).isValid()); QVERIFY(!cmap1.entryColor(-1).isValid()); QVERIFY(!cmap1.entryColor(100).isValid()); @@ -1529,7 +1529,7 @@ void tst_QGL::colormap() // not to detect when it is empty! QVERIFY(cmap1.isEmpty()); QCOMPARE(cmap1.size(), 256); - QVERIFY(cmap1.entryRgb(0) == 0); + QCOMPARE(cmap1.entryRgb(0), QRgb(0)); QVERIFY(cmap1.entryColor(0) == QColor(0, 0, 0, 255)); QVERIFY(cmap1.entryRgb(56) == qRgb(255, 0, 0)); QVERIFY(cmap1.entryColor(56) == QColor(255, 0, 0, 255)); @@ -1611,7 +1611,7 @@ void tst_QGL::colormap() QVERIFY(cmap4.isEmpty()); QCOMPARE(cmap4.size(), 256); cmap4.setHandle(Qt::HANDLE(42)); - QVERIFY(cmap4.handle() == Qt::HANDLE(42)); + QCOMPARE(cmap4.handle(), Qt::HANDLE(42)); QVERIFY(!cmap4.isEmpty()); QCOMPARE(cmap4.size(), 256); } @@ -1629,7 +1629,7 @@ void tst_QGL::fboFormat() // Check the initial conditions. QGLFramebufferObjectFormat format1; QCOMPARE(format1.samples(), 0); - QVERIFY(format1.attachment() == QGLFramebufferObject::NoAttachment); + QCOMPARE(format1.attachment(), QGLFramebufferObject::NoAttachment); QCOMPARE(int(format1.textureTarget()), int(GL_TEXTURE_2D)); int expectedFormat = #ifdef QT_OPENGL_ES_2 @@ -1645,7 +1645,7 @@ void tst_QGL::fboFormat() format1.setTextureTarget(GL_TEXTURE_3D); format1.setInternalTextureFormat(GL_RGB16); QCOMPARE(format1.samples(), 8); - QVERIFY(format1.attachment() == QGLFramebufferObject::CombinedDepthStencil); + QCOMPARE(format1.attachment(), QGLFramebufferObject::CombinedDepthStencil); QCOMPARE(int(format1.textureTarget()), int(GL_TEXTURE_3D)); QCOMPARE(int(format1.internalTextureFormat()), int(GL_RGB16)); @@ -1653,12 +1653,12 @@ void tst_QGL::fboFormat() QGLFramebufferObjectFormat format2(format1); QGLFramebufferObjectFormat format3; QCOMPARE(format2.samples(), 8); - QVERIFY(format2.attachment() == QGLFramebufferObject::CombinedDepthStencil); + QCOMPARE(format2.attachment(), QGLFramebufferObject::CombinedDepthStencil); QCOMPARE(int(format2.textureTarget()), int(GL_TEXTURE_3D)); QCOMPARE(int(format2.internalTextureFormat()), int(GL_RGB16)); format3 = format1; QCOMPARE(format3.samples(), 8); - QVERIFY(format3.attachment() == QGLFramebufferObject::CombinedDepthStencil); + QCOMPARE(format3.attachment(), QGLFramebufferObject::CombinedDepthStencil); QCOMPARE(int(format3.textureTarget()), int(GL_TEXTURE_3D)); QCOMPARE(int(format3.internalTextureFormat()), int(GL_RGB16)); @@ -1666,7 +1666,7 @@ void tst_QGL::fboFormat() format2.setSamples(9); format3.setTextureTarget(GL_TEXTURE_2D); QCOMPARE(format1.samples(), 8); - QVERIFY(format1.attachment() == QGLFramebufferObject::CombinedDepthStencil); + QCOMPARE(format1.attachment(), QGLFramebufferObject::CombinedDepthStencil); QCOMPARE(int(format1.textureTarget()), int(GL_TEXTURE_3D)); QCOMPARE(int(format1.internalTextureFormat()), int(GL_RGB16)); @@ -1674,39 +1674,39 @@ void tst_QGL::fboFormat() QGLFramebufferObjectFormat format1c; QGLFramebufferObjectFormat format2c; - QVERIFY(format1c == format2c); + QCOMPARE(format1c, format2c); QVERIFY(!(format1c != format2c)); format1c.setSamples(8); QVERIFY(!(format1c == format2c)); QVERIFY(format1c != format2c); format2c.setSamples(8); - QVERIFY(format1c == format2c); + QCOMPARE(format1c, format2c); QVERIFY(!(format1c != format2c)); format1c.setAttachment(QGLFramebufferObject::CombinedDepthStencil); QVERIFY(!(format1c == format2c)); QVERIFY(format1c != format2c); format2c.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - QVERIFY(format1c == format2c); + QCOMPARE(format1c, format2c); QVERIFY(!(format1c != format2c)); format1c.setTextureTarget(GL_TEXTURE_3D); QVERIFY(!(format1c == format2c)); QVERIFY(format1c != format2c); format2c.setTextureTarget(GL_TEXTURE_3D); - QVERIFY(format1c == format2c); + QCOMPARE(format1c, format2c); QVERIFY(!(format1c != format2c)); format1c.setInternalTextureFormat(GL_RGB16); QVERIFY(!(format1c == format2c)); QVERIFY(format1c != format2c); format2c.setInternalTextureFormat(GL_RGB16); - QVERIFY(format1c == format2c); + QCOMPARE(format1c, format2c); QVERIFY(!(format1c != format2c)); QGLFramebufferObjectFormat format3c(format1c); QGLFramebufferObjectFormat format4c; - QVERIFY(format1c == format3c); + QCOMPARE(format1c, format3c); QVERIFY(!(format1c != format3c)); format3c.setInternalTextureFormat( #ifdef QT_OPENGL_ES_2 @@ -1719,7 +1719,7 @@ void tst_QGL::fboFormat() QVERIFY(format1c != format3c); format4c = format1c; - QVERIFY(format1c == format4c); + QCOMPARE(format1c, format4c); QVERIFY(!(format1c != format4c)); format4c.setInternalTextureFormat( #ifdef QT_OPENGL_ES_2 @@ -1947,7 +1947,7 @@ void tst_QGL::destroyFBOAfterContext() delete glw; // The handle should now be zero. - QVERIFY(fbo->handle() == 0); + QVERIFY(!fbo->handle()); QVERIFY(!fbo->isValid()); delete fbo; @@ -1984,14 +1984,14 @@ void tst_QGL::shareRegister() // Create a guard for the first context. QOpenGLSharedResourceGuard guard(glw1->context()->contextHandle()); - QVERIFY(guard.id() == 0); + QCOMPARE(guard.id(), 0); guard.setId(3); - QVERIFY(guard.id() == 3); + QCOMPARE(guard.id(), 3); // Request a tst_QGLResource object for the first context. tst_QGLResource *res1 = qt_shared_test()->value(glw1->context()->contextHandle()); QVERIFY(res1); - QVERIFY(qt_shared_test()->value(glw1->context()->contextHandle()) == res1); + QCOMPARE(qt_shared_test()->value(glw1->context()->contextHandle()), res1); // Create another context that shares with the first. QVERIFY(!glw1->isSharing()); @@ -2005,12 +2005,12 @@ void tst_QGL::shareRegister() QVERIFY(glw1->context() != glw2->context()); // Check that the first context's resource is also on the second. - QVERIFY(qt_shared_test()->value(glw1->context()) == res1); - QVERIFY(qt_shared_test()->value(glw2->context()) == res1); + QCOMPARE(qt_shared_test()->value(glw1->context()), res1); + QCOMPARE(qt_shared_test()->value(glw2->context()), res1); // Guard should still be the same. - QVERIFY(guard.context() == glw1->context()); - QVERIFY(guard.id() == 3); + QCOMPARE(guard.context(), glw1->context()); + QCOMPARE(guard.id(), 3); // Check the sharing relationships. QVERIFY(QGLContext::areSharing(glw1->context(), glw1->context())); @@ -2032,9 +2032,9 @@ void tst_QGL::shareRegister() // Request a resource to the third context. tst_QGLResource *res3 = qt_shared_test()->value(glw3->context()); QVERIFY(res3); - QVERIFY(qt_shared_test()->value(glw1->context()) == res1); - QVERIFY(qt_shared_test()->value(glw2->context()) == res1); - QVERIFY(qt_shared_test()->value(glw3->context()) == res3); + QCOMPARE(qt_shared_test()->value(glw1->context()), res1); + QCOMPARE(qt_shared_test()->value(glw2->context()), res1); + QCOMPARE(qt_shared_test()->value(glw3->context()), res3); // Check the sharing relationships again. QVERIFY(QGLContext::areSharing(glw1->context(), glw1->context())); @@ -2053,8 +2053,8 @@ void tst_QGL::shareRegister() QVERIFY(!QGLContext::areSharing(0, 0)); // Shared guard should still be the same. - QVERIFY(guard.context() == glw1->context()); - QVERIFY(guard.id() == 3); + QCOMPARE(guard.context(), glw1->context()); + QCOMPARE(guard.id(), 3); // Delete the first context. delete glw1; @@ -2064,14 +2064,14 @@ void tst_QGL::shareRegister() // The first context's resource should transfer to the second context. QCOMPARE(tst_QGLResource::deletions, 0); - QVERIFY(qt_shared_test()->value(glw2->context()) == res1); - QVERIFY(qt_shared_test()->value(glw3->context()) == res3); + QCOMPARE(qt_shared_test()->value(glw2->context()), res1); + QCOMPARE(qt_shared_test()->value(glw3->context()), res3); // Shared guard should now be the second context, with the id the same. - QVERIFY(guard.context() == glw2->context()); - QVERIFY(guard.id() == 3); - QVERIFY(guard3.context() == glw3->context()); - QVERIFY(guard3.id() == 5); + QCOMPARE(guard.context(), glw2->context()); + QCOMPARE(guard.id(), 3); + QCOMPARE(guard3.context(), glw3->context()); + QCOMPARE(guard3.id(), 5); // Clean up and check that the resources are properly deleted. delete glw2; @@ -2115,25 +2115,25 @@ void tst_QGL::qglContextDefaultBindTexture() QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); // Make sure the texture IDs returned are valid: - QCOMPARE((bool)funcs->glIsTexture(boundImageTextureId), GL_TRUE); - QCOMPARE((bool)funcs->glIsTexture(boundPixmapTextureId), GL_TRUE); + QCOMPARE(funcs->glIsTexture(boundImageTextureId), GLboolean(GL_TRUE)); + QCOMPARE(funcs->glIsTexture(boundPixmapTextureId), GLboolean(GL_TRUE)); // Make sure the textures are still valid after we delete the image/pixmap: // Also check that although the textures are left intact, the cache entries are removed: delete boundImage; boundImage = 0; - QCOMPARE((bool)funcs->glIsTexture(boundImageTextureId), GL_TRUE); + QCOMPARE(funcs->glIsTexture(boundImageTextureId), GLboolean(GL_TRUE)); QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); delete boundPixmap; boundPixmap = 0; - QCOMPARE((bool)funcs->glIsTexture(boundPixmapTextureId), GL_TRUE); + QCOMPARE(funcs->glIsTexture(boundPixmapTextureId), GLboolean(GL_TRUE)); QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); // Finally, make sure QGLContext::deleteTexture deletes the texture IDs: ctx->deleteTexture(boundImageTextureId); ctx->deleteTexture(boundPixmapTextureId); - QCOMPARE((bool)funcs->glIsTexture(boundImageTextureId), GL_FALSE); - QCOMPARE((bool)funcs->glIsTexture(boundPixmapTextureId), GL_FALSE); + QCOMPARE(funcs->glIsTexture(boundImageTextureId), GLboolean(GL_FALSE)); + QCOMPARE(funcs->glIsTexture(boundPixmapTextureId), GLboolean(GL_FALSE)); } #endif diff --git a/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp b/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp index b0409d46d0207c29f9af33a650a2913c0d61d0d2..f96e3514a728e07ce7e15e04336ec34a76df7f36 100644 --- a/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp +++ b/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp @@ -86,14 +86,14 @@ void tst_QGLBuffer::testBuffer(QGLBuffer::Type type) // Create the local object, but not the buffer in the server. QGLBuffer buffer(type); - QVERIFY(buffer.usagePattern() == QGLBuffer::StaticDraw); + QCOMPARE(buffer.usagePattern(), QGLBuffer::StaticDraw); buffer.setUsagePattern(QGLBuffer::UsagePattern(usagePattern)); // Check the initial state. - QVERIFY(buffer.type() == type); + QCOMPARE(buffer.type(), type); QVERIFY(!buffer.isCreated()); - QVERIFY(buffer.bufferId() == 0); - QVERIFY(buffer.usagePattern() == QGLBuffer::UsagePattern(usagePattern)); + QCOMPARE(buffer.bufferId(), GLuint(0)); + QCOMPARE(buffer.usagePattern(), QGLBuffer::UsagePattern(usagePattern)); QCOMPARE(buffer.size(), -1); // Should not be able to bind it yet because it isn't created. @@ -253,7 +253,7 @@ void tst_QGLBuffer::bufferSharing() delete w2; // The buffer should now be invalid. - QVERIFY(buffer.bufferId() == 0); + QCOMPARE(buffer.bufferId(), GLuint(0)); QVERIFY(!buffer.isCreated()); } diff --git a/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp b/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp index 866cd573810883fa61d3e59e6e6c9f6c7f0edc1d..07fdba466440d13353cf7b7fa3fce7054c796e04 100644 --- a/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp +++ b/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp @@ -200,13 +200,13 @@ void tst_QGLFunctions::multitexture() GLint active = 0; funcs.glGetIntegerv(GL_ACTIVE_TEXTURE, &active); - QVERIFY(active == GL_TEXTURE1); + QCOMPARE(active, GL_TEXTURE1); funcs.glActiveTexture(GL_TEXTURE0); active = 0; funcs.glGetIntegerv(GL_ACTIVE_TEXTURE, &active); - QVERIFY(active == GL_TEXTURE0); + QCOMPARE(active, GL_TEXTURE0); } // Verify that the glBlendColor() function appears to resolve and work. diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp index 8f7dcdb3c53e3fb1799ddb8520ddf9bb3bde2781..5ef247483de1d2d16e6cb1492ab7f965956f4138 100644 --- a/tests/auto/other/compiler/tst_compiler.cpp +++ b/tests/auto/other/compiler/tst_compiler.cpp @@ -336,17 +336,17 @@ struct Qxxx {}; void tst_Compiler::detectDataStream() { - QVERIFY(QtTestInternal::DataStreamChecker<int>::HasDataStream == true); - QVERIFY(QtTestInternal::DataStreamChecker<uint>::HasDataStream == true); + QVERIFY(QtTestInternal::DataStreamChecker<int>::HasDataStream); + QVERIFY(QtTestInternal::DataStreamChecker<uint>::HasDataStream); QVERIFY(QtTestInternal::DataStreamChecker<char *>::HasDataStream == true); QVERIFY(QtTestInternal::DataStreamChecker<const int>::HasInDataStream == true); QVERIFY(QtTestInternal::DataStreamChecker<const int>::HasOutDataStream == false); QVERIFY(QtTestInternal::DataStreamChecker<const int>::HasDataStream == false); - QVERIFY(QtTestInternal::DataStreamChecker<double>::HasDataStream == true); + QVERIFY(QtTestInternal::DataStreamChecker<double>::HasDataStream); - QVERIFY(QtTestInternal::DataStreamChecker<QString>::HasDataStream == true); - QVERIFY(QtTestInternal::DataStreamChecker<MyString>::HasDataStream == true); - QVERIFY(QtTestInternal::DataStreamChecker<Qxxx>::HasDataStream == false); + QVERIFY(QtTestInternal::DataStreamChecker<QString>::HasDataStream); + QVERIFY(QtTestInternal::DataStreamChecker<MyString>::HasDataStream); + QVERIFY(!QtTestInternal::DataStreamChecker<Qxxx>::HasDataStream); QVERIFY(QtTestInternal::getSaveOperator<int>() != 0); QVERIFY(QtTestInternal::getSaveOperator<uint>() != 0); @@ -354,7 +354,7 @@ void tst_Compiler::detectDataStream() QVERIFY(QtTestInternal::getSaveOperator<double>() != 0); QVERIFY(QtTestInternal::getSaveOperator<QString>() != 0); QVERIFY(QtTestInternal::getSaveOperator<MyString>() != 0); - QVERIFY(QtTestInternal::getSaveOperator<Qxxx>() == 0); + QVERIFY(!QtTestInternal::getSaveOperator<Qxxx>()); } #else void tst_Compiler::detectDataStream() @@ -637,7 +637,7 @@ void tst_Compiler::cxx11_alignas() QSKIP("Compiler does not support C++11 feature"); #else alignas(double) char c; - QVERIFY(Q_ALIGNOF(c) == Q_ALIGNOF(double)); + QCOMPARE(Q_ALIGNOF(c), Q_ALIGNOF(double)); #endif } diff --git a/tests/auto/other/gestures/BLACKLIST b/tests/auto/other/gestures/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..4e8745ca78938ba851fcac337d17632392bb14d8 --- /dev/null +++ b/tests/auto/other/gestures/BLACKLIST @@ -0,0 +1,2 @@ +[customGesture] +opensuse-13.1 diff --git a/tests/auto/other/gestures/tst_gestures.cpp b/tests/auto/other/gestures/tst_gestures.cpp index 43ce6b2d729b9b67a8f986500fd7e7672c482546..2a4f88c62745532afb432341a346e956062a0772 100644 --- a/tests/auto/other/gestures/tst_gestures.cpp +++ b/tests/auto/other/gestures/tst_gestures.cpp @@ -1461,7 +1461,7 @@ void tst_Gestures::ungrabGesture() // a method on QWidget QPointer<QGesture> customGestureB; customGestureB = *(b->gestures.begin()); QVERIFY(!customGestureB.isNull()); - QVERIFY(customGestureA.data() == customGestureB.data()); + QCOMPARE(customGestureA.data(), customGestureB.data()); QCOMPARE(customGestureB->gestureType(), CustomGesture::GestureType); a->gestures.clear(); diff --git a/tests/auto/other/lancelot/paintcommands.cpp b/tests/auto/other/lancelot/paintcommands.cpp index caca0f2ebdb95357f2b582acae19190a13eb0d03..4fc41fd64983af9bf2bd2b5121c547def1b41239 100644 --- a/tests/auto/other/lancelot/paintcommands.cpp +++ b/tests/auto/other/lancelot/paintcommands.cpp @@ -2383,7 +2383,10 @@ void PaintCommands::command_surface_begin(QRegExp re) m_surface_glbuffer->bind(); m_surface_glpaintdevice = new QOpenGLPaintDevice(qRound(w), qRound(h)); m_painter = new QPainter(m_surface_glpaintdevice); + m_painter->save(); + m_painter->setCompositionMode(QPainter::CompositionMode_Clear); m_painter->fillRect(QRect(0, 0, qRound(w), qRound(h)), Qt::transparent); + m_painter->restore(); #endif #ifdef Q_DEAD_CODE_FROM_QT4_X11 } else if (m_type == WidgetType) { diff --git a/tests/auto/other/lancelot/scripts/arcs2.qps b/tests/auto/other/lancelot/scripts/arcs2.qps index 411ff080145b6c4d6d9f62117b4a1334498dde64..a2739a8c9760549dde0bb9ecae00e02136a3300c 100644 --- a/tests/auto/other/lancelot/scripts/arcs2.qps +++ b/tests/auto/other/lancelot/scripts/arcs2.qps @@ -45,3 +45,10 @@ drawArc 100 350 300 300 5440 5760 drawArc 100 350 300 300 5600 5760 setPen white drawArc 100 350 300 300 0 5760 + +translate 400 300 +setRenderHint Antialiasing true +setPen blue 40 +drawArc 100 100 200 200 0 4320 +setPen red 40 +drawArc 60 60 280 280 0 4320 diff --git a/tests/auto/other/lancelot/scripts/text.qps b/tests/auto/other/lancelot/scripts/text.qps index 344c7a813dc4b96c530e871a8efe23ec114fdfd9..169549a5bde3622810e392762c9174381037cedf 100644 --- a/tests/auto/other/lancelot/scripts/text.qps +++ b/tests/auto/other/lancelot/scripts/text.qps @@ -159,4 +159,11 @@ save setPen black drawText 0 70 "testing glyph cache textures" -restore \ No newline at end of file +restore + +translate 0 75 +save + setPen black + setFont "sansserif" 16 normal + drawText 0 40 "e😃m😇oðŸ˜j😜i😸!" +restore diff --git a/tests/auto/other/macgui/tst_macgui.cpp b/tests/auto/other/macgui/tst_macgui.cpp index 56035f4be4857113039146da4685fa8bf13841e0..ba6ac536f21c427fe2145cf533b40830302cb036 100644 --- a/tests/auto/other/macgui/tst_macgui.cpp +++ b/tests/auto/other/macgui/tst_macgui.cpp @@ -146,7 +146,7 @@ void tst_MacGui::splashScreenModality() connect(wn.getWidget(interface), SIGNAL(clicked()), SLOT(exitLoopSlot())); const int timeout = 4; QTestEventLoop::instance().enterLoop(timeout); - QVERIFY(QTestEventLoop::instance().timeout() == false); + QVERIFY(!QTestEventLoop::instance().timeout()); } class PrimaryWindowDialog : public QDialog @@ -231,7 +231,7 @@ void tst_MacGui::spinBoxArrowButtons() const QRect lessRect = lessInterface->rect(); const QRect lessLocalRect(colorWidget.mapFromGlobal(lessRect.topLeft()), colorWidget.mapFromGlobal(lessRect.bottomRight())); const QRect compareRect = lessLocalRect.adjusted(5, 3, -5, -7); - QVERIFY(noFocus.copy(compareRect) == focus.copy(compareRect)); + QCOMPARE(noFocus.copy(compareRect), focus.copy(compareRect)); } QTEST_MAIN(tst_MacGui) diff --git a/tests/auto/other/macnativeevents/BLACKLIST b/tests/auto/other/macnativeevents/BLACKLIST index 2820457075dfc3a5805f65dce91dcbd5f90a69f4..4129868022c98e209079cc712764ea09f3308e9a 100644 --- a/tests/auto/other/macnativeevents/BLACKLIST +++ b/tests/auto/other/macnativeevents/BLACKLIST @@ -3,9 +3,22 @@ osx [testMouseEnter] osx-10.9 +osx-10.8 [testChildDialogInFrontOfModalParent] osx [testChildWindowInFrontOfStaysOnTopParentWindow] osx [testModifierCtrlWithDontSwapCtrlAndMeta] osx +[testMouseMoveLocation] +osx +[testMouseLeftDoubleClick] +osx +[stressTestMouseLeftDoubleClick] +osx +[testMouseDragInside] +osx +[testMouseDragOutside] +osx +[testMouseDragToNonClientArea] +osx diff --git a/tests/auto/other/macnativeevents/tst_macnativeevents.cpp b/tests/auto/other/macnativeevents/tst_macnativeevents.cpp index 5d24655144935abf7170362028c435b76776b283..d1c5e4a35ee34871e03b665aaa0b416b629c6262 100644 --- a/tests/auto/other/macnativeevents/tst_macnativeevents.cpp +++ b/tests/auto/other/macnativeevents/tst_macnativeevents.cpp @@ -457,8 +457,8 @@ void tst_MacNativeEvents::testModifierCtrl() QWidget w; w.show(); - QVERIFY(kControlUnicode == QKeySequence(Qt::Key_Meta).toString(QKeySequence::NativeText)[0]); - QVERIFY(kCommandUnicode == QKeySequence(Qt::Key_Control).toString(QKeySequence::NativeText)[0]); + QCOMPARE(ushort(kControlUnicode), QKeySequence(Qt::Key_Meta).toString(QKeySequence::NativeText).at(0).unicode()); + QCOMPARE(ushort(kCommandUnicode), QKeySequence(Qt::Key_Control).toString(QKeySequence::NativeText).at(0).unicode()); NativeEventList native; native.append(new QNativeModifierEvent(Qt::ControlModifier)); @@ -490,8 +490,8 @@ void tst_MacNativeEvents::testModifierCtrlWithDontSwapCtrlAndMeta() QWidget w; w.show(); - QVERIFY(kCommandUnicode == QKeySequence(Qt::Key_Meta).toString(QKeySequence::NativeText)[0]); - QVERIFY(kControlUnicode == QKeySequence(Qt::Key_Control).toString(QKeySequence::NativeText)[0]); + QCOMPARE(ushort(kCommandUnicode), QKeySequence(Qt::Key_Meta).toString(QKeySequence::NativeText).at(0).unicode()); + QCOMPARE(ushort(kControlUnicode), QKeySequence(Qt::Key_Control).toString(QKeySequence::NativeText).at(0).unicode()); NativeEventList native; native.append(new QNativeModifierEvent(Qt::ControlModifier)); diff --git a/tests/auto/other/modeltest/modeltest.cpp b/tests/auto/other/modeltest/modeltest.cpp index 72a4a0ad29682f98a8a93313bd90e70a155463e3..c119fdaa4e542048a1ca6c1f831357a02d1cc828 100644 --- a/tests/auto/other/modeltest/modeltest.cpp +++ b/tests/auto/other/modeltest/modeltest.cpp @@ -569,7 +569,7 @@ void ModelTest::dataChanged(const QModelIndex &topLeft, const QModelIndex &botto QVERIFY(topLeft.isValid()); QVERIFY(bottomRight.isValid()); QModelIndex commonParent = bottomRight.parent(); - QVERIFY(topLeft.parent() == commonParent); + QCOMPARE(topLeft.parent(), commonParent); QVERIFY(topLeft.row() <= bottomRight.row()); QVERIFY(topLeft.column() <= bottomRight.column()); int rowCount = model->rowCount(commonParent); diff --git a/tests/auto/other/networkselftest/tst_networkselftest.cpp b/tests/auto/other/networkselftest/tst_networkselftest.cpp index 5612260cca20316e7f0c2e8452b313fb0e47588a..7ce385121cb32835a7e3a246e7a1e9898e69d763 100644 --- a/tests/auto/other/networkselftest/tst_networkselftest.cpp +++ b/tests/auto/other/networkselftest/tst_networkselftest.cpp @@ -34,6 +34,8 @@ #include <QtTest/QtTest> #include <QtNetwork/QtNetwork> #include <QtCore/QDateTime> +#include <QtCore/QTextStream> +#include <QtCore/QStandardPaths> #include <QtCore/private/qiodevice_p.h> #ifndef QT_NO_BEARERMANAGEMENT @@ -460,7 +462,7 @@ void tst_NetworkSelfTest::remotePortsOpen() else QFAIL(QString("Error connecting to server on port %1: %2").arg(portNumber).arg(socket.errorString()).toLocal8Bit()); } - QVERIFY(socket.state() == QAbstractSocket::ConnectedState); + QCOMPARE(socket.state(), QAbstractSocket::ConnectedState); } static QList<Chat> ftpChat(const QByteArray &userSuffix = QByteArray()) @@ -960,6 +962,25 @@ void tst_NetworkSelfTest::supportsSsl() #endif } +#ifndef QT_NO_PROCESS +static const QByteArray msgProcessError(const QProcess &process, const char *what) +{ + QString result; + QTextStream(&result) << what << ": \"" << process.program() << ' ' + << process.arguments().join(QLatin1Char(' ')) << "\": " << process.errorString(); + return result.toLocal8Bit(); +} + +static void ensureTermination(QProcess &process) +{ + if (process.state() == QProcess::Running) { + process.terminate(); + if (!process.waitForFinished(300)) + process.kill(); + } +} +#endif // !QT_NO_PROCESS + void tst_NetworkSelfTest::smbServer() { static const char contents[] = "This is 34 bytes. Do not change..."; @@ -977,19 +998,24 @@ void tst_NetworkSelfTest::smbServer() QVERIFY(memcmp(buf, contents, strlen(contents)) == 0); #else #ifndef QT_NO_PROCESS + enum { sambaTimeOutSecs = 5 }; // try to use Samba - QString progname = "smbclient"; - QProcess smbclient; - smbclient.start(progname, QIODevice::ReadOnly); - if (!smbclient.waitForStarted(2000)) + const QString progname = "smbclient"; + const QString binary = QStandardPaths::findExecutable(progname); + if (binary.isEmpty()) QSKIP("Could not find smbclient (from Samba), cannot continue testing"); - if (!smbclient.waitForFinished(2000) || smbclient.exitStatus() != QProcess::NormalExit) - QSKIP("smbclient isn't working, cannot continue testing"); - smbclient.close(); // try listing the server - smbclient.start(progname, QStringList() << "-g" << "-N" << "-L" << QtNetworkSettings::winServerName(), QIODevice::ReadOnly); - QVERIFY(smbclient.waitForFinished(5000)); + const QStringList timeOutArguments = QStringList() + << "--timeout" << QString::number(sambaTimeOutSecs); + QStringList arguments = timeOutArguments; + arguments << "-g" << "-N" << "-L" << QtNetworkSettings::winServerName(); + QProcess smbclient; + smbclient.start(binary, arguments, QIODevice::ReadOnly); + QVERIFY2(smbclient.waitForStarted(), msgProcessError(smbclient, "Unable to start")); + const bool listFinished = smbclient.waitForFinished((1 + sambaTimeOutSecs) * 1000); + ensureTermination(smbclient); + QVERIFY2(listFinished, msgProcessError(smbclient, "Listing servers timed out")); if (smbclient.exitStatus() != QProcess::NormalExit) QSKIP("smbclient crashed"); QVERIFY2(smbclient.exitCode() == 0, "Test server not found"); @@ -1004,9 +1030,13 @@ void tst_NetworkSelfTest::smbServer() QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert("PAGER", "/bin/cat"); // just in case smbclient.setProcessEnvironment(env); - smbclient.start(progname, QStringList() << "-N" << "-c" << "more test.pri" - << QString("\\\\%1\\testshare").arg(QtNetworkSettings::winServerName()), QIODevice::ReadOnly); - QVERIFY(smbclient.waitForFinished(5000)); + arguments = timeOutArguments; + arguments << "-N" << "-c" << "more test.pri" + << ("\\\\" + QtNetworkSettings::winServerName() + "\\testshare"); + smbclient.start(binary, arguments, QIODevice::ReadOnly); + const bool fileFinished = smbclient.waitForFinished((1 + sambaTimeOutSecs) * 1000); + ensureTermination(smbclient); + QVERIFY2(fileFinished, msgProcessError(smbclient, "Timed out")); if (smbclient.exitStatus() != QProcess::NormalExit) QSKIP("smbclient crashed"); QVERIFY2(smbclient.exitCode() == 0, "File //qt-test-server/testshare/test.pri not found"); diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro index 8c911da2e09b0982dbfec1dda5b410cc2c344b26..673e922fdd339b3643496fd1c21fbcca71e942f2 100644 --- a/tests/auto/other/other.pro +++ b/tests/auto/other/other.pro @@ -58,7 +58,7 @@ wince*|!contains(QT_CONFIG, accessibility): SUBDIRS -= qaccessibility macplist \ qaccessibilitymac -!embedded|wince*: SUBDIRS -= \ +!embedded|wince: SUBDIRS -= \ qdirectpainter winrt: SUBDIRS -= \ diff --git a/tests/auto/other/qaccessibility/qaccessibility.pro b/tests/auto/other/qaccessibility/qaccessibility.pro index 70cced1dac1d94d66f4b2998246e94ecc4c987f2..1d6fc6bcd1facbb7bed96afc42181e969ee4728e 100644 --- a/tests/auto/other/qaccessibility/qaccessibility.pro +++ b/tests/auto/other/qaccessibility/qaccessibility.pro @@ -7,7 +7,7 @@ HEADERS += accessiblewidgets.h unix:!mac:!haiku:LIBS+=-lm -wince*: { +wince { accessneeded.files = $$QT_BUILD_TREE\\plugins\\accessible\\*.dll accessneeded.path = accessible DEPLOYMENT += accessneeded diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 92a8623a648d0f46d9d57e2c6f303c7320d14a1b..69007bd250b9bb163cb21b2e92862f92ed21a6f1 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -452,15 +452,15 @@ void tst_QAccessibility::statesStructTest() QVERIFY(s1.modal == 0); QAccessible::State s2; - QVERIFY(s2 == s1); + QCOMPARE(s2, s1); s2.busy = true; QVERIFY(!(s2 == s1)); s1.busy = true; - QVERIFY(s2 == s1); + QCOMPARE(s2, s1); s1 = QAccessible::State(); QVERIFY(!(s2 == s1)); s1 = s2; - QVERIFY(s2 == s1); + QCOMPARE(s2, s1); QVERIFY(s1.busy == 1); } @@ -523,9 +523,9 @@ void tst_QAccessibility::navigateHierarchy() QVERIFY(ifaceW->isValid()); QAccessibleInterface *target = ifaceW->child(14); - QVERIFY(target == 0); + QVERIFY(!target); target = ifaceW->child(-1); - QVERIFY(target == 0); + QVERIFY(!target); target = ifaceW->child(0); QAccessibleInterface *interfaceW1(ifaceW->child(0)); QVERIFY(target); @@ -541,7 +541,7 @@ void tst_QAccessibility::navigateHierarchy() QCOMPARE(target->object(), (QObject*)w3); QAccessibleInterface *child = target->child(1); - QVERIFY(child == 0); + QVERIFY(!child); child = target->child(0); QVERIFY(child != 0); QVERIFY(child->isValid()); @@ -959,7 +959,7 @@ void tst_QAccessibility::mainWindowTest() QWindow window; window.setGeometry(80, 80, 40, 40); window.show(); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); // We currently don't have an accessible interface for QWindow // the active state is either in the QMainWindow or QQuickView @@ -1303,7 +1303,7 @@ void tst_QAccessibility::tabTest() QCOMPARE(child1->text(QAccessible::Description), QLatin1String("Cool tool tip")); QCOMPARE(child1->text(QAccessible::Help), QLatin1String("I don't know")); - QVERIFY((child1->state().invisible) == false); + QVERIFY(!(child1->state().invisible)); tabBar->hide(); QCoreApplication::processEvents(); @@ -1650,7 +1650,7 @@ void tst_QAccessibility::spinBoxTest() // make sure that the line edit is not there const int numChildren = interface->childCount(); QCOMPARE(numChildren, 0); - QVERIFY(interface->child(0) == Q_NULLPTR); + QVERIFY(!interface->child(0)); QVERIFY(interface->valueInterface()); QCOMPARE(interface->valueInterface()->currentValue().toInt(), 3); @@ -1736,6 +1736,13 @@ static bool fuzzyRectCompare(const QRect &a, const QRect &b) && qAbs(delta.right()) <= MAX_ACCEPTABLE_DELTA && qAbs(delta.bottom()) <= MAX_ACCEPTABLE_DELTA; } +static QByteArray msgRectMismatch(const QRect &a, const QRect &b) +{ + QString result; + QDebug(&result) << a << "!=" << b; + return result.toLocal8Bit(); +} + void tst_QAccessibility::textEditTest() { for (int pass = 0; pass < 2; ++pass) { @@ -1781,16 +1788,24 @@ void tst_QAccessibility::textEditTest() int offset = 10; QCOMPARE(textIface->text(offset, offset + 1), QStringLiteral("d")); - QVERIFY(fuzzyRectCompare(textIface->characterRect(offset), characterRect(edit, offset))); + const QRect actual10 = textIface->characterRect(offset); + const QRect expected10 = characterRect(edit, offset); + QVERIFY2(fuzzyRectCompare(actual10, expected10), msgRectMismatch(actual10, expected10).constData()); offset = 13; QCOMPARE(textIface->text(offset, offset + 1), QStringLiteral("H")); - QVERIFY(fuzzyRectCompare(textIface->characterRect(offset), characterRect(edit, offset))); + const QRect actual13 = textIface->characterRect(offset); + const QRect expected13 = characterRect(edit, offset); + QVERIFY2(fuzzyRectCompare(actual13, expected13), msgRectMismatch(actual13, expected13).constData()); offset = 21; QCOMPARE(textIface->text(offset, offset + 1), QStringLiteral("y")); - QVERIFY(fuzzyRectCompare(textIface->characterRect(offset), characterRect(edit, offset))); + const QRect actual21 = textIface->characterRect(offset); + const QRect expected21 = characterRect(edit, offset); + QVERIFY2(fuzzyRectCompare(actual21, expected21), msgRectMismatch(actual21, expected21).constData()); offset = 32; QCOMPARE(textIface->text(offset, offset + 1), QStringLiteral("I")); - QVERIFY(fuzzyRectCompare(textIface->characterRect(offset), characterRect(edit, offset))); + const QRect actual32 = textIface->characterRect(offset); + const QRect expected32 = characterRect(edit, offset); + QVERIFY2(fuzzyRectCompare(actual32, expected32), msgRectMismatch(actual32, expected32).constData()); QTestAccessibility::clearEvents(); @@ -2471,7 +2486,7 @@ void tst_QAccessibility::groupBoxTest() QCOMPARE(iface->text(QAccessible::Name), QLatin1String("Test QGroupBox")); QCOMPARE(iface->text(QAccessible::Description), QLatin1String("This group box will be used to test accessibility")); QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > relations = rButtonIface->relations(); - QVERIFY(relations.size() == 1); + QCOMPARE(relations.size(), 1); QPair<QAccessibleInterface*, QAccessible::Relation> relation = relations.first(); QCOMPARE(relation.first->object(), groupBox); QCOMPARE(relation.second, QAccessible::Label); @@ -3516,13 +3531,13 @@ void tst_QAccessibility::dockWidgetTest() QPoint buttonPoint = pb2->mapToGlobal(QPoint(pb2->width()/2, pb2->height()/2)); QAccessibleInterface *childAt = accDock2->childAt(buttonPoint.x(), buttonPoint.y()); QVERIFY(childAt); - QVERIFY(childAt->object() == pb2); + QCOMPARE(childAt->object(), pb2); QWidget *close1 = qobject_cast<QWidget*>(dock1Close->object()); QPoint close1ButtonPoint = close1->mapToGlobal(QPoint(close1->width()/2, close1->height()/2)); QAccessibleInterface *childAt2 = accDock1->childAt(close1ButtonPoint.x(), close1ButtonPoint.y()); QVERIFY(childAt2); - QVERIFY(childAt2->object() == close1); + QCOMPARE(childAt2->object(), close1); // custom title bar widget QDockWidget *dock3 = new QDockWidget(mw); diff --git a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm index d0ff6af6405001cf455762f869ba1082849ba5f0..3056904dcf08d9cdde0409d47aaf432c3dcda1ed 100644 --- a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm +++ b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm @@ -129,7 +129,7 @@ QDebug operator<<(QDebug dbg, AXErrorTag err) - (AXUIElementRef) ref { return reference; } - (void) print { - NSLog(@"Accessible Object role: '%@', title: '%@', description: '%@', value: '%@', rect: '%@'", self.role, self.title, self.description, self.value, NSStringFromRect(self.rect)); + NSLog(@"Accessible Object role: '%@', title: '%@', description: '%@', value: '%@', rect: '%@'", self.role, self.title, self.description, self.value, NSStringFromRect(NSRectFromCGRect(self.rect))); NSLog(@" Children: %ld", [[self childList] count]); } diff --git a/tests/auto/other/qcomplextext/tst_qcomplextext.cpp b/tests/auto/other/qcomplextext/tst_qcomplextext.cpp index a9234b7060548fdbee3ed7699cbc7f8454db3813..1428a63123d88ac08385f6ac058986ef82b9a43e 100644 --- a/tests/auto/other/qcomplextext/tst_qcomplextext.cpp +++ b/tests/auto/other/qcomplextext/tst_qcomplextext.cpp @@ -173,7 +173,7 @@ void tst_QComplexText::bidiCursor_qtbug2795() qreal x2 = line2.cursorToX(0) - line2.cursorToX(str.size()); // The cursor should remain at the same position after a digit is appended - QVERIFY(x1 == x2); + QCOMPARE(x1, x2); } void tst_QComplexText::bidiCursorMovement_data() diff --git a/tests/auto/other/windowsmobile/test/tst_windowsmobile.cpp b/tests/auto/other/windowsmobile/test/tst_windowsmobile.cpp index b161dccb88a031e4dc6228c2f102bc5f01e353e4..acb0d28c6bb14216ec8ec4ec874c34c94b15a533 100644 --- a/tests/auto/other/windowsmobile/test/tst_windowsmobile.cpp +++ b/tests/auto/other/windowsmobile/test/tst_windowsmobile.cpp @@ -132,7 +132,7 @@ void compareScreenshots(const QString &image1, const QString &image2) //screenShot.save("scr2.png", "PNG"); //original.save("orig1.png", "PNG"); - QVERIFY(original == screenShot); + QCOMPARE(original, screenShot); } void takeScreenShot(const QString filename) diff --git a/tests/auto/printsupport/kernel/qprintdevice/tst_qprintdevice.cpp b/tests/auto/printsupport/kernel/qprintdevice/tst_qprintdevice.cpp index 598abca43b204aa5efb9bc0730cc155e8003b4cd..f3b865ed92aae73224b372b7044cc44ae62d24fb 100644 --- a/tests/auto/printsupport/kernel/qprintdevice/tst_qprintdevice.cpp +++ b/tests/auto/printsupport/kernel/qprintdevice/tst_qprintdevice.cpp @@ -57,7 +57,6 @@ void tst_QPrintDevice::basics() if (defaultId.isEmpty()) { qDebug() << "No default printer found"; } else { - qDebug() << "Default Printer ID :" << defaultId; QVERIFY(ps->availablePrintDeviceIds().contains(defaultId)); } @@ -66,7 +65,9 @@ void tst_QPrintDevice::basics() // Just exercise the api for now as we don't know what is installed foreach (const QString id, ps->availablePrintDeviceIds()) { QPrintDevice printDevice = ps->createPrintDevice(id); - qDebug() << "Created printer" << id; + const char quote = id == defaultId ? '*' : '"'; + qDebug().noquote().nospace() << "\nCreated printer " << quote << id + << quote << ":\n" << printDevice << '\n'; QCOMPARE(printDevice.isValid(), true); printDevice.id(); printDevice.name(); diff --git a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp index c256d9ba82ae214e63e57c4070ac785b930f7dad..318f87467c53a78eaf11f4c1d3cdb3002a8f452d 100644 --- a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp +++ b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp @@ -425,12 +425,12 @@ void tst_QPrinter::outputFormatFromSuffix() if (QPrinterInfo::availablePrinters().size() == 0) QSKIP("No printers available."); QPrinter p; - QVERIFY(p.outputFormat() == QPrinter::NativeFormat); + QCOMPARE(p.outputFormat(), QPrinter::NativeFormat); p.setOutputFileName("test.pdf"); TempFileCleanup tmpFile("test.pdf"); - QVERIFY(p.outputFormat() == QPrinter::PdfFormat); + QCOMPARE(p.outputFormat(), QPrinter::PdfFormat); p.setOutputFileName(QString()); - QVERIFY(p.outputFormat() == QPrinter::NativeFormat); + QCOMPARE(p.outputFormat(), QPrinter::NativeFormat); } void tst_QPrinter::testPageMargins_data() diff --git a/tests/auto/sql/kernel/qsql/qsql.pro b/tests/auto/sql/kernel/qsql/qsql.pro index 6bef8d4601c16b60d90372a0ed430056ef84cd19..03918f5d3da9b0f9ee2202c475e3e13fb08fb265 100644 --- a/tests/auto/sql/kernel/qsql/qsql.pro +++ b/tests/auto/sql/kernel/qsql/qsql.pro @@ -5,7 +5,7 @@ SOURCES += tst_qsql.cpp QT = core-private sql-private testlib -wince*: { +wince { DEPLOYMENT_PLUGIN += qsqlite } mingw: LIBS += -lws2_32 diff --git a/tests/auto/sql/kernel/qsqldatabase/qsqldatabase.pro b/tests/auto/sql/kernel/qsqldatabase/qsqldatabase.pro index d562e47c5523f7ee79807240e66b07224af39067..7da5b8bc8e5434b33596bc67394697f88e8fbc63 100644 --- a/tests/auto/sql/kernel/qsqldatabase/qsqldatabase.pro +++ b/tests/auto/sql/kernel/qsqldatabase/qsqldatabase.pro @@ -5,11 +5,11 @@ SOURCES += tst_qsqldatabase.cpp QT = core sql testlib core-private sql-private win32: { - !wince*: LIBS += -lws2_32 + !wince: LIBS += -lws2_32 else: LIBS += -lws2 } -wince*: { +wince { DEPLOYMENT_PLUGIN += qsqlite testData.files = testdata diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h index c499aed481036eb1361b4d1366a05b5c1c500de0..fe8a3689b02c73e0578f784f0b828d2fe4af84fd 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h +++ b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h @@ -261,8 +261,8 @@ public: // addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.qt-project.org" ); // addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.qt-project.org", 3307 ); -// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.qt-project.org", 3308, "CLIENT_COMPRESS=1;CLIENT_SSL=1" ); // MySQL 4.1.1 -// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.qt-project.org", 3309, "CLIENT_COMPRESS=1;CLIENT_SSL=1" ); // MySQL 5.0.18 Linux +// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.qt-project.org", 3308, "CLIENT_COMPRESS=1" ); // MySQL 4.1.1 +// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.qt-project.org", 3309, "CLIENT_COMPRESS=1" ); // MySQL 5.0.18 Linux // addDb( "QMYSQL3", "testdb", "troll", "trond", "silence.qt-project.org" ); // MySQL 5.1.36 Windows // addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql41.qt-project.org" ); // MySQL 4.1.22-2.el4 linux diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp index 1993f23672ed05eaaf50503770b0417353bdc31c..83cf0394f90d6444dea6e64bb9c034208914fa79 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp @@ -1569,11 +1569,11 @@ void tst_QSqlDatabase::ibase_numericFields() QCOMPARE(q.value(2).toString(), QString("%1").arg(num2)); QCOMPARE(QString("%1").arg(q.value(3).toDouble()), QString("%1").arg(num3)); QCOMPARE(QString("%1").arg(q.value(4).toDouble()), QString("%1").arg(num4)); - QVERIFY(q.value(0).type() == QVariant::Int); - QVERIFY(q.value(1).type() == QVariant::Double); - QVERIFY(q.value(2).type() == QVariant::Double); - QVERIFY(q.value(3).type() == QVariant::Double); - QVERIFY(q.value(4).type() == QVariant::Double); + QCOMPARE(q.value(0).type(), QVariant::Int); + QCOMPARE(q.value(1).type(), QVariant::Double); + QCOMPARE(q.value(2).type(), QVariant::Double); + QCOMPARE(q.value(3).type(), QVariant::Double); + QCOMPARE(q.value(4).type(), QVariant::Double); QCOMPARE(q.record().field(1).length(), 2); QCOMPARE(q.record().field(1).precision(), 1); @@ -1583,16 +1583,16 @@ void tst_QSqlDatabase::ibase_numericFields() QCOMPARE(q.record().field(3).precision(), 3); QCOMPARE(q.record().field(4).length(), 18); QCOMPARE(q.record().field(4).precision(), 4); - QVERIFY(q.record().field(0).requiredStatus() == QSqlField::Required); - QVERIFY(q.record().field(1).requiredStatus() == QSqlField::Optional); + QCOMPARE(q.record().field(0).requiredStatus(), QSqlField::Required); + QCOMPARE(q.record().field(1).requiredStatus(), QSqlField::Optional); } QSqlRecord r = db.record(tableName); - QVERIFY(r.field(0).type() == QVariant::Int); - QVERIFY(r.field(1).type() == QVariant::Double); - QVERIFY(r.field(2).type() == QVariant::Double); - QVERIFY(r.field(3).type() == QVariant::Double); - QVERIFY(r.field(4).type() == QVariant::Double); + QCOMPARE(r.field(0).type(), QVariant::Int); + QCOMPARE(r.field(1).type(), QVariant::Double); + QCOMPARE(r.field(2).type(), QVariant::Double); + QCOMPARE(r.field(3).type(), QVariant::Double); + QCOMPARE(r.field(4).type(), QVariant::Double); QCOMPARE(r.field(1).length(), 2); QCOMPARE(r.field(1).precision(), 1); QCOMPARE(r.field(2).length(), 5); @@ -1601,8 +1601,8 @@ void tst_QSqlDatabase::ibase_numericFields() QCOMPARE(r.field(3).precision(), 3); QCOMPARE(r.field(4).length(), 18); QCOMPARE(r.field(4).precision(), 4); - QVERIFY(r.field(0).requiredStatus() == QSqlField::Required); - QVERIFY(r.field(1).requiredStatus() == QSqlField::Optional); + QCOMPARE(r.field(0).requiredStatus(), QSqlField::Required); + QCOMPARE(r.field(1).requiredStatus(), QSqlField::Optional); } void tst_QSqlDatabase::ibase_fetchBlobs() @@ -2086,7 +2086,7 @@ void tst_QSqlDatabase::eventNotificationIBase() QCOMPARE(spy.count(), 1); QList<QVariant> arguments = spy.takeFirst(); - QVERIFY(arguments.at(0).toString() == procedureName); + QCOMPARE(arguments.at(0).toString(), procedureName); QVERIFY_SQL(*driver, unsubscribeFromNotification(procedureName)); q.exec(QString("DROP PROCEDURE %1").arg(procedureName)); } diff --git a/tests/auto/sql/kernel/qsqldriver/qsqldriver.pro b/tests/auto/sql/kernel/qsqldriver/qsqldriver.pro index 13674f7c9ebb6e1822780bbb953e0249f53ef5b1..5633840635ed57e040ac4cc7266ce9fc9f6e614e 100644 --- a/tests/auto/sql/kernel/qsqldriver/qsqldriver.pro +++ b/tests/auto/sql/kernel/qsqldriver/qsqldriver.pro @@ -5,7 +5,7 @@ SOURCES += tst_qsqldriver.cpp QT = core sql testlib core-private sql-private -wince*: { +wince { plugFiles.files = ../../../plugins/sqldrivers plugFiles.path = . DEPLOYMENT += plugFiles diff --git a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp index 7a12f66452219926886d616f150d625dd6575d39..70e09a2b801820f9a4f3a1df356afe3be458b06c 100644 --- a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp +++ b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp @@ -160,7 +160,7 @@ void tst_QSqlError::operators() error2.setType(QSqlError::NoError); error3.setType(QSqlError::UnknownError); - QVERIFY(error1 == error2); + QCOMPARE(error1, error2); QVERIFY(error1 != error3); } diff --git a/tests/auto/sql/kernel/qsqlquery/qsqlquery.pro b/tests/auto/sql/kernel/qsqlquery/qsqlquery.pro index 360d874f1aa353ea3e21c59f7e5a501c20488c32..a6be23892dd81e483719bf2ad0d3ce5bf55d3785 100644 --- a/tests/auto/sql/kernel/qsqlquery/qsqlquery.pro +++ b/tests/auto/sql/kernel/qsqlquery/qsqlquery.pro @@ -5,9 +5,9 @@ SOURCES += tst_qsqlquery.cpp QT = core sql testlib core-private sql-private -!wince*:win32:LIBS += -lws2_32 +win32:!wince: LIBS += -lws2_32 -wince*: { +wince { plugFiles.files = ../../../plugins/sqldrivers plugFiles.path = . DEPLOYMENT += plugFiles diff --git a/tests/auto/sql/kernel/qsqlthread/qsqlthread.pro b/tests/auto/sql/kernel/qsqlthread/qsqlthread.pro index 3249309bf4ab898efc5bd954a1d29a4ce1e62467..64d8c5ccfbad1828d7d0f690848ef4b5eb682c67 100644 --- a/tests/auto/sql/kernel/qsqlthread/qsqlthread.pro +++ b/tests/auto/sql/kernel/qsqlthread/qsqlthread.pro @@ -5,7 +5,7 @@ SOURCES += tst_qsqlthread.cpp QT = core sql testlib core-private sql-private -wince*: { +wince { plugFiles.files = ../../../plugins/sqldrivers plugFiles.path = . DEPLOYMENT += plugFiles diff --git a/tests/auto/sql/models/qsqlquerymodel/qsqlquerymodel.pro b/tests/auto/sql/models/qsqlquerymodel/qsqlquerymodel.pro index 7bcde084695a02624c6857a89e13630caa2509e6..bc627e072447dc4dfc6c4f8bb088f8a3596c71fc 100644 --- a/tests/auto/sql/models/qsqlquerymodel/qsqlquerymodel.pro +++ b/tests/auto/sql/models/qsqlquerymodel/qsqlquerymodel.pro @@ -5,7 +5,7 @@ SOURCES += tst_qsqlquerymodel.cpp QT += widgets sql testlib core-private sql-private -wince*: { +wince { DEPLOYMENT_PLUGIN += qsqlite LIBS += -lws2 } else { diff --git a/tests/auto/sql/models/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro b/tests/auto/sql/models/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro index 6bcc3a1870d35a0ce3d3d49f102c27cbcb9e5606..5ce1b5694c3ebffc84e8506055c9f30950876500 100644 --- a/tests/auto/sql/models/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro +++ b/tests/auto/sql/models/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro @@ -5,7 +5,7 @@ SOURCES += tst_qsqlrelationaltablemodel.cpp QT = core sql testlib core-private sql-private -wince*: { +wince { plugFiles.files = ../../../plugins/sqldrivers plugFiles.path = . DEPLOYMENT += plugFiles diff --git a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index 71ec2b6588ade47c7cdaa20f046e1ec064e10291..3702631275b447f6533d9f5acbef07a6568ab218 100644 --- a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -858,7 +858,7 @@ static void testRevert(QSqlRelationalTableModel &model) /* Now revert the newly inserted rows */ model.revertAll(); - QVERIFY(model.rowCount() == initialRowCount); + QCOMPARE(model.rowCount(), initialRowCount); /* Insert rows again */ QVERIFY(model.insertRows(4, 4)); @@ -1026,7 +1026,7 @@ void tst_QSqlRelationalTableModel::invalidData() QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); //try to set data in non valid index - QVERIFY(model.setData(model.index(0,10),5) == false); + QVERIFY(!model.setData(model.index(0,10),5)); //same test with LeftJoin mode model.setJoinMode(QSqlRelationalTableModel::LeftJoin); @@ -1037,7 +1037,7 @@ void tst_QSqlRelationalTableModel::invalidData() QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); //try to set data in non valid index - QVERIFY(model.setData(model.index(0,10),5) == false); + QVERIFY(!model.setData(model.index(0,10),5)); } void tst_QSqlRelationalTableModel::relationModel() @@ -1051,20 +1051,20 @@ void tst_QSqlRelationalTableModel::relationModel() model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); QVERIFY_SQL(model, select()); - QVERIFY(model.relationModel(0) == NULL); - QVERIFY(model.relationModel(1) == NULL); + QVERIFY(!model.relationModel(0)); + QVERIFY(!model.relationModel(1)); QVERIFY(model.relationModel(2) != NULL); - QVERIFY(model.relationModel(3) == NULL); - QVERIFY(model.relationModel(4) == NULL); + QVERIFY(!model.relationModel(3)); + QVERIFY(!model.relationModel(4)); model.setRelation(3, QSqlRelation(reltest4, "id", "name")); QVERIFY_SQL(model, select()); - QVERIFY(model.relationModel(0) == NULL); - QVERIFY(model.relationModel(1) == NULL); + QVERIFY(!model.relationModel(0)); + QVERIFY(!model.relationModel(1)); QVERIFY(model.relationModel(2) != NULL); QVERIFY(model.relationModel(3) != NULL); - QVERIFY(model.relationModel(4) == NULL); + QVERIFY(!model.relationModel(4)); QSqlTableModel *rel_model = model.relationModel(2); QCOMPARE(rel_model->data(rel_model->index(0,1)).toString(), QString("herr")); @@ -1073,11 +1073,11 @@ void tst_QSqlRelationalTableModel::relationModel() model.setJoinMode(QSqlRelationalTableModel::LeftJoin); QVERIFY_SQL(model, select()); - QVERIFY(model.relationModel(0) == NULL); - QVERIFY(model.relationModel(1) == NULL); + QVERIFY(!model.relationModel(0)); + QVERIFY(!model.relationModel(1)); QVERIFY(model.relationModel(2) != NULL); QVERIFY(model.relationModel(3) != NULL); - QVERIFY(model.relationModel(4) == NULL); + QVERIFY(!model.relationModel(4)); QSqlTableModel *rel_model2 = model.relationModel(2); QCOMPARE(rel_model2->data(rel_model->index(0,1)).toString(), QString("herr")); @@ -1487,13 +1487,13 @@ void tst_QSqlRelationalTableModel::selectAfterUpdate() model.setTable(reltest1); model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); QVERIFY_SQL(model, select()); - QVERIFY(model.relationModel(2)->rowCount() == 2); + QCOMPARE(model.relationModel(2)->rowCount(), 2); { QSqlQuery q(db); QVERIFY_SQL(q, exec("insert into " + reltest2 + " values(3, 'mrs')")); model.relationModel(2)->select(); } - QVERIFY(model.relationModel(2)->rowCount() == 3); + QCOMPARE(model.relationModel(2)->rowCount(), 3); QVERIFY(model.setData(model.index(0,2), 3)); QVERIFY(model.submitAll()); QCOMPARE(model.data(model.index(0,2)), QVariant("mrs")); diff --git a/tests/auto/sql/models/qsqltablemodel/qsqltablemodel.pro b/tests/auto/sql/models/qsqltablemodel/qsqltablemodel.pro index 211c2f2c2e59d4e2ca49bb99c780409471229f5e..fedb41ba1d86c7bc0577e56d7ddb9f7771ab479f 100644 --- a/tests/auto/sql/models/qsqltablemodel/qsqltablemodel.pro +++ b/tests/auto/sql/models/qsqltablemodel/qsqltablemodel.pro @@ -5,7 +5,7 @@ SOURCES += tst_qsqltablemodel.cpp QT = core core-private sql sql-private testlib -wince*: { +wince { plugFiles.files = ../../../plugins/sqldrivers plugFiles.path = . DEPLOYMENT += plugFiles diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp index 9c351f4657f17087e888de853ffd9caff5484509..2ace79973b5bccc2dd9f2a06daeb90a3746a475d 100644 --- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp @@ -533,7 +533,7 @@ void tst_QSqlTableModel::setData() idx = model.index(0, 0); QVERIFY_SQL(model, setData(idx, QVariant(QVariant::Int))); val = model.data(idx); - QVERIFY(val == QVariant(QVariant::Int)); + QCOMPARE(val, QVariant(QVariant::Int)); QVERIFY(val.isNull()); QVERIFY_SQL(model, isDirty(idx)); QVERIFY_SQL(model, submitAll()); @@ -560,13 +560,13 @@ void tst_QSqlTableModel::setData() // initial state idx = model.index(0, 0); QSqlRecord rec = model.record(0); - QVERIFY(rec.value(0) == QVariant(QVariant::Int)); + QCOMPARE(rec.value(0), QVariant(QVariant::Int)); QVERIFY(rec.isNull(0)); QVERIFY(!rec.isGenerated(0)); // unchanged value, but causes column to be included in INSERT QVERIFY_SQL(model, setData(idx, QVariant(QVariant::Int))); rec = model.record(0); - QVERIFY(rec.value(0) == QVariant(QVariant::Int)); + QCOMPARE(rec.value(0), QVariant(QVariant::Int)); QVERIFY(rec.isNull(0)); QVERIFY(rec.isGenerated(0)); QVERIFY_SQL(model, submitAll()); @@ -1136,8 +1136,8 @@ void tst_QSqlTableModel::removeRows() QVERIFY_SQL(model, removeRows(0, 1)); QVERIFY_SQL(model, removeRows(1, 1)); QCOMPARE(beforeDeleteSpy.count(), 2); - QVERIFY(beforeDeleteSpy.at(0).at(0).toInt() == 0); - QVERIFY(beforeDeleteSpy.at(1).at(0).toInt() == 1); + QCOMPARE(beforeDeleteSpy.at(0).at(0).toInt(), 0); + QCOMPARE(beforeDeleteSpy.at(1).at(0).toInt(), 1); // deleted rows shown as empty until select QCOMPARE(model.rowCount(), 3); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("")); @@ -1172,11 +1172,11 @@ void tst_QSqlTableModel::removeRows() QCOMPARE(headerDataChangedSpy.at(1).at(1).toInt(), 0); QCOMPARE(headerDataChangedSpy.at(1).at(2).toInt(), 0); QCOMPARE(model.rowCount(), 3); - QVERIFY(beforeDeleteSpy.count() == 0); + QCOMPARE(beforeDeleteSpy.count(), 0); QVERIFY(model.submitAll()); - QVERIFY(beforeDeleteSpy.count() == 2); - QVERIFY(beforeDeleteSpy.at(0).at(0).toInt() == 0); - QVERIFY(beforeDeleteSpy.at(1).at(0).toInt() == 1); + QCOMPARE(beforeDeleteSpy.count(), 2); + QCOMPARE(beforeDeleteSpy.at(0).at(0).toInt(), 0); + QCOMPARE(beforeDeleteSpy.at(1).at(0).toInt(), 1); QCOMPARE(model.rowCount(), 1); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("vohi")); } diff --git a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp index 6b94dfb529843d1137b04a587cded93666e9fa15..6446fec51097270f0bc76f97f0a6cd914617ed6a 100644 --- a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp +++ b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp @@ -124,6 +124,8 @@ class tst_Cmptest: public QObject Q_OBJECT private slots: + void compare_unregistered_enums(); + void compare_registered_enums(); void compare_boolfuncs(); void compare_pointerfuncs(); void compare_tostring(); @@ -138,8 +140,26 @@ private slots: void compareQImages(); void compareQImages_data(); #endif + void verify(); + void verify2(); + void tryVerify(); + void tryVerify2(); }; +enum MyUnregisteredEnum { MyUnregisteredEnumValue1, MyUnregisteredEnumValue2 }; + +void tst_Cmptest::compare_unregistered_enums() +{ + QCOMPARE(MyUnregisteredEnumValue1, MyUnregisteredEnumValue1); + QCOMPARE(MyUnregisteredEnumValue1, MyUnregisteredEnumValue2); +} + +void tst_Cmptest::compare_registered_enums() +{ + QCOMPARE(Qt::ArrowCursor, Qt::ArrowCursor); + QCOMPARE(Qt::ArrowCursor, Qt::BusyCursor); +} + static bool boolfunc() { return true; } static bool boolfunc2() { return true; } @@ -371,7 +391,36 @@ void tst_Cmptest::compareQImages() QCOMPARE(opA, opB); } -#endif +#endif // QT_GUI_LIB + +static int opaqueFunc() +{ + return 42; +} + +void tst_Cmptest::verify() +{ + QVERIFY(opaqueFunc() > 2); + QVERIFY(opaqueFunc() < 2); +} + +void tst_Cmptest::verify2() +{ + QVERIFY2(opaqueFunc() > 2, QByteArray::number(opaqueFunc()).constData()); + QVERIFY2(opaqueFunc() < 2, QByteArray::number(opaqueFunc()).constData()); +} + +void tst_Cmptest::tryVerify() +{ + QTRY_VERIFY(opaqueFunc() > 2); + QTRY_VERIFY_WITH_TIMEOUT(opaqueFunc() < 2, 1); +} + +void tst_Cmptest::tryVerify2() +{ + QTRY_VERIFY2(opaqueFunc() > 2, QByteArray::number(opaqueFunc()).constData()); + QTRY_VERIFY2_WITH_TIMEOUT(opaqueFunc() < 2, QByteArray::number(opaqueFunc()).constData(), 1); +} QTEST_MAIN(tst_Cmptest) #include "tst_cmptest.moc" diff --git a/tests/auto/testlib/selftests/expected_cmptest.lightxml b/tests/auto/testlib/selftests/expected_cmptest.lightxml index 4a376b5c8b6f794a714e8feb937ee584e2e5e604..36929cec6bca60d2bd208f4959a714687653c514 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.lightxml +++ b/tests/auto/testlib/selftests/expected_cmptest.lightxml @@ -5,18 +5,32 @@ </Environment> <TestFunction name="initTestCase"> <Incident type="pass" file="" line="0" /> -<Duration msecs="0"/> + <Duration msecs="0"/> +</TestFunction> +<TestFunction name="compare_unregistered_enums"> +<Incident type="fail" file="tst_cmptest.cpp" line="154"> + <Description><![CDATA[Compared values are not the same]]></Description> +</Incident> + <Duration msecs="0"/> +</TestFunction> +<TestFunction name="compare_registered_enums"> +<Incident type="fail" file="tst_cmptest.cpp" line="160"> + <Description><![CDATA[Compared values are not the same + Actual (Qt::ArrowCursor): ArrowCursor + Expected (Qt::BusyCursor) : BusyCursor]]></Description> +</Incident> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compare_boolfuncs"> <Incident type="pass" file="" line="0" /> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compare_pointerfuncs"> <Incident type="pass" file="" line="0" /> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compare_tostring"> -<Incident type="fail" file="tst_cmptest.cpp" line="219"> +<Incident type="fail" file="tst_cmptest.cpp" line="231"> <DataTag><![CDATA[int, string]]></DataTag> <Description><![CDATA[Compared values are not the same Actual (actual) : QVariant(int,123) @@ -25,25 +39,25 @@ <Incident type="pass" file="" line="0"> <DataTag><![CDATA[both invalid]]></DataTag> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="219"> +<Incident type="fail" file="tst_cmptest.cpp" line="231"> <DataTag><![CDATA[null hash, invalid]]></DataTag> <Description><![CDATA[Compared values are not the same Actual (actual) : QVariant(QVariantHash) Expected (expected): QVariant()]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="219"> +<Incident type="fail" file="tst_cmptest.cpp" line="231"> <DataTag><![CDATA[string, null user type]]></DataTag> <Description><![CDATA[Compared values are not the same Actual (actual) : QVariant(QString,A simple string) Expected (expected): QVariant(PhonyClass)]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="219"> +<Incident type="fail" file="tst_cmptest.cpp" line="231"> <DataTag><![CDATA[both non-null user type]]></DataTag> <Description><![CDATA[Compared values are not the same Actual (actual) : QVariant(PhonyClass,<value not representable as string>) Expected (expected): QVariant(PhonyClass,<value not representable as string>)]]></Description> </Incident> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compareQStringLists"> <Incident type="pass" file="" line="0"> @@ -52,65 +66,65 @@ <Incident type="pass" file="" line="0"> <DataTag><![CDATA[equal lists]]></DataTag> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="313"> +<Incident type="fail" file="tst_cmptest.cpp" line="325"> <DataTag><![CDATA[last item different]]></DataTag> <Description><![CDATA[Compared lists differ at index 2. Actual (opA): "string3" Expected (opB): "DIFFERS"]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="313"> +<Incident type="fail" file="tst_cmptest.cpp" line="325"> <DataTag><![CDATA[second-last item different]]></DataTag> <Description><![CDATA[Compared lists differ at index 2. Actual (opA): "string3" Expected (opB): "DIFFERS"]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="313"> +<Incident type="fail" file="tst_cmptest.cpp" line="325"> <DataTag><![CDATA[prefix]]></DataTag> <Description><![CDATA[Compared lists have different sizes. Actual (opA) size: 2 Expected (opB) size: 1]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="313"> +<Incident type="fail" file="tst_cmptest.cpp" line="325"> <DataTag><![CDATA[short list second]]></DataTag> <Description><![CDATA[Compared lists have different sizes. Actual (opA) size: 12 Expected (opB) size: 1]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="313"> +<Incident type="fail" file="tst_cmptest.cpp" line="325"> <DataTag><![CDATA[short list first]]></DataTag> <Description><![CDATA[Compared lists have different sizes. Actual (opA) size: 1 Expected (opB) size: 12]]></Description> </Incident> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compareQListInt"> -<Incident type="fail" file="tst_cmptest.cpp" line="320"> +<Incident type="fail" file="tst_cmptest.cpp" line="332"> <Description><![CDATA[Compared lists differ at index 2. Actual (int1): 3 Expected (int2): 4]]></Description> </Incident> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compareQListDouble"> -<Incident type="fail" file="tst_cmptest.cpp" line="327"> +<Incident type="fail" file="tst_cmptest.cpp" line="339"> <Description><![CDATA[Compared lists differ at index 0. Actual (double1): 1.5 Expected (double2): 1]]></Description> </Incident> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compareQPixmaps"> <Incident type="pass" file="" line="0"> <DataTag><![CDATA[both null]]></DataTag> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="353"> +<Incident type="fail" file="tst_cmptest.cpp" line="365"> <DataTag><![CDATA[one null]]></DataTag> <Description><![CDATA[Compared QPixmaps differ. Actual (opA).isNull(): 1 Expected (opB).isNull(): 0]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="353"> +<Incident type="fail" file="tst_cmptest.cpp" line="365"> <DataTag><![CDATA[other null]]></DataTag> <Description><![CDATA[Compared QPixmaps differ. Actual (opA).isNull(): 0 @@ -119,29 +133,29 @@ <Incident type="pass" file="" line="0"> <DataTag><![CDATA[equal]]></DataTag> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="353"> +<Incident type="fail" file="tst_cmptest.cpp" line="365"> <DataTag><![CDATA[different size]]></DataTag> <Description><![CDATA[Compared QPixmaps differ in size. Actual (opA): 11x20 Expected (opB): 20x20]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="353"> +<Incident type="fail" file="tst_cmptest.cpp" line="365"> <DataTag><![CDATA[different pixels]]></DataTag> <Description><![CDATA[Compared values are not the same]]></Description> </Incident> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compareQImages"> <Incident type="pass" file="" line="0"> <DataTag><![CDATA[both null]]></DataTag> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="380"> +<Incident type="fail" file="tst_cmptest.cpp" line="392"> <DataTag><![CDATA[one null]]></DataTag> <Description><![CDATA[Compared QImages differ. Actual (opA).isNull(): 1 Expected (opB).isNull(): 0]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="380"> +<Incident type="fail" file="tst_cmptest.cpp" line="392"> <DataTag><![CDATA[other null]]></DataTag> <Description><![CDATA[Compared QImages differ. Actual (opA).isNull(): 0 @@ -150,26 +164,50 @@ <Incident type="pass" file="" line="0"> <DataTag><![CDATA[equal]]></DataTag> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="380"> +<Incident type="fail" file="tst_cmptest.cpp" line="392"> <DataTag><![CDATA[different size]]></DataTag> <Description><![CDATA[Compared QImages differ in size. Actual (opA): 11x20 Expected (opB): 20x20]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="380"> +<Incident type="fail" file="tst_cmptest.cpp" line="392"> <DataTag><![CDATA[different format]]></DataTag> <Description><![CDATA[Compared QImages differ in format. Actual (opA): 6 Expected (opB): 3]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="380"> +<Incident type="fail" file="tst_cmptest.cpp" line="392"> <DataTag><![CDATA[different pixels]]></DataTag> <Description><![CDATA[Compared values are not the same]]></Description> </Incident> -<Duration msecs="0"/> + <Duration msecs="0"/> +</TestFunction> +<TestFunction name="verify"> +<Incident type="fail" file="tst_cmptest.cpp" line="404"> + <Description><![CDATA['opaqueFunc() < 2' returned FALSE. ()]]></Description> +</Incident> + <Duration msecs="0"/> +</TestFunction> +<TestFunction name="verify2"> +<Incident type="fail" file="tst_cmptest.cpp" line="410"> + <Description><![CDATA['opaqueFunc() < 2' returned FALSE. (42)]]></Description> +</Incident> + <Duration msecs="0"/> +</TestFunction> +<TestFunction name="tryVerify"> +<Incident type="fail" file="tst_cmptest.cpp" line="416"> + <Description><![CDATA['opaqueFunc() < 2' returned FALSE. ()]]></Description> +</Incident> + <Duration msecs="0"/> +</TestFunction> +<TestFunction name="tryVerify2"> +<Incident type="fail" file="tst_cmptest.cpp" line="422"> + <Description><![CDATA['opaqueFunc() < 2' returned FALSE. (42)]]></Description> +</Incident> + <Duration msecs="0"/> </TestFunction> <TestFunction name="cleanupTestCase"> <Incident type="pass" file="" line="0" /> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <Duration msecs="0"/> diff --git a/tests/auto/testlib/selftests/expected_cmptest.txt b/tests/auto/testlib/selftests/expected_cmptest.txt index 9e8c56ed99f24be937401f191052f42a2cc2c63c..70c54704f94b10ff4d91e5cc92201d8928c6631b 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.txt +++ b/tests/auto/testlib/selftests/expected_cmptest.txt @@ -1,91 +1,105 @@ ********* Start testing of tst_Cmptest ********* -Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ +Config: Using QtTest library PASS : tst_Cmptest::initTestCase() +FAIL! : tst_Cmptest::compare_unregistered_enums() Compared values are not the same + Loc: [tst_cmptest.cpp(154)] +FAIL! : tst_Cmptest::compare_registered_enums() Compared values are not the same + Actual (Qt::ArrowCursor): ArrowCursor + Expected (Qt::BusyCursor) : BusyCursor + Loc: [tst_cmptest.cpp(160)] PASS : tst_Cmptest::compare_boolfuncs() PASS : tst_Cmptest::compare_pointerfuncs() FAIL! : tst_Cmptest::compare_tostring(int, string) Compared values are not the same Actual (actual) : QVariant(int,123) Expected (expected): QVariant(QString,hi) - Loc: [tst_cmptest.cpp(219)] + Loc: [tst_cmptest.cpp(231)] PASS : tst_Cmptest::compare_tostring(both invalid) FAIL! : tst_Cmptest::compare_tostring(null hash, invalid) Compared values are not the same Actual (actual) : QVariant(QVariantHash) Expected (expected): QVariant() - Loc: [tst_cmptest.cpp(219)] + Loc: [tst_cmptest.cpp(231)] FAIL! : tst_Cmptest::compare_tostring(string, null user type) Compared values are not the same Actual (actual) : QVariant(QString,A simple string) Expected (expected): QVariant(PhonyClass) - Loc: [tst_cmptest.cpp(219)] + Loc: [tst_cmptest.cpp(231)] FAIL! : tst_Cmptest::compare_tostring(both non-null user type) Compared values are not the same Actual (actual) : QVariant(PhonyClass,<value not representable as string>) Expected (expected): QVariant(PhonyClass,<value not representable as string>) - Loc: [tst_cmptest.cpp(219)] + Loc: [tst_cmptest.cpp(231)] PASS : tst_Cmptest::compareQStringLists(empty lists) PASS : tst_Cmptest::compareQStringLists(equal lists) FAIL! : tst_Cmptest::compareQStringLists(last item different) Compared lists differ at index 2. Actual (opA): "string3" Expected (opB): "DIFFERS" - Loc: [tst_cmptest.cpp(313)] + Loc: [tst_cmptest.cpp(325)] FAIL! : tst_Cmptest::compareQStringLists(second-last item different) Compared lists differ at index 2. Actual (opA): "string3" Expected (opB): "DIFFERS" - Loc: [tst_cmptest.cpp(313)] + Loc: [tst_cmptest.cpp(325)] FAIL! : tst_Cmptest::compareQStringLists(prefix) Compared lists have different sizes. Actual (opA) size: 2 Expected (opB) size: 1 - Loc: [tst_cmptest.cpp(313)] + Loc: [tst_cmptest.cpp(325)] FAIL! : tst_Cmptest::compareQStringLists(short list second) Compared lists have different sizes. Actual (opA) size: 12 Expected (opB) size: 1 - Loc: [tst_cmptest.cpp(313)] + Loc: [tst_cmptest.cpp(325)] FAIL! : tst_Cmptest::compareQStringLists(short list first) Compared lists have different sizes. Actual (opA) size: 1 Expected (opB) size: 12 - Loc: [tst_cmptest.cpp(313)] + Loc: [tst_cmptest.cpp(325)] FAIL! : tst_Cmptest::compareQListInt() Compared lists differ at index 2. Actual (int1): 3 Expected (int2): 4 - Loc: [tst_cmptest.cpp(320)] + Loc: [tst_cmptest.cpp(332)] FAIL! : tst_Cmptest::compareQListDouble() Compared lists differ at index 0. Actual (double1): 1.5 Expected (double2): 1 - Loc: [tst_cmptest.cpp(327)] + Loc: [tst_cmptest.cpp(339)] PASS : tst_Cmptest::compareQPixmaps(both null) FAIL! : tst_Cmptest::compareQPixmaps(one null) Compared QPixmaps differ. Actual (opA).isNull(): 1 Expected (opB).isNull(): 0 - Loc: [tst_cmptest.cpp(353)] + Loc: [tst_cmptest.cpp(365)] FAIL! : tst_Cmptest::compareQPixmaps(other null) Compared QPixmaps differ. Actual (opA).isNull(): 0 Expected (opB).isNull(): 1 - Loc: [tst_cmptest.cpp(353)] + Loc: [tst_cmptest.cpp(365)] PASS : tst_Cmptest::compareQPixmaps(equal) FAIL! : tst_Cmptest::compareQPixmaps(different size) Compared QPixmaps differ in size. Actual (opA): 11x20 Expected (opB): 20x20 - Loc: [tst_cmptest.cpp(353)] + Loc: [tst_cmptest.cpp(365)] FAIL! : tst_Cmptest::compareQPixmaps(different pixels) Compared values are not the same - Loc: [tst_cmptest.cpp(353)] + Loc: [tst_cmptest.cpp(365)] PASS : tst_Cmptest::compareQImages(both null) FAIL! : tst_Cmptest::compareQImages(one null) Compared QImages differ. Actual (opA).isNull(): 1 Expected (opB).isNull(): 0 - Loc: [tst_cmptest.cpp(380)] + Loc: [tst_cmptest.cpp(392)] FAIL! : tst_Cmptest::compareQImages(other null) Compared QImages differ. Actual (opA).isNull(): 0 Expected (opB).isNull(): 1 - Loc: [tst_cmptest.cpp(380)] + Loc: [tst_cmptest.cpp(392)] PASS : tst_Cmptest::compareQImages(equal) FAIL! : tst_Cmptest::compareQImages(different size) Compared QImages differ in size. Actual (opA): 11x20 Expected (opB): 20x20 - Loc: [tst_cmptest.cpp(380)] + Loc: [tst_cmptest.cpp(392)] FAIL! : tst_Cmptest::compareQImages(different format) Compared QImages differ in format. Actual (opA): 6 Expected (opB): 3 - Loc: [tst_cmptest.cpp(380)] + Loc: [tst_cmptest.cpp(392)] FAIL! : tst_Cmptest::compareQImages(different pixels) Compared values are not the same - Loc: [tst_cmptest.cpp(380)] + Loc: [tst_cmptest.cpp(392)] +FAIL! : tst_Cmptest::verify() 'opaqueFunc() < 2' returned FALSE. () + Loc: [tst_cmptest.cpp(404)] +FAIL! : tst_Cmptest::verify2() 'opaqueFunc() < 2' returned FALSE. (42) + Loc: [tst_cmptest.cpp(410)] +FAIL! : tst_Cmptest::tryVerify() 'opaqueFunc() < 2' returned FALSE. () + Loc: [tst_cmptest.cpp(416)] +FAIL! : tst_Cmptest::tryVerify2() 'opaqueFunc() < 2' returned FALSE. (42) + Loc: [tst_cmptest.cpp(422)] PASS : tst_Cmptest::cleanupTestCase() -Totals: 11 passed, 20 failed, 0 skipped, 0 blacklisted +Totals: 11 passed, 26 failed, 0 skipped, 0 blacklisted ********* Finished testing of tst_Cmptest ********* diff --git a/tests/auto/testlib/selftests/expected_cmptest.xml b/tests/auto/testlib/selftests/expected_cmptest.xml index aefb1b5f4cfe1ce45c1c9d7995239b4055efcf35..9437e8e4b7c3ade760bb55e12113aa93ce981b64 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xml +++ b/tests/auto/testlib/selftests/expected_cmptest.xml @@ -7,18 +7,32 @@ </Environment> <TestFunction name="initTestCase"> <Incident type="pass" file="" line="0" /> -<Duration msecs="0"/> + <Duration msecs="0"/> +</TestFunction> +<TestFunction name="compare_unregistered_enums"> +<Incident type="fail" file="tst_cmptest.cpp" line="154"> + <Description><![CDATA[Compared values are not the same]]></Description> +</Incident> + <Duration msecs="0"/> +</TestFunction> +<TestFunction name="compare_registered_enums"> +<Incident type="fail" file="tst_cmptest.cpp" line="160"> + <Description><![CDATA[Compared values are not the same + Actual (Qt::ArrowCursor): ArrowCursor + Expected (Qt::BusyCursor) : BusyCursor]]></Description> +</Incident> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compare_boolfuncs"> <Incident type="pass" file="" line="0" /> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compare_pointerfuncs"> <Incident type="pass" file="" line="0" /> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compare_tostring"> -<Incident type="fail" file="tst_cmptest.cpp" line="219"> +<Incident type="fail" file="tst_cmptest.cpp" line="231"> <DataTag><![CDATA[int, string]]></DataTag> <Description><![CDATA[Compared values are not the same Actual (actual) : QVariant(int,123) @@ -27,25 +41,25 @@ <Incident type="pass" file="" line="0"> <DataTag><![CDATA[both invalid]]></DataTag> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="219"> +<Incident type="fail" file="tst_cmptest.cpp" line="231"> <DataTag><![CDATA[null hash, invalid]]></DataTag> <Description><![CDATA[Compared values are not the same Actual (actual) : QVariant(QVariantHash) Expected (expected): QVariant()]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="219"> +<Incident type="fail" file="tst_cmptest.cpp" line="231"> <DataTag><![CDATA[string, null user type]]></DataTag> <Description><![CDATA[Compared values are not the same Actual (actual) : QVariant(QString,A simple string) Expected (expected): QVariant(PhonyClass)]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="219"> +<Incident type="fail" file="tst_cmptest.cpp" line="231"> <DataTag><![CDATA[both non-null user type]]></DataTag> <Description><![CDATA[Compared values are not the same Actual (actual) : QVariant(PhonyClass,<value not representable as string>) Expected (expected): QVariant(PhonyClass,<value not representable as string>)]]></Description> </Incident> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compareQStringLists"> <Incident type="pass" file="" line="0"> @@ -54,65 +68,65 @@ <Incident type="pass" file="" line="0"> <DataTag><![CDATA[equal lists]]></DataTag> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="313"> +<Incident type="fail" file="tst_cmptest.cpp" line="325"> <DataTag><![CDATA[last item different]]></DataTag> <Description><![CDATA[Compared lists differ at index 2. Actual (opA): "string3" Expected (opB): "DIFFERS"]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="313"> +<Incident type="fail" file="tst_cmptest.cpp" line="325"> <DataTag><![CDATA[second-last item different]]></DataTag> <Description><![CDATA[Compared lists differ at index 2. Actual (opA): "string3" Expected (opB): "DIFFERS"]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="313"> +<Incident type="fail" file="tst_cmptest.cpp" line="325"> <DataTag><![CDATA[prefix]]></DataTag> <Description><![CDATA[Compared lists have different sizes. Actual (opA) size: 2 Expected (opB) size: 1]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="313"> +<Incident type="fail" file="tst_cmptest.cpp" line="325"> <DataTag><![CDATA[short list second]]></DataTag> <Description><![CDATA[Compared lists have different sizes. Actual (opA) size: 12 Expected (opB) size: 1]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="313"> +<Incident type="fail" file="tst_cmptest.cpp" line="325"> <DataTag><![CDATA[short list first]]></DataTag> <Description><![CDATA[Compared lists have different sizes. Actual (opA) size: 1 Expected (opB) size: 12]]></Description> </Incident> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compareQListInt"> -<Incident type="fail" file="tst_cmptest.cpp" line="320"> +<Incident type="fail" file="tst_cmptest.cpp" line="332"> <Description><![CDATA[Compared lists differ at index 2. Actual (int1): 3 Expected (int2): 4]]></Description> </Incident> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compareQListDouble"> -<Incident type="fail" file="tst_cmptest.cpp" line="327"> +<Incident type="fail" file="tst_cmptest.cpp" line="339"> <Description><![CDATA[Compared lists differ at index 0. Actual (double1): 1.5 Expected (double2): 1]]></Description> </Incident> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compareQPixmaps"> <Incident type="pass" file="" line="0"> <DataTag><![CDATA[both null]]></DataTag> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="353"> +<Incident type="fail" file="tst_cmptest.cpp" line="365"> <DataTag><![CDATA[one null]]></DataTag> <Description><![CDATA[Compared QPixmaps differ. Actual (opA).isNull(): 1 Expected (opB).isNull(): 0]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="353"> +<Incident type="fail" file="tst_cmptest.cpp" line="365"> <DataTag><![CDATA[other null]]></DataTag> <Description><![CDATA[Compared QPixmaps differ. Actual (opA).isNull(): 0 @@ -121,29 +135,29 @@ <Incident type="pass" file="" line="0"> <DataTag><![CDATA[equal]]></DataTag> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="353"> +<Incident type="fail" file="tst_cmptest.cpp" line="365"> <DataTag><![CDATA[different size]]></DataTag> <Description><![CDATA[Compared QPixmaps differ in size. Actual (opA): 11x20 Expected (opB): 20x20]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="353"> +<Incident type="fail" file="tst_cmptest.cpp" line="365"> <DataTag><![CDATA[different pixels]]></DataTag> <Description><![CDATA[Compared values are not the same]]></Description> </Incident> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <TestFunction name="compareQImages"> <Incident type="pass" file="" line="0"> <DataTag><![CDATA[both null]]></DataTag> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="380"> +<Incident type="fail" file="tst_cmptest.cpp" line="392"> <DataTag><![CDATA[one null]]></DataTag> <Description><![CDATA[Compared QImages differ. Actual (opA).isNull(): 1 Expected (opB).isNull(): 0]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="380"> +<Incident type="fail" file="tst_cmptest.cpp" line="392"> <DataTag><![CDATA[other null]]></DataTag> <Description><![CDATA[Compared QImages differ. Actual (opA).isNull(): 0 @@ -152,27 +166,51 @@ <Incident type="pass" file="" line="0"> <DataTag><![CDATA[equal]]></DataTag> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="380"> +<Incident type="fail" file="tst_cmptest.cpp" line="392"> <DataTag><![CDATA[different size]]></DataTag> <Description><![CDATA[Compared QImages differ in size. Actual (opA): 11x20 Expected (opB): 20x20]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="380"> +<Incident type="fail" file="tst_cmptest.cpp" line="392"> <DataTag><![CDATA[different format]]></DataTag> <Description><![CDATA[Compared QImages differ in format. Actual (opA): 6 Expected (opB): 3]]></Description> </Incident> -<Incident type="fail" file="tst_cmptest.cpp" line="380"> +<Incident type="fail" file="tst_cmptest.cpp" line="392"> <DataTag><![CDATA[different pixels]]></DataTag> <Description><![CDATA[Compared values are not the same]]></Description> </Incident> -<Duration msecs="0"/> + <Duration msecs="0"/> +</TestFunction> +<TestFunction name="verify"> +<Incident type="fail" file="tst_cmptest.cpp" line="404"> + <Description><![CDATA['opaqueFunc() < 2' returned FALSE. ()]]></Description> +</Incident> + <Duration msecs="0"/> +</TestFunction> +<TestFunction name="verify2"> +<Incident type="fail" file="tst_cmptest.cpp" line="410"> + <Description><![CDATA['opaqueFunc() < 2' returned FALSE. (42)]]></Description> +</Incident> + <Duration msecs="0"/> +</TestFunction> +<TestFunction name="tryVerify"> +<Incident type="fail" file="tst_cmptest.cpp" line="416"> + <Description><![CDATA['opaqueFunc() < 2' returned FALSE. ()]]></Description> +</Incident> + <Duration msecs="0"/> +</TestFunction> +<TestFunction name="tryVerify2"> +<Incident type="fail" file="tst_cmptest.cpp" line="422"> + <Description><![CDATA['opaqueFunc() < 2' returned FALSE. (42)]]></Description> +</Incident> + <Duration msecs="0"/> </TestFunction> <TestFunction name="cleanupTestCase"> <Incident type="pass" file="" line="0" /> -<Duration msecs="0"/> + <Duration msecs="0"/> </TestFunction> <Duration msecs="0"/> </TestCase> diff --git a/tests/auto/testlib/selftests/expected_cmptest.xunitxml b/tests/auto/testlib/selftests/expected_cmptest.xunitxml index 7502d3cc5497354c2bce6dbdbf81ab33c8951168..fa970d41726cfb50b8b5e770fbd080fc16f4b5e0 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xunitxml +++ b/tests/auto/testlib/selftests/expected_cmptest.xunitxml @@ -1,11 +1,19 @@ <?xml version="1.0" encoding="UTF-8" ?> -<testsuite errors="0" failures="20" tests="10" name="tst_Cmptest"> +<testsuite errors="0" failures="26" tests="16" name="tst_Cmptest"> <properties> <property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/> <property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/> <property value="" name="QtBuild"/> </properties> <testcase result="pass" name="initTestCase"/> + <testcase result="fail" name="compare_unregistered_enums"> + <failure message="Compared values are not the same" result="fail"/> + </testcase> + <testcase result="fail" name="compare_registered_enums"> + <failure message="Compared values are not the same + Actual (Qt::ArrowCursor): ArrowCursor + Expected (Qt::BusyCursor) : BusyCursor" result="fail"/> + </testcase> <testcase result="pass" name="compare_boolfuncs"/> <testcase result="pass" name="compare_pointerfuncs"/> <testcase result="fail" name="compare_tostring"> @@ -76,6 +84,18 @@ Expected (opB): 3" result="fail"/> <failure tag="different pixels" message="Compared values are not the same" result="fail"/> </testcase> + <testcase result="fail" name="verify"> + <failure message="'opaqueFunc() < 2' returned FALSE. ()" result="fail"/> + </testcase> + <testcase result="fail" name="verify2"> + <failure message="'opaqueFunc() < 2' returned FALSE. (42)" result="fail"/> + </testcase> + <testcase result="fail" name="tryVerify"> + <failure message="'opaqueFunc() < 2' returned FALSE. ()" result="fail"/> + </testcase> + <testcase result="fail" name="tryVerify2"> + <failure message="'opaqueFunc() < 2' returned FALSE. (42)" result="fail"/> + </testcase> <testcase result="pass" name="cleanupTestCase"/> <system-err/> </testsuite> diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index 5e97a9cfe4e118b9d3c9c64c8f8a6a29aee392a9..9b76bca28c74dc1ea67e706d172ef2ee98a8caab 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -628,8 +628,8 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge QList<QByteArray> res = splitLines(actualOutputs[n]); const QString expectedFileName = expectedFileNameFromTest(subdir, logger); QList<QByteArray> exp = expectedResult(expectedFileName); -#if defined (Q_CC_MSVC) || defined(Q_CC_MINGW) - // MSVC, MinGW format double numbers differently +#if (defined (Q_CC_MSVC) && _MSC_VER < 1900)|| defined(Q_CC_MINGW) + // MSVC up to MSVC2013, MinGW format double numbers differently if (n == 0 && subdir == QStringLiteral("float")) { for (int i = 0; i < exp.size(); ++i) { exp[i].replace("e-07", "e-007"); diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 350c6142d204c9d4702d446cdb60844f9ab51efb..fa1b68b4f9db37e0f67c494f80f4241c844df8f1 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -880,7 +880,7 @@ void tst_Moc::preprocessorConditionals() QVERIFY(mobj->indexOfSignal("signalInIf1()") != -1); QVERIFY(mobj->indexOfSignal("signalInIf2()") != -1); QVERIFY(mobj->indexOfSignal("signalInIf3()") != -1); - QVERIFY(mobj->indexOfSignal("doNotExist()") == -1); + QCOMPARE(mobj->indexOfSignal("doNotExist()"), -1); } void tst_Moc::blackslashNewlines() @@ -888,7 +888,7 @@ void tst_Moc::blackslashNewlines() BackslashNewlines tst; const QMetaObject *mobj = tst.metaObject(); QVERIFY(mobj->indexOfSlot("works()") != -1); - QVERIFY(mobj->indexOfSlot("buggy()") == -1); + QCOMPARE(mobj->indexOfSlot("buggy()"), -1); } void tst_Moc::slotWithSillyConst() @@ -928,8 +928,8 @@ void tst_Moc::testExtraDataForEnum() const QMetaObject * const *objects = mobjUser->d.relatedMetaObjects; QVERIFY(objects); - QVERIFY(objects[0] == mobjSource); - QVERIFY(objects[1] == 0); + QCOMPARE(objects[0], mobjSource); + QVERIFY(!objects[1]); } void tst_Moc::namespaceTypeProperty() @@ -982,7 +982,7 @@ void tst_Moc::namespacedFlags() const QVariant v = bar.property("flags"); QVERIFY(v.isValid()); QVERIFY(baz.setProperty("flags", v)); - QVERIFY(baz.flags() == bar.flags()); + QCOMPARE(baz.flags(), bar.flags()); QList<Foo::Bar::Flags> l; l << baz.flags(); @@ -1104,7 +1104,7 @@ void tst_Moc::winNewline() if (data.at(i) == QLatin1Char('\r')) { QVERIFY(i < data.count() - 1); ++i; - QVERIFY(data.at(i) == '\n'); + QCOMPARE(data.at(i), '\n'); } else { QVERIFY(data.at(i) != '\n'); } @@ -1255,14 +1255,14 @@ void tst_Moc::invokable() { const QMetaObject &mobj = InvokableBeforeReturnType::staticMetaObject; QCOMPARE(mobj.methodCount(), 6); - QVERIFY(mobj.method(5).methodSignature() == QByteArray("foo()")); + QCOMPARE(mobj.method(5).methodSignature(), QByteArray("foo()")); } { const QMetaObject &mobj = InvokableBeforeInline::staticMetaObject; QCOMPARE(mobj.methodCount(), 7); - QVERIFY(mobj.method(5).methodSignature() == QByteArray("foo()")); - QVERIFY(mobj.method(6).methodSignature() == QByteArray("bar()")); + QCOMPARE(mobj.method(5).methodSignature(), QByteArray("foo()")); + QCOMPARE(mobj.method(6).methodSignature(), QByteArray("bar()")); } } @@ -1271,22 +1271,22 @@ void tst_Moc::singleFunctionKeywordSignalAndSlot() { const QMetaObject &mobj = SingleFunctionKeywordBeforeReturnType::staticMetaObject; QCOMPARE(mobj.methodCount(), 7); - QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()")); - QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()")); + QCOMPARE(mobj.method(5).methodSignature(), QByteArray("mySignal()")); + QCOMPARE(mobj.method(6).methodSignature(), QByteArray("mySlot()")); } { const QMetaObject &mobj = SingleFunctionKeywordBeforeInline::staticMetaObject; QCOMPARE(mobj.methodCount(), 7); - QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()")); - QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()")); + QCOMPARE(mobj.method(5).methodSignature(), QByteArray("mySignal()")); + QCOMPARE(mobj.method(6).methodSignature(), QByteArray("mySlot()")); } { const QMetaObject &mobj = SingleFunctionKeywordAfterInline::staticMetaObject; QCOMPARE(mobj.methodCount(), 7); - QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()")); - QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()")); + QCOMPARE(mobj.method(5).methodSignature(), QByteArray("mySignal()")); + QCOMPARE(mobj.method(6).methodSignature(), QByteArray("mySlot()")); } } @@ -1740,34 +1740,34 @@ template <class T> void tst_Moc::revisions_T() { int idx = T::staticMetaObject.indexOfProperty("prop1"); - QVERIFY(T::staticMetaObject.property(idx).revision() == 0); + QCOMPARE(T::staticMetaObject.property(idx).revision(), 0); idx = T::staticMetaObject.indexOfProperty("prop2"); - QVERIFY(T::staticMetaObject.property(idx).revision() == 2); + QCOMPARE(T::staticMetaObject.property(idx).revision(), 2); idx = T::staticMetaObject.indexOfMethod("method1()"); - QVERIFY(T::staticMetaObject.method(idx).revision() == 0); + QCOMPARE(T::staticMetaObject.method(idx).revision(), 0); idx = T::staticMetaObject.indexOfMethod("method2()"); - QVERIFY(T::staticMetaObject.method(idx).revision() == 4); + QCOMPARE(T::staticMetaObject.method(idx).revision(), 4); idx = T::staticMetaObject.indexOfSlot("slot1()"); - QVERIFY(T::staticMetaObject.method(idx).revision() == 0); + QCOMPARE(T::staticMetaObject.method(idx).revision(), 0); idx = T::staticMetaObject.indexOfSlot("slot2()"); - QVERIFY(T::staticMetaObject.method(idx).revision() == 3); + QCOMPARE(T::staticMetaObject.method(idx).revision(), 3); idx = T::staticMetaObject.indexOfSlot("slot3()"); - QVERIFY(T::staticMetaObject.method(idx).revision() == 6); + QCOMPARE(T::staticMetaObject.method(idx).revision(), 6); idx = T::staticMetaObject.indexOfSlot("slot4()"); - QVERIFY(T::staticMetaObject.method(idx).revision() == 6); + QCOMPARE(T::staticMetaObject.method(idx).revision(), 6); idx = T::staticMetaObject.indexOfSignal("signal1()"); - QVERIFY(T::staticMetaObject.method(idx).revision() == 0); + QCOMPARE(T::staticMetaObject.method(idx).revision(), 0); idx = T::staticMetaObject.indexOfSignal("signal2()"); - QVERIFY(T::staticMetaObject.method(idx).revision() == 5); + QCOMPARE(T::staticMetaObject.method(idx).revision(), 5); idx = T::staticMetaObject.indexOfSignal("signal3()"); - QVERIFY(T::staticMetaObject.method(idx).revision() == 7); + QCOMPARE(T::staticMetaObject.method(idx).revision(), 7); idx = T::staticMetaObject.indexOfSignal("signal4()"); - QVERIFY(T::staticMetaObject.method(idx).revision() == 7); + QCOMPARE(T::staticMetaObject.method(idx).revision(), 7); idx = T::staticMetaObject.indexOfEnumerator("TestEnum"); QCOMPARE(T::staticMetaObject.enumerator(idx).keyCount(), 2); @@ -1947,7 +1947,7 @@ public: void tst_Moc::privateClass() { - QVERIFY(PrivateClass::staticMetaObject.indexOfConstructor("PrivateClass()") == 0); + QCOMPARE(PrivateClass::staticMetaObject.indexOfConstructor("PrivateClass()"), 0); QVERIFY(PrivateClass::staticMetaObject.indexOfSignal("someSignal()") > 0); } @@ -3068,7 +3068,7 @@ void tst_Moc::parseDefines() int index = mo->indexOfSlot("stringMethod()"); QVERIFY(index != -1); - QVERIFY(mo->method(index).returnType() == QMetaType::QString); + QCOMPARE(mo->method(index).returnType(), int(QMetaType::QString)); index = mo->indexOfSlot("combined1()"); QVERIFY(index != -1); @@ -3127,7 +3127,7 @@ void tst_Moc::parseDefines() QVERIFY(!qstrcmp(mci.value(), "TestValue")); } } - QVERIFY(count == 3); + QCOMPARE(count, 3); index = mo->indexOfSlot("PD_DEFINE_ITSELF_SUFFIX(int)"); QVERIFY(index != -1); @@ -3253,7 +3253,7 @@ void tst_Moc::relatedMetaObjectsWithinNamespaces() const QMetaObject *testMo = &QTBUG_2151::B::staticMetaObject; QVERIFY(testMo->d.relatedMetaObjects); - QVERIFY(testMo->d.relatedMetaObjects[0] == relatedMo); + QCOMPARE(testMo->d.relatedMetaObjects[0], relatedMo); } void tst_Moc::relatedMetaObjectsInGadget() @@ -3262,7 +3262,7 @@ void tst_Moc::relatedMetaObjectsInGadget() const QMetaObject *testMo = &QTBUG_35657::B::staticMetaObject; QVERIFY(testMo->d.relatedMetaObjects); - QVERIFY(testMo->d.relatedMetaObjects[0] == relatedMo); + QCOMPARE(testMo->d.relatedMetaObjects[0], relatedMo); } void tst_Moc::relatedMetaObjectsNameConflict_data() diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index fab2cdce17f8cd4d89fc4c5d2f07ae05992e8740..bed4c792a1ecf22f38354056bd3bbfab097181be 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -1356,7 +1356,7 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir) QTest::newRow("$$relative_path(): relative file to empty") << "VAR = $$relative_path(dir/..)" - << "VAR =" + << "VAR = ." << "" << true; @@ -1368,7 +1368,7 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir) QTest::newRow("$$relative_path(): empty file & path") << "VAR = $$relative_path('', /root/sub)" - << "VAR =" + << "VAR = ." << "" << true; diff --git a/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro b/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro index 22f6bab49797541cfb4462d3ace8c5f8123e53de..c379e67ec5fa10b4e248da5ccbaf138e7677014c 100644 --- a/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro +++ b/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro @@ -4,5 +4,4 @@ TARGET = tst_qcolordialog QT += widgets testlib SOURCES += tst_qcolordialog.cpp - - +linux*: CONFIG += insignificant_test # Crashes on different Linux distros diff --git a/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp b/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp index 59227a6168daf8cd1f16308c01bc1bf98dba00a8..c5e31a4bd44fe93209d8e161d9f6b4d7237aa7c4 100644 --- a/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp +++ b/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp @@ -98,7 +98,7 @@ void tst_QColorDialog::testNativeActiveModalWidget() TestNativeDialog d; QTimer::singleShot(1000, &d, SLOT(hide())); d.exec(); - QVERIFY(&d == d.m_activeModalWidget); + QCOMPARE(&d, d.m_activeModalWidget); } void tst_QColorDialog::native_activeModalWidget() diff --git a/tests/auto/widgets/dialogs/qdialog/BLACKLIST b/tests/auto/widgets/dialogs/qdialog/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..3da73377846a9f0d4752fe95ec6d3ee37fd3082b --- /dev/null +++ b/tests/auto/widgets/dialogs/qdialog/BLACKLIST @@ -0,0 +1,2 @@ +[snapToDefaultButton] +osx diff --git a/tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro b/tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro index 3a968273523ac40ad75aba36985741ac21e9536d..2a11a294207fbd9da46557667b04eb08290ec88c 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro +++ b/tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro @@ -21,3 +21,5 @@ wince* { } else { DEFINES += SRCDIR=\\\"$$PWD/\\\" } + +linux*: CONFIG += insignificant_test # Crashes on different Linux distros diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index ffc000a418238b76e8b943545484f7a7ee7180b3..cc321bb137a9657019bbb972b1d7d58dcf104492 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp @@ -677,7 +677,7 @@ void tst_QFiledialog::filters() // effects QList<QComboBox*> views = fd.findChildren<QComboBox*>("fileTypeCombo"); - QVERIFY(views.count() == 1); + QCOMPARE(views.count(), 1); QCOMPARE(views.at(0)->isVisible(), false); QStringList filters; @@ -1296,7 +1296,7 @@ void tst_QFiledialog::clearLineEdit() QLineEdit *lineEdit = fd.findChild<QLineEdit*>("fileNameEdit"); QVERIFY(lineEdit); - QVERIFY(lineEdit->text() == "foo"); + QCOMPARE(lineEdit->text(), QLatin1String("foo")); fd.setDirectory(QDir::home()); QListView* list = fd.findChild<QListView*>("listView"); @@ -1393,12 +1393,12 @@ void tst_QFiledialog::trailingDotsAndSpaces() QTest::keyClick(lineEdit, Qt::Key_Space); QTest::keyClick(lineEdit, Qt::Key_Period); QTest::qWait(1000); - QVERIFY(currentChildrenCount == list->model()->rowCount(list->rootIndex())); + QCOMPARE(currentChildrenCount, list->model()->rowCount(list->rootIndex())); lineEdit->clear(); QTest::keyClick(lineEdit, Qt::Key_Period); QTest::keyClick(lineEdit, Qt::Key_Space); QTest::qWait(1000); - QVERIFY(currentChildrenCount == list->model()->rowCount(list->rootIndex())); + QCOMPARE(currentChildrenCount, list->model()->rowCount(list->rootIndex())); } #ifdef Q_OS_UNIX diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index 03f0d253752f9fb9dfd28b5015fc9fb8ac2fdbef..0e7f760b4ee019ce749ea2ad3ae132bf1a96a964 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -167,7 +167,7 @@ void tst_QFileSystemModel::cleanup() QVERIFY(dir.rmdir(list.at(i))); } list = dir.entryList(QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot); - QVERIFY(list.count() == 0); + QCOMPARE(list.count(), 0); } } @@ -523,8 +523,14 @@ void tst_QFileSystemModel::rowsInserted() QVERIFY(createFiles(tmp, QStringList(".hidden_file"), 5 + count)); - if (count != 0) QTRY_VERIFY(spy0.count() >= 1); else QTRY_VERIFY(spy0.count() == 0); - if (count != 0) QTRY_VERIFY(spy1.count() >= 1); else QTRY_VERIFY(spy1.count() == 0); + if (count != 0) + QTRY_VERIFY(spy0.count() >= 1); + else + QTRY_COMPARE(spy0.count(), 0); + if (count != 0) + QTRY_VERIFY(spy1.count() >= 1); + else + QTRY_COMPARE(spy1.count(), 0); } void tst_QFileSystemModel::rowsRemoved_data() @@ -563,8 +569,8 @@ void tst_QFileSystemModel::rowsRemoved() } } else { if (i == 10 || spy0.count() == 0) { - QVERIFY(spy0.count() == 0); - QVERIFY(spy1.count() == 0); + QCOMPARE(spy0.count(), 0); + QCOMPARE(spy1.count(), 0); } } QStringList lst; @@ -583,8 +589,8 @@ void tst_QFileSystemModel::rowsRemoved() QVERIFY(QFile::remove(tmp + '/' + QString(".c"))); QTest::qWait(WAITTIME); - if (count != 0) QVERIFY(spy0.count() >= 1); else QVERIFY(spy0.count() == 0); - if (count != 0) QVERIFY(spy1.count() >= 1); else QVERIFY(spy1.count() == 0); + if (count != 0) QVERIFY(spy0.count() >= 1); else QCOMPARE(spy0.count(), 0); + if (count != 0) QVERIFY(spy1.count() >= 1); else QCOMPARE(spy1.count(), 0); } void tst_QFileSystemModel::dataChanged_data() @@ -614,7 +620,7 @@ void tst_QFileSystemModel::dataChanged() QTest::qWait(WAITTIME); - if (count != 0) QVERIFY(spy.count() >= 1); else QVERIFY(spy.count() == 0); + if (count != 0) QVERIFY(spy.count() >= 1); else QCOMPARE(spy.count(), 0); */ } diff --git a/tests/auto/widgets/dialogs/qfontdialog/BLACKLIST b/tests/auto/widgets/dialogs/qfontdialog/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..31fbc428c9f092523c5c12495aaed6012085ee73 --- /dev/null +++ b/tests/auto/widgets/dialogs/qfontdialog/BLACKLIST @@ -0,0 +1,4 @@ +[task256466_wrongStyle] +opensuse-13.1 +[setFont] +ubuntu-14.04 diff --git a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp index bac72f03654cd4b6537e67bf34ad9f5028b447ab..796b4b9fdbcb70e2755d83eb0f17cd0b630d8566 100644 --- a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp +++ b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp @@ -225,6 +225,8 @@ void tst_QFontDialog::qtbug_41513_stylesheetStyle() QFontDialog::DontUseNativeDialog); QVERIFY(accepted); + // The fontdialog sets the styleName, when the fontdatabase knows the style name. + resultFont.setStyleName(testFont.styleName()); QCOMPARE(resultFont, testFont); // reset stylesheet diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp index bef51bd73d55c6e930543df209d7a7195cf0ab4d..97cfec817122c17585853d5cfba52a1f045eda4f 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp @@ -216,7 +216,7 @@ void tst_QMessageBox::button() // remove the cancel, should not exist anymore msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - QVERIFY(msgBox.button(QMessageBox::Cancel) == 0); + QVERIFY(!msgBox.button(QMessageBox::Cancel)); QVERIFY(msgBox.button(QMessageBox::Yes) != 0); // should not crash @@ -228,10 +228,10 @@ void tst_QMessageBox::button() void tst_QMessageBox::defaultButton() { QMessageBox msgBox; - QVERIFY(msgBox.defaultButton() == 0); + QVERIFY(!msgBox.defaultButton()); msgBox.addButton(QMessageBox::Ok); msgBox.addButton(QMessageBox::Cancel); - QVERIFY(msgBox.defaultButton() == 0); + QVERIFY(!msgBox.defaultButton()); QPushButton pushButton; msgBox.setDefaultButton(&pushButton); QVERIFY(msgBox.defaultButton() == 0); // we have not added it yet @@ -250,27 +250,27 @@ void tst_QMessageBox::defaultButton() exec(&msgBox, Qt::Key_Enter); QCOMPARE(msgBox.clickedButton(), okButton); msgBox.setDefaultButton(QMessageBox::Yes); // its not in there! - QVERIFY(msgBox.defaultButton() == okButton); + QCOMPARE(msgBox.defaultButton(), okButton); msgBox.removeButton(okButton); delete okButton; okButton = 0; - QVERIFY(msgBox.defaultButton() == 0); + QVERIFY(!msgBox.defaultButton()); msgBox.setDefaultButton(QMessageBox::Ok); - QVERIFY(msgBox.defaultButton() == 0); + QVERIFY(!msgBox.defaultButton()); } void tst_QMessageBox::escapeButton() { QMessageBox msgBox; - QVERIFY(msgBox.escapeButton() == 0); + QVERIFY(!msgBox.escapeButton()); msgBox.addButton(QMessageBox::Ok); exec(&msgBox); QVERIFY(msgBox.clickedButton() == msgBox.button(QMessageBox::Ok)); // auto detected (one button only) msgBox.addButton(QMessageBox::Cancel); - QVERIFY(msgBox.escapeButton() == 0); + QVERIFY(!msgBox.escapeButton()); QPushButton invalidButton; msgBox.setEscapeButton(&invalidButton); - QVERIFY(msgBox.escapeButton() == 0); + QVERIFY(!msgBox.escapeButton()); QAbstractButton *retryButton = msgBox.addButton(QMessageBox::Retry); exec(&msgBox); @@ -293,13 +293,13 @@ void tst_QMessageBox::escapeButton() exec(&msgBox, Qt::Key_Escape); QCOMPARE(msgBox.clickedButton(), okButton); msgBox.setEscapeButton(QMessageBox::Yes); // its not in there! - QVERIFY(msgBox.escapeButton() == okButton); + QCOMPARE(msgBox.escapeButton(), okButton); msgBox.removeButton(okButton); delete okButton; okButton = 0; - QVERIFY(msgBox.escapeButton() == 0); + QVERIFY(!msgBox.escapeButton()); msgBox.setEscapeButton(QMessageBox::Ok); - QVERIFY(msgBox.escapeButton() == 0); + QVERIFY(!msgBox.escapeButton()); QMessageBox msgBox2; msgBox2.addButton(QMessageBox::Yes); @@ -363,7 +363,7 @@ void tst_QMessageBox::statics() } } -// shortcuts are not used on MAC OS X +// shortcuts are not used on OS X #ifndef Q_OS_MAC void tst_QMessageBox::shortcut() { @@ -483,7 +483,7 @@ void tst_QMessageBox::instanceSourceCompat() QCOMPARE(exec(&mb, Qt::Key_Enter), int(QMessageBox::Yes)); QCOMPARE(exec(&mb, Qt::Key_Escape), int(QMessageBox::Cancel)); #ifndef Q_OS_MAC - // mnemonics are not used on Mac OS X + // mnemonics are not used on OS X QCOMPARE(exec(&mb, Qt::ALT + Qt::Key_R), 0); QCOMPARE(exec(&mb, Qt::ALT + Qt::Key_Z), 1); #endif @@ -527,13 +527,13 @@ void tst_QMessageBox::testSymbols() QCOMPARE(mb1.text(), text); icon = mb1.icon(); - QVERIFY(icon == QMessageBox::NoIcon); + QCOMPARE(icon, QMessageBox::NoIcon); mb1.setIcon(QMessageBox::Question); - QVERIFY(mb1.icon() == QMessageBox::Question); + QCOMPARE(mb1.icon(), QMessageBox::Question); QPixmap iconPixmap = mb1.iconPixmap(); mb1.setIconPixmap(iconPixmap); - QVERIFY(mb1.icon() == QMessageBox::NoIcon); + QCOMPARE(mb1.icon(), QMessageBox::NoIcon); QCOMPARE(mb1.buttonText(QMessageBox::Ok), QLatin1String("OK")); QCOMPARE(mb1.buttonText(QMessageBox::Cancel), QString()); diff --git a/tests/auto/widgets/dialogs/qprogressdialog/BLACKLIST b/tests/auto/widgets/dialogs/qprogressdialog/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..a2670e8f3651ec5d8a3e5f72cd439eb1830447ec --- /dev/null +++ b/tests/auto/widgets/dialogs/qprogressdialog/BLACKLIST @@ -0,0 +1,2 @@ +[autoShow:50_to_100_fast_0_compat] +osx diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp index 21c15edff20e7ad6d65d8eaf3da1210845029d7d..b2bdbac79a362a7236837f15d0859570c8d31d8c 100644 --- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp +++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp @@ -400,7 +400,7 @@ void tst_QWizard::setButton() // revert to default button wizard.setButton(QWizard::NextButton, 0); - QVERIFY(toolButton == 0); + QVERIFY(toolButton.isNull()); QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))); QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next")); } @@ -408,16 +408,16 @@ void tst_QWizard::setButton() void tst_QWizard::setTitleFormatEtc() { QWizard wizard; - QVERIFY(wizard.titleFormat() == Qt::AutoText); - QVERIFY(wizard.subTitleFormat() == Qt::AutoText); + QCOMPARE(wizard.titleFormat(), Qt::AutoText); + QCOMPARE(wizard.subTitleFormat(), Qt::AutoText); wizard.setTitleFormat(Qt::RichText); - QVERIFY(wizard.titleFormat() == Qt::RichText); - QVERIFY(wizard.subTitleFormat() == Qt::AutoText); + QCOMPARE(wizard.titleFormat(), Qt::RichText); + QCOMPARE(wizard.subTitleFormat(), Qt::AutoText); wizard.setSubTitleFormat(Qt::PlainText); - QVERIFY(wizard.titleFormat() == Qt::RichText); - QVERIFY(wizard.subTitleFormat() == Qt::PlainText); + QCOMPARE(wizard.titleFormat(), Qt::RichText); + QCOMPARE(wizard.subTitleFormat(), Qt::PlainText); } void tst_QWizard::setPixmap() @@ -439,7 +439,7 @@ void tst_QWizard::setPixmap() QVERIFY(wizard.pixmap(QWizard::LogoPixmap).isNull()); QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).isNull()); #ifdef Q_OS_OSX - QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull() == false); + QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull()); #else QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull()); #endif @@ -448,7 +448,7 @@ void tst_QWizard::setPixmap() QVERIFY(page->pixmap(QWizard::LogoPixmap).isNull()); QVERIFY(page->pixmap(QWizard::WatermarkPixmap).isNull()); #ifdef Q_OS_OSX - QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull() == false); + QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull()); #else QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull()); #endif @@ -459,20 +459,20 @@ void tst_QWizard::setPixmap() page->setPixmap(QWizard::LogoPixmap, p5); - QVERIFY(wizard.pixmap(QWizard::BannerPixmap).size() == p1.size()); - QVERIFY(wizard.pixmap(QWizard::LogoPixmap).size() == p2.size()); - QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).size() == p3.size()); - QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).size() == p4.size()); + QCOMPARE(wizard.pixmap(QWizard::BannerPixmap).size(), p1.size()); + QCOMPARE(wizard.pixmap(QWizard::LogoPixmap).size(), p2.size()); + QCOMPARE(wizard.pixmap(QWizard::WatermarkPixmap).size(), p3.size()); + QCOMPARE(wizard.pixmap(QWizard::BackgroundPixmap).size(), p4.size()); - QVERIFY(page->pixmap(QWizard::BannerPixmap).size() == p1.size()); - QVERIFY(page->pixmap(QWizard::LogoPixmap).size() == p5.size()); - QVERIFY(page->pixmap(QWizard::WatermarkPixmap).size() == p3.size()); - QVERIFY(page->pixmap(QWizard::BackgroundPixmap).size() == p4.size()); + QCOMPARE(page->pixmap(QWizard::BannerPixmap).size(), p1.size()); + QCOMPARE(page->pixmap(QWizard::LogoPixmap).size(), p5.size()); + QCOMPARE(page->pixmap(QWizard::WatermarkPixmap).size(), p3.size()); + QCOMPARE(page->pixmap(QWizard::BackgroundPixmap).size(), p4.size()); - QVERIFY(page2->pixmap(QWizard::BannerPixmap).size() == p1.size()); - QVERIFY(page2->pixmap(QWizard::LogoPixmap).size() == p2.size()); - QVERIFY(page2->pixmap(QWizard::WatermarkPixmap).size() == p3.size()); - QVERIFY(page2->pixmap(QWizard::BackgroundPixmap).size() == p4.size()); + QCOMPARE(page2->pixmap(QWizard::BannerPixmap).size(), p1.size()); + QCOMPARE(page2->pixmap(QWizard::LogoPixmap).size(), p2.size()); + QCOMPARE(page2->pixmap(QWizard::WatermarkPixmap).size(), p3.size()); + QCOMPARE(page2->pixmap(QWizard::BackgroundPixmap).size(), p4.size()); } class MyPage1 : public QWizardPage @@ -571,7 +571,7 @@ void tst_QWizard::addPage() } for (int i = 0; i < N; ++i) { - QVERIFY(pages[i] == wizard.page(i)); + QCOMPARE(pages[i], wizard.page(i)); } QVERIFY(!wizard.page(-1)); QVERIFY(!wizard.page(N)); @@ -667,7 +667,7 @@ void tst_QWizard::setPage() QCOMPARE(wizard.page(-2), page); QCOMPARE(wizard.startId(), -2); QCOMPARE(wizard.currentId(), -2); - QVERIFY(wizard.currentPage() == page); + QCOMPARE(wizard.currentPage(), page); QCOMPARE(wizard.nextId(), 0); CHECK_VISITED(wizard, QList<int>() << -2); @@ -679,14 +679,14 @@ void tst_QWizard::setPage() QCOMPARE(wizard.page(2), page); QCOMPARE(wizard.startId(), -2); QCOMPARE(wizard.currentId(), -2); - QVERIFY(wizard.currentPage() == wizard.page(-2)); + QCOMPARE(wizard.currentPage(), wizard.page(-2)); QCOMPARE(wizard.nextId(), 0); CHECK_VISITED(wizard, QList<int>() << -2); wizard.restart(); QCOMPARE(wizard.startId(), -2); QCOMPARE(wizard.currentId(), -2); - QVERIFY(wizard.currentPage() == wizard.page(-2)); + QCOMPARE(wizard.currentPage(), wizard.page(-2)); QCOMPARE(wizard.nextId(), 0); CHECK_VISITED(wizard, QList<int>() << -2); @@ -698,28 +698,28 @@ void tst_QWizard::setPage() QCOMPARE(wizard.page(-3), page); QCOMPARE(wizard.startId(), -3); QCOMPARE(wizard.currentId(), -2); - QVERIFY(wizard.currentPage() == wizard.page(-2)); + QCOMPARE(wizard.currentPage(), wizard.page(-2)); QCOMPARE(wizard.nextId(), 0); CHECK_VISITED(wizard, QList<int>() << -2); wizard.restart(); QCOMPARE(wizard.startId(), -3); QCOMPARE(wizard.currentId(), -3); - QVERIFY(wizard.currentPage() == wizard.page(-3)); + QCOMPARE(wizard.currentPage(), wizard.page(-3)); QCOMPARE(wizard.nextId(), -2); CHECK_VISITED(wizard, QList<int>() << -3); wizard.next(); QCOMPARE(wizard.startId(), -3); QCOMPARE(wizard.currentId(), -2); - QVERIFY(wizard.currentPage() == wizard.page(-2)); + QCOMPARE(wizard.currentPage(), wizard.page(-2)); QCOMPARE(wizard.nextId(), 0); CHECK_VISITED(wizard, QList<int>() << -3 << -2); wizard.next(); QCOMPARE(wizard.startId(), -3); QCOMPARE(wizard.currentId(), 0); - QVERIFY(wizard.currentPage() == wizard.page(0)); + QCOMPARE(wizard.currentPage(), wizard.page(0)); QCOMPARE(wizard.nextId(), 2); CHECK_VISITED(wizard, QList<int>() << -3 << -2 << 0); @@ -727,7 +727,7 @@ void tst_QWizard::setPage() wizard.next(); QCOMPARE(wizard.startId(), -3); QCOMPARE(wizard.currentId(), 2); - QVERIFY(wizard.currentPage() == wizard.page(2)); + QCOMPARE(wizard.currentPage(), wizard.page(2)); QCOMPARE(wizard.nextId(), -1); CHECK_VISITED(wizard, QList<int>() << -3 << -2 << 0 << 2); } @@ -735,14 +735,14 @@ void tst_QWizard::setPage() wizard.back(); QCOMPARE(wizard.startId(), -3); QCOMPARE(wizard.currentId(), 0); - QVERIFY(wizard.currentPage() == wizard.page(0)); + QCOMPARE(wizard.currentPage(), wizard.page(0)); QCOMPARE(wizard.nextId(), 2); CHECK_VISITED(wizard, QList<int>() << -3 << -2 << 0); wizard.back(); QCOMPARE(wizard.startId(), -3); QCOMPARE(wizard.currentId(), -2); - QVERIFY(wizard.currentPage() == wizard.page(-2)); + QCOMPARE(wizard.currentPage(), wizard.page(-2)); QCOMPARE(wizard.nextId(), 0); CHECK_VISITED(wizard, QList<int>() << -3 << -2); @@ -750,7 +750,7 @@ void tst_QWizard::setPage() wizard.back(); QCOMPARE(wizard.startId(), -3); QCOMPARE(wizard.currentId(), -3); - QVERIFY(wizard.currentPage() == wizard.page(-3)); + QCOMPARE(wizard.currentPage(), wizard.page(-3)); QCOMPARE(wizard.nextId(), -2); CHECK_VISITED(wizard, QList<int>() << -3); } @@ -759,7 +759,7 @@ void tst_QWizard::setPage() wizard.restart(); QCOMPARE(wizard.startId(), -3); QCOMPARE(wizard.currentId(), -3); - QVERIFY(wizard.currentPage() == wizard.page(-3)); + QCOMPARE(wizard.currentPage(), wizard.page(-3)); QCOMPARE(wizard.nextId(), -2); CHECK_VISITED(wizard, QList<int>() << -3); } @@ -808,31 +808,31 @@ void tst_QWizard::setStartId() wizard.restart(); QCOMPARE(wizard.startId(), -2); QCOMPARE(wizard.currentId(), -2); - QVERIFY(wizard.currentPage() == wizard.page(-2)); + QCOMPARE(wizard.currentPage(), wizard.page(-2)); QCOMPARE(wizard.nextId(), 0); wizard.next(); QCOMPARE(wizard.startId(), -2); QCOMPARE(wizard.currentId(), 0); - QVERIFY(wizard.currentPage() == wizard.page(0)); + QCOMPARE(wizard.currentPage(), wizard.page(0)); QCOMPARE(wizard.nextId(), 1); wizard.setStartId(INT_MIN); QCOMPARE(wizard.startId(), INT_MIN); QCOMPARE(wizard.currentId(), 0); - QVERIFY(wizard.currentPage() == wizard.page(0)); + QCOMPARE(wizard.currentPage(), wizard.page(0)); QCOMPARE(wizard.nextId(), 1); wizard.next(); QCOMPARE(wizard.startId(), INT_MIN); QCOMPARE(wizard.currentId(), 1); - QVERIFY(wizard.currentPage() == wizard.page(1)); + QCOMPARE(wizard.currentPage(), wizard.page(1)); QCOMPARE(wizard.nextId(), INT_MAX); wizard.next(); QCOMPARE(wizard.startId(), INT_MIN); QCOMPARE(wizard.currentId(), INT_MAX); - QVERIFY(wizard.currentPage() == wizard.page(INT_MAX)); + QCOMPARE(wizard.currentPage(), wizard.page(INT_MAX)); QCOMPARE(wizard.nextId(), -1); CHECK_VISITED(wizard, QList<int>() << -2 << 0 << 1 << INT_MAX); } @@ -1143,12 +1143,12 @@ void tst_QWizard::setOption_ExtendedWatermarkPixmap() } if (wizard1.wizardStyle() == QWizard::MacStyle) { - QVERIFY(i1[0] == i1[1]); - QVERIFY(i2[0] == i2[1]); - QVERIFY(i1[0] == i2[0]); + QCOMPARE(i1[0], i1[1]); + QCOMPARE(i2[0], i2[1]); + QCOMPARE(i1[0], i2[0]); } else { QVERIFY(i1[0] != i1[1]); - QVERIFY(i2[0] == i2[1]); + QCOMPARE(i2[0], i2[1]); QVERIFY(i1[0] != i2[0]); QVERIFY(i1[1] != i2[1]); } @@ -2425,19 +2425,19 @@ void tst_QWizard::sideWidget() QWizard wizard; wizard.setSideWidget(0); - QVERIFY(wizard.sideWidget() == 0); + QVERIFY(!wizard.sideWidget()); QScopedPointer<QWidget> w1(new QWidget(&wizard)); wizard.setSideWidget(w1.data()); QCOMPARE(wizard.sideWidget(), w1.data()); QWidget *w2 = new QWidget(&wizard); wizard.setSideWidget(w2); - QVERIFY(wizard.sideWidget() == w2); + QCOMPARE(wizard.sideWidget(), w2); QVERIFY(w1->parent() != 0); QCOMPARE(w1->window(), static_cast<QWidget *>(&wizard)); QCOMPARE(w2->window(), static_cast<QWidget *>(&wizard)); w1->setParent(0); wizard.setSideWidget(0); - QVERIFY(wizard.sideWidget() == 0); + QVERIFY(!wizard.sideWidget()); } void tst_QWizard::objectNames_data() @@ -2558,7 +2558,7 @@ void tst_QWizard::task183550_stretchFactor() page2->disableVerticalExpansion(); wizard.next(); QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page2)); - QVERIFY(page2->treeWidgetHeight() == page2->treeWidgetSizeHintHeight()); + QCOMPARE(page2->treeWidgetHeight(), page2->treeWidgetSizeHintHeight()); wizard.back(); QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page1)); @@ -2576,7 +2576,7 @@ void tst_QWizard::task183550_stretchFactor() page2->disableVerticalExpansion(); wizard.next(); QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page2)); - QVERIFY(page2->treeWidgetHeight() == page2->treeWidgetSizeHintHeight()); + QCOMPARE(page2->treeWidgetHeight(), page2->treeWidgetSizeHintHeight()); } void tst_QWizard::task161658_alignments() diff --git a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp index 4d7f55f37d20eebbd746079f2904786b6f6187a3..c7d1dd0aa13022c59b3618dc825b77329312fd33 100644 --- a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp +++ b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp @@ -520,7 +520,7 @@ public: void draw(QPainter *painter) { - QVERIFY(sourcePixmap(Qt::LogicalCoordinates).handle() == pixmap.handle()); + QCOMPARE(sourcePixmap(Qt::LogicalCoordinates).handle(), pixmap.handle()); QVERIFY((painter->worldTransform().type() <= QTransform::TxTranslate) == (sourcePixmap(Qt::DeviceCoordinates).handle() == pixmap.handle())); ++repaints; @@ -595,7 +595,7 @@ void tst_QGraphicsEffect::deviceCoordinateTranslateCaching() item->translate(10, 0); - QTRY_VERIFY(item->numRepaints == numRepaints); + QTRY_COMPARE(item->numRepaints, numRepaints); } void tst_QGraphicsEffect::inheritOpacity() diff --git a/tests/auto/widgets/effects/qpixmapfilter/qpixmapfilter.pro b/tests/auto/widgets/effects/qpixmapfilter/qpixmapfilter.pro index 879d31604b6a1e06bbc11f2711007df6b7e94ebd..b6693eeb5f5858b3cb338651b3b37fedc9c2c8c5 100644 --- a/tests/auto/widgets/effects/qpixmapfilter/qpixmapfilter.pro +++ b/tests/auto/widgets/effects/qpixmapfilter/qpixmapfilter.pro @@ -7,7 +7,7 @@ QT += gui-private SOURCES += tst_qpixmapfilter.cpp -wince*: { +wince { addFiles.files = noise.png addFiles.path = . DEPLOYMENT += addFiles diff --git a/tests/auto/widgets/gestures/qgesturerecognizer/BLACKLIST b/tests/auto/widgets/gestures/qgesturerecognizer/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..7f55c2dae023e30bcf3b93f5c4838af80d2bd592 --- /dev/null +++ b/tests/auto/widgets/gestures/qgesturerecognizer/BLACKLIST @@ -0,0 +1,2 @@ +[panGesture:Two finger] +xcb diff --git a/tests/auto/widgets/gestures/qgesturerecognizer/tst_qgesturerecognizer.cpp b/tests/auto/widgets/gestures/qgesturerecognizer/tst_qgesturerecognizer.cpp index 67c431d16e36d9ec0cdf5c41d33648f9a433b492..dc2adad5da3c401f378fb24d39b0e6c772d2f7f4 100644 --- a/tests/auto/widgets/gestures/qgesturerecognizer/tst_qgesturerecognizer.cpp +++ b/tests/auto/widgets/gestures/qgesturerecognizer/tst_qgesturerecognizer.cpp @@ -269,7 +269,8 @@ void tst_QGestureRecognizer::pinchGesture() enum SwipeSubTest { SwipeLineSubTest, - SwipeChangeDirectionSubTest, + SwipeDirectionChangeSubTest, + SwipeSmallDirectionChangeSubTest }; void tst_QGestureRecognizer::swipeGesture_data() @@ -277,7 +278,8 @@ void tst_QGestureRecognizer::swipeGesture_data() QTest::addColumn<int>("swipeSubTest"); QTest::addColumn<bool>("gestureExpected"); QTest::newRow("Line") << int(SwipeLineSubTest) << true; - QTest::newRow("ChangeDirection") << int(SwipeChangeDirectionSubTest) << false; + QTest::newRow("DirectionChange") << int(SwipeDirectionChangeSubTest) << false; + QTest::newRow("SmallDirectionChange") << int(SwipeSmallDirectionChangeSubTest) << true; } void tst_QGestureRecognizer::swipeGesture() @@ -314,10 +316,17 @@ void tst_QGestureRecognizer::swipeGesture() case SwipeLineSubTest: linearSequence(5, moveDelta, swipeSequence, points, &widget); break; - case SwipeChangeDirectionSubTest: + case SwipeDirectionChangeSubTest: linearSequence(5, moveDelta, swipeSequence, points, &widget); linearSequence(3, QPoint(-moveDelta.x(), moveDelta.y()), swipeSequence, points, &widget); break; + case SwipeSmallDirectionChangeSubTest: { // QTBUG-46195, small changes in direction should not cause the gesture to be canceled. + const QPoint smallChangeMoveDelta(50, 1); + linearSequence(5, smallChangeMoveDelta, swipeSequence, points, &widget); + linearSequence(1, QPoint(smallChangeMoveDelta.x(), -3), swipeSequence, points, &widget); + linearSequence(5, smallChangeMoveDelta, swipeSequence, points, &widget); + } + break; } releaseSequence(swipeSequence, points, &widget); diff --git a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index ca01b27bee02090ec5bd04b5825a295b7d1419bd..f71308cdaf9dc9a996c5bbae2b503338ca1d0c7e 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -133,7 +133,6 @@ static bool checkReverseDirection(QGraphicsWidget *widget) layout->getContentsMargins(&left, &top, &right, &bottom); widget->setLayoutDirection(Qt::LeftToRight); QApplication::processEvents(); - const QRectF layoutGeometry = layout->geometry(); QMap<QGraphicsLayoutItem *, QRectF> geometries; for (int i = 0; i < layout->count(); ++i) { QGraphicsLayoutItem *item = layout->itemAt(i); @@ -141,7 +140,7 @@ static bool checkReverseDirection(QGraphicsWidget *widget) } widget->setLayoutDirection(Qt::RightToLeft); QApplication::processEvents(); - layoutGeometry.adjusted(+right, +top, -left, -bottom); + const QRectF layoutGeometry = layout->geometry().adjusted(+right, +top, -left, -bottom); for (int i = 0; i < layout->count(); ++i) { QGraphicsLayoutItem *item = layout->itemAt(i); const QRectF rightToLeftGeometry = item->geometry(); @@ -653,7 +652,7 @@ void tst_QGraphicsAnchorLayout::snake() QCOMPARE(c->geometry(), QRectF(90.0, 200.0, 100.0, 100.0)); QCOMPARE(p.size(), layoutMaximumSize); - QVERIFY(layoutHasConflict(l) == false); + QVERIFY(!layoutHasConflict(l)); // Test QSizePolicy::ExpandFlag, it shouldn't change the extreme // points of the layout... @@ -2041,9 +2040,9 @@ void tst_QGraphicsAnchorLayout::graphicsAnchorHandling() QGraphicsAnchor *invalidAnchor = l->anchor(a, Qt::AnchorTop, l, Qt::AnchorBottom); // Ensure none of these anchors are accessible. - QVERIFY(layoutAnchor == 0); - QVERIFY(itemAnchor == 0); - QVERIFY(invalidAnchor == 0); + QVERIFY(!layoutAnchor); + QVERIFY(!itemAnchor); + QVERIFY(!invalidAnchor); // Hook the anchors to a QObject QObject object; diff --git a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp index a2108dd49489f80597230e29f00720795276efa9..a58f2955759d05978e212a0d37b64939617fbf78 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp @@ -715,7 +715,7 @@ void tst_QGraphicsAnchorLayout1::testSpecialCases() widget1->setGeometry(QRectF(0,0,100,100)); QCOMPARE(childWidget->geometry(), QRectF(1,1,98,98)); - QVERIFY(childWidget->parentLayoutItem() == layout1); + QCOMPARE(childWidget->parentLayoutItem(), layout1); QGraphicsWidget *widget2 = new QGraphicsWidget; TheAnchorLayout *layout2 = new TheAnchorLayout(); widget2->setLayout(layout2); @@ -739,10 +739,10 @@ void tst_QGraphicsAnchorLayout1::testSpecialCases() widget2->setGeometry(QRectF(0,0,100,100)); QCOMPARE(childWidget->geometry(), QRectF(1,1,98,98)); - QVERIFY(childWidget->parentLayoutItem() == layout2); + QCOMPARE(childWidget->parentLayoutItem(), layout2); QCOMPARE(widget4->geometry(), QRectF(1,1,98,98)); - QVERIFY(widget4->parentLayoutItem() == layout2); - QVERIFY(widget4->parentItem() == widget2); + QCOMPARE(widget4->parentLayoutItem(), layout2); + QCOMPARE(widget4->parentItem(), widget2); delete widget4; delete widget3; diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro b/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro index 527f62b22d23e06ad91f2cd610e2275cd882de0b..66e39869bb6a301d42a67c6625110a4f9c63bc52 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro @@ -5,5 +5,5 @@ QT += core-private gui-private SOURCES += tst_qgraphicsitem.cpp DEFINES += QT_NO_CAST_TO_ASCII -win32:!wince*:!winrt: LIBS += -luser32 +win32:!wince:!winrt: LIBS += -luser32 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 0dd1161dcfb1b331586de2fa4622dbdba70994c0..835aeaa4df2cbeba0e62fba63d23a98f585b26b3 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4274,7 +4274,7 @@ void tst_QGraphicsItem::cursor() void tst_QGraphicsItem::textControlGetterSetter() { QGraphicsTextItem *item = new QGraphicsTextItem; - QVERIFY(item->textControl()->parent() == item); + QCOMPARE(item->textControl()->parent(), item); QPointer<QWidgetTextControl> control = item->textControl(); delete item; QVERIFY(!control); @@ -4285,7 +4285,7 @@ void tst_QGraphicsItem::textControlGetterSetter() control = new QWidgetTextControl; item->setTextControl(control); - QVERIFY(item->textControl() == control); + QCOMPARE(item->textControl(), control); QVERIFY(!control->parent()); QVERIFY(!oldControl); @@ -5141,19 +5141,19 @@ void tst_QGraphicsItem::paint() //nominal case, update call paint tester2.update(); qApp->processEvents(); - QTRY_VERIFY(tester2.painted == 2); + QTRY_COMPARE(tester2.painted, 2); //we remove the item from the scene, number of updates is still the same tester2.update(); scene2.removeItem(&tester2); qApp->processEvents(); - QTRY_VERIFY(tester2.painted == 2); + QTRY_COMPARE(tester2.painted, 2); //We re-add the item, the number of paint should increase scene2.addItem(&tester2); tester2.update(); qApp->processEvents(); - QTRY_VERIFY(tester2.painted == 3); + QTRY_COMPARE(tester2.painted, 3); } class HarakiriItem : public QGraphicsRectItem @@ -5878,7 +5878,7 @@ void tst_QGraphicsItem::itemContainsChildrenInShape() scene.setItemIndexMethod(QGraphicsScene::NoIndex); scene.addItem(parent); - QVERIFY(parent->boundingRectCalls == childOutsideShape->boundingRectCalls); + QCOMPARE(parent->boundingRectCalls, childOutsideShape->boundingRectCalls); int oldParentBoundingRectCalls = parent->boundingRectCalls; int oldChildBoundingRectCalls = childOutsideShape->boundingRectCalls; @@ -5886,10 +5886,10 @@ void tst_QGraphicsItem::itemContainsChildrenInShape() // First test that both items are searched if no optimization flags are set QGraphicsItem* item = scene.itemAt(25,5); - QVERIFY(item == childOutsideShape); + QCOMPARE(item, childOutsideShape); QVERIFY(parent->boundingRectCalls > oldParentBoundingRectCalls); QVERIFY(childOutsideShape->boundingRectCalls > oldChildBoundingRectCalls); - QVERIFY(parent->boundingRectCalls == childOutsideShape->boundingRectCalls); + QCOMPARE(parent->boundingRectCalls, childOutsideShape->boundingRectCalls); oldParentBoundingRectCalls = parent->boundingRectCalls; oldChildBoundingRectCalls = childOutsideShape->boundingRectCalls; @@ -5897,10 +5897,10 @@ void tst_QGraphicsItem::itemContainsChildrenInShape() // Repeat the test to make sure that no caching/indexing is in effect item = scene.itemAt(25,5); - QVERIFY(item == childOutsideShape); + QCOMPARE(item, childOutsideShape); QVERIFY(parent->boundingRectCalls > oldParentBoundingRectCalls); QVERIFY(childOutsideShape->boundingRectCalls > oldChildBoundingRectCalls); - QVERIFY(parent->boundingRectCalls == childOutsideShape->boundingRectCalls); + QCOMPARE(parent->boundingRectCalls, childOutsideShape->boundingRectCalls); oldParentBoundingRectCalls = parent->boundingRectCalls; oldChildBoundingRectCalls = childOutsideShape->boundingRectCalls; @@ -5912,7 +5912,7 @@ void tst_QGraphicsItem::itemContainsChildrenInShape() QVERIFY(!(item)); QVERIFY(parent->boundingRectCalls > oldParentBoundingRectCalls); - QVERIFY(childOutsideShape->boundingRectCalls == oldChildBoundingRectCalls); + QCOMPARE(childOutsideShape->boundingRectCalls, oldChildBoundingRectCalls); QVERIFY(parent->boundingRectCalls > childOutsideShape->boundingRectCalls); } @@ -11205,21 +11205,21 @@ void tst_QGraphicsItem::QTBUG_6738_missingUpdateWithSetParent() child2->setVisible(false); child2->setParentItem(child); - QTRY_VERIFY(view.repaints == 1); + QTRY_COMPARE(view.repaints, 1); // test case #2 view.reset(); child3->setOpacity(0.0); child3->setParentItem(child); - QTRY_VERIFY(view.repaints == 1); + QTRY_COMPARE(view.repaints, 1); // test case #3 view.reset(); child4->setParentItem(child); child4->setVisible(false); - QTRY_VERIFY(view.repaints == 1); + QTRY_COMPARE(view.repaints, 1); } void tst_QGraphicsItem::QT_2653_fullUpdateDiscardingOpacityUpdate() @@ -11469,9 +11469,9 @@ void tst_QGraphicsItem::itemDiesDuringDraggingOperation() QGraphicsSceneDragDropEvent event(QEvent::GraphicsSceneDragMove); event.setScenePos(item->boundingRect().center()); QApplication::sendEvent(&scene, &event); - QVERIFY(QGraphicsScenePrivate::get(&scene)->dragDropItem == item); + QCOMPARE(QGraphicsScenePrivate::get(&scene)->dragDropItem, item); delete item; - QVERIFY(QGraphicsScenePrivate::get(&scene)->dragDropItem == 0); + QVERIFY(!QGraphicsScenePrivate::get(&scene)->dragDropItem); } void tst_QGraphicsItem::QTBUG_12112_focusItem() diff --git a/tests/auto/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/auto/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp index bd104539ac95b1ff21a1115d010c822eda1bc412..a2740edc54f424e78feaa9f7e27d66c14dff4238 100644 --- a/tests/auto/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp @@ -948,7 +948,7 @@ void tst_QGraphicsLayout::ownership() destructedSet.clear(); window->setLayout(0); - QVERIFY(destructedSet.count() == 0); + QCOMPARE(destructedSet.count(), 0); delete window; } diff --git a/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp index 6a8b690560a5f6a44a2f1caf8cf4de9bf685deba..8bebd4edddfa1ef7acb3c0f05317a150f7f3169a 100644 --- a/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp @@ -1230,8 +1230,8 @@ void tst_QGraphicsLinearLayout::testStretch() layout->addStretch(2); layout->addItem(w2); QCOMPARE(layout->count(), 2); - QVERIFY(layout->itemAt(0) == w1); - QVERIFY(layout->itemAt(1) == w2); + QCOMPARE(layout->itemAt(0), w1); + QCOMPARE(layout->itemAt(1), w2); layout->activate(); //view->setSceneRect(-50, -50, 800, 800); diff --git a/tests/auto/widgets/graphicsview/qgraphicsobject/tst_qgraphicsobject.cpp b/tests/auto/widgets/graphicsview/qgraphicsobject/tst_qgraphicsobject.cpp index 84c39bbb983761cecce7b2d04fa1dff05dc88ca5..0f9e8c101eaaad4d91cf5c28892e46eebdce7ad1 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsobject/tst_qgraphicsobject.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsobject/tst_qgraphicsobject.cpp @@ -102,7 +102,7 @@ void tst_QGraphicsObject::pos() QCOMPARE(xSpy.count(), 1); QCOMPARE(ySpy.count(), 1); - QVERIFY(object.pos() == QPointF(10,10)); + QCOMPARE(object.pos(), QPointF(10,10)); object.setPos(10, 10); QCOMPARE(xSpy.count(), 1); @@ -111,12 +111,12 @@ void tst_QGraphicsObject::pos() object.setProperty("pos", QPointF(0, 0)); QCOMPARE(xSpy.count(), 2); QCOMPARE(ySpy.count(), 2); - QVERIFY(object.property("pos") == QPointF(0,0)); + QCOMPARE(object.property("pos").toPointF(), QPointF(0,0)); object.setProperty("pos", QPointF(10, 0)); QCOMPARE(xSpy.count(), 3); QCOMPARE(ySpy.count(), 2); - QVERIFY(object.property("pos") == QPointF(10,0)); + QCOMPARE(object.property("pos").toPointF(), QPointF(10,0)); object.setProperty("pos", QPointF(10, 10)); QCOMPARE(xSpy.count(), 3); @@ -135,7 +135,7 @@ void tst_QGraphicsObject::x() QCOMPARE(ySpy.count(), 0); QVERIFY(object.pos() == QPointF(10, 0)); - QVERIFY(object.x() == 10); + QCOMPARE(object.x(), qreal(10)); object.setX(10); QCOMPARE(xSpy.count(), 1); @@ -144,7 +144,7 @@ void tst_QGraphicsObject::x() object.setProperty("x", 0); QCOMPARE(xSpy.count(), 2); QCOMPARE(ySpy.count(), 0); - QVERIFY(object.property("x") == 0); + QCOMPARE(object.property("x").toDouble(), double(0)); } void tst_QGraphicsObject::y() @@ -158,7 +158,7 @@ void tst_QGraphicsObject::y() QCOMPARE(ySpy.count(), 1); QVERIFY(object.pos() == QPointF(0, 10)); - QVERIFY(object.y() == 10); + QCOMPARE(object.y(), qreal(10)); object.setY(10); QCOMPARE(xSpy.count(), 0); @@ -167,79 +167,79 @@ void tst_QGraphicsObject::y() object.setProperty("y", 0); QCOMPARE(xSpy.count(), 0); QCOMPARE(ySpy.count(), 2); - QVERIFY(object.property("y") == 0); + QCOMPARE(object.property("y").toDouble(), qreal(0)); } void tst_QGraphicsObject::z() { MyGraphicsObject object; QSignalSpy zSpy(&object, SIGNAL(zChanged())); - QVERIFY(object.zValue() == 0); + QCOMPARE(object.zValue(), qreal(0)); object.setZValue(10); QCOMPARE(zSpy.count(), 1); - QVERIFY(object.zValue() == 10); + QCOMPARE(object.zValue(), qreal(10)); object.setZValue(10); QCOMPARE(zSpy.count(), 1); object.setProperty("z", 0); QCOMPARE(zSpy.count(), 2); - QVERIFY(object.property("z") == 0); + QCOMPARE(object.property("z").toDouble(), double(0)); } void tst_QGraphicsObject::opacity() { MyGraphicsObject object; QSignalSpy spy(&object, SIGNAL(opacityChanged())); - QVERIFY(object.opacity() == 1.); + QCOMPARE(object.opacity(), 1.); object.setOpacity(0); QCOMPARE(spy.count(), 1); - QVERIFY(object.opacity() == 0.); + QCOMPARE(object.opacity(), 0.); object.setOpacity(0); QCOMPARE(spy.count(), 1); object.setProperty("opacity", .5); QCOMPARE(spy.count(), 2); - QVERIFY(object.property("opacity") == .5); + QCOMPARE(object.property("opacity").toDouble(), .5); } void tst_QGraphicsObject::enabled() { MyGraphicsObject object; QSignalSpy spy(&object, SIGNAL(enabledChanged())); - QVERIFY(object.isEnabled() == true); + QVERIFY(object.isEnabled()); object.setEnabled(false); QCOMPARE(spy.count(), 1); - QVERIFY(object.isEnabled() == false); + QVERIFY(!object.isEnabled()); object.setEnabled(false); QCOMPARE(spy.count(), 1); object.setProperty("enabled", true); QCOMPARE(spy.count(), 2); - QVERIFY(object.property("enabled") == true); + QVERIFY(object.property("enabled").toBool()); } void tst_QGraphicsObject::visible() { MyGraphicsObject object; QSignalSpy spy(&object, SIGNAL(visibleChanged())); - QVERIFY(object.isVisible() == true); + QVERIFY(object.isVisible()); object.setVisible(false); QCOMPARE(spy.count(), 1); - QVERIFY(object.isVisible() == false); + QVERIFY(!object.isVisible()); object.setVisible(false); QCOMPARE(spy.count(), 1); object.setProperty("visible", true); QCOMPARE(spy.count(), 2); - QVERIFY(object.property("visible") == true); + QVERIFY(object.property("visible").toBool()); } class DeleteTester : public QGraphicsObject diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 05a97dc2f3285ef03b5ecdad3725869c12828b55..4896d52343a8f92304a9aa545a83b81ddd3ed87c 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -97,8 +97,8 @@ private slots: void paint_2(); void setWidget_data(); void setWidget(); - void eventFilter_data(); - void eventFilter(); + void testEventFilter_data(); + void testEventFilter(); void focusInEvent_data(); void focusInEvent(); void focusInEventNoWidget(); @@ -314,7 +314,7 @@ void tst_QGraphicsProxyWidget::qgraphicsproxywidget() SubQGraphicsProxyWidget proxy; proxy.paint(0, 0, 0); proxy.setWidget(0); - QVERIFY(proxy.type() == QGraphicsProxyWidget::Type); + QCOMPARE(proxy.type(), int(QGraphicsProxyWidget::Type)); QVERIFY(!proxy.widget()); QEvent event(QEvent::None); proxy.call_eventFilter(0, &event); @@ -533,7 +533,7 @@ void tst_QGraphicsProxyWidget::setWidget() } Q_DECLARE_METATYPE(QEvent::Type) -void tst_QGraphicsProxyWidget::eventFilter_data() +void tst_QGraphicsProxyWidget::testEventFilter_data() { QTest::addColumn<QEvent::Type>("eventType"); QTest::addColumn<bool>("fromObject"); // big grin evil @@ -552,7 +552,7 @@ void tst_QGraphicsProxyWidget::eventFilter_data() } // protected bool eventFilter(QObject* object, QEvent* event) -void tst_QGraphicsProxyWidget::eventFilter() +void tst_QGraphicsProxyWidget::testEventFilter() { QFETCH(QEvent::Type, eventType); QFETCH(bool, fromObject); @@ -3017,36 +3017,36 @@ void tst_QGraphicsProxyWidget::createProxyForChildWidget() layout->addWidget(rightDial); window.setLayout(layout); - QVERIFY(window.graphicsProxyWidget() == 0); - QVERIFY(checkbox->graphicsProxyWidget() == 0); + QVERIFY(!window.graphicsProxyWidget()); + QVERIFY(!checkbox->graphicsProxyWidget()); QGraphicsProxyWidget *windowProxy = scene.addWidget(&window); QGraphicsView view(&scene); view.show(); view.resize(500,500); - QVERIFY(window.graphicsProxyWidget() == windowProxy); - QVERIFY(box->graphicsProxyWidget() == 0); - QVERIFY(checkbox->graphicsProxyWidget() == 0); + QCOMPARE(window.graphicsProxyWidget(), windowProxy); + QVERIFY(!box->graphicsProxyWidget()); + QVERIFY(!checkbox->graphicsProxyWidget()); QPointer<QGraphicsProxyWidget> checkboxProxy = windowProxy->createProxyForChildWidget(checkbox); QGraphicsProxyWidget *boxProxy = box->graphicsProxyWidget(); QVERIFY(boxProxy); - QVERIFY(checkbox->graphicsProxyWidget() == checkboxProxy); - QVERIFY(checkboxProxy->parentItem() == boxProxy); - QVERIFY(boxProxy->parentItem() == windowProxy); + QCOMPARE(checkbox->graphicsProxyWidget(), checkboxProxy.data()); + QCOMPARE(checkboxProxy->parentItem(), boxProxy); + QCOMPARE(boxProxy->parentItem(), windowProxy); QVERIFY(checkboxProxy->mapToScene(QPointF()) == checkbox->mapTo(&window, QPoint())); - QVERIFY(checkboxProxy->size() == checkbox->size()); - QVERIFY(boxProxy->size() == box->size()); + QCOMPARE(checkboxProxy->size().toSize(), checkbox->size()); + QCOMPARE(boxProxy->size().toSize(), box->size()); window.resize(500,500); - QVERIFY(windowProxy->size() == QSize(500,500)); + QCOMPARE(windowProxy->size().toSize(), QSize(500,500)); QVERIFY(checkboxProxy->mapToScene(QPointF()) == checkbox->mapTo(&window, QPoint())); - QVERIFY(checkboxProxy->size() == checkbox->size()); - QVERIFY(boxProxy->size() == box->size()); + QCOMPARE(checkboxProxy->size().toSize(), checkbox->size()); + QCOMPARE(boxProxy->size().toSize(), box->size()); QTest::qWait(10); @@ -3064,9 +3064,9 @@ void tst_QGraphicsProxyWidget::createProxyForChildWidget() boxProxy->setWidget(0); - QVERIFY(checkbox->graphicsProxyWidget() == 0); - QVERIFY(box->graphicsProxyWidget() == 0); - QVERIFY(checkboxProxy == 0); + QVERIFY(!checkbox->graphicsProxyWidget()); + QVERIFY(!box->graphicsProxyWidget()); + QVERIFY(checkboxProxy.isNull()); delete boxProxy; } @@ -3670,6 +3670,14 @@ void tst_QGraphicsProxyWidget::QTBUG_6986_sendMouseEventToAlienWidget() QTRY_COMPARE(scene.hoverButton->hoverLeaveReceived, true); } +static QByteArray msgPointMismatch(const QPoint &actual, const QPoint &expected) +{ + QString result; + QDebug(&result) << actual << " != " << expected << " manhattanLength=" + << (expected - actual).manhattanLength(); + return result.toLocal8Bit(); +} + void tst_QGraphicsProxyWidget::mapToGlobal() // QTBUG-41135 { const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry(); @@ -3681,20 +3689,29 @@ void tst_QGraphicsProxyWidget::mapToGlobal() // QTBUG-41135 view.move(availableGeometry.bottomRight() - QPoint(size.width(), size.height()) - QPoint(100, 100)); QWidget *embeddedWidget = new QWidget; embeddedWidget->setFixedSize(size / 2); + QWidget *childWidget = new QWidget(embeddedWidget); + childWidget->setStyleSheet(QLatin1String("background-color: \"red\"; ")); + childWidget->resize(embeddedWidget->size() / 2); + childWidget->move(embeddedWidget->width() / 4, embeddedWidget->height() / 4); // center in embeddedWidget scene.addWidget(embeddedWidget); QApplication::setActiveWindow(&view); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); - const QPoint embeddedCenter = embeddedWidget->geometry().center(); + const QPoint embeddedCenter = embeddedWidget->rect().center(); const QPoint embeddedCenterGlobal = embeddedWidget->mapToGlobal(embeddedCenter); QCOMPARE(embeddedWidget->mapFromGlobal(embeddedCenterGlobal), embeddedCenter); // This should be equivalent to the view center give or take rounding // errors due to odd window margins const QPoint viewCenter = view.geometry().center(); QVERIFY2((viewCenter - embeddedCenterGlobal).manhattanLength() <= 2, - qPrintable(QStringLiteral("%1, %2 != %3, %4") - .arg(viewCenter.x()).arg(viewCenter.y()) - .arg(embeddedCenterGlobal.x()).arg(embeddedCenterGlobal.y()))); + msgPointMismatch(embeddedCenterGlobal, viewCenter).constData()); + + // Same test with child centered on embeddedWidget + const QPoint childCenter = childWidget->rect().center(); + const QPoint childCenterGlobal = childWidget->mapToGlobal(childCenter); + QCOMPARE(childWidget->mapFromGlobal(childCenterGlobal), childCenter); + QVERIFY2((viewCenter - childCenterGlobal).manhattanLength() <= 4, + msgPointMismatch(childCenterGlobal, viewCenter).constData()); } void tst_QGraphicsProxyWidget::mapToGlobalWithoutScene() // QTBUG-44509 diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro b/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro index a6022e0d7dc71415df36e368ebb4d9faf8649f9f..25a43d682169cc7a58a9265c286e161e25829b13 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro @@ -4,9 +4,9 @@ QT += widgets widgets-private testlib QT += core-private gui-private SOURCES += tst_qgraphicsscene.cpp RESOURCES += images.qrc -win32:!wince*:!winrt: LIBS += -luser32 +win32:!wince:!winrt: LIBS += -luser32 -!wince*:DEFINES += SRCDIR=\\\"$$PWD\\\" +!wince: DEFINES += SRCDIR=\\\"$$PWD\\\" DEFINES += QT_NO_CAST_TO_ASCII wince* { diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp index ff29f998754e4be69568e54af2bdc2c7038ed212..ae71b0412fcb99320b82cd0dca91c2f4a917434a 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp @@ -4727,9 +4727,9 @@ void tst_QGraphicsScene::minimumRenderSize() QTRY_VERIFY(view.repaints > viewRepaints); viewRepaints = view.repaints; - QVERIFY(viewRepaints == bigParent->repaints); - QVERIFY(viewRepaints == smallChild->repaints); - QVERIFY(viewRepaints == smallerGrandChild->repaints); + QCOMPARE(viewRepaints, bigParent->repaints); + QCOMPARE(viewRepaints, smallChild->repaints); + QCOMPARE(viewRepaints, smallerGrandChild->repaints); // Setting a minimum render size should cause a repaint scene.setMinimumRenderSize(0.5); @@ -4738,9 +4738,9 @@ void tst_QGraphicsScene::minimumRenderSize() QTRY_VERIFY(view.repaints > viewRepaints); viewRepaints = view.repaints; - QVERIFY(viewRepaints == bigParent->repaints); - QVERIFY(viewRepaints == smallChild->repaints); - QVERIFY(viewRepaints == smallerGrandChild->repaints); + QCOMPARE(viewRepaints, bigParent->repaints); + QCOMPARE(viewRepaints, smallChild->repaints); + QCOMPARE(viewRepaints, smallerGrandChild->repaints); // Scaling should cause a repaint of big items only. view.scale(0.1, 0.1); @@ -4749,8 +4749,8 @@ void tst_QGraphicsScene::minimumRenderSize() QTRY_VERIFY(view.repaints > viewRepaints); viewRepaints = view.repaints; - QVERIFY(viewRepaints == bigParent->repaints); - QVERIFY(viewRepaints == smallChild->repaints); + QCOMPARE(viewRepaints, bigParent->repaints); + QCOMPARE(viewRepaints, smallChild->repaints); QVERIFY(smallChild->repaints > smallerGrandChild->repaints); // Scaling further should cause even fewer items to be repainted @@ -4760,7 +4760,7 @@ void tst_QGraphicsScene::minimumRenderSize() QTRY_VERIFY(view.repaints > viewRepaints); viewRepaints = view.repaints; - QVERIFY(viewRepaints == bigParent->repaints); + QCOMPARE(viewRepaints, bigParent->repaints); QVERIFY(bigParent->repaints > smallChild->repaints); QVERIFY(smallChild->repaints > smallerGrandChild->repaints); } diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST index be7a7e398b4820d96b894cfef417e4174cb7c9cc..3cba8bad7e6cf99aac971db34feabcd457c28b8b 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST +++ b/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST @@ -1,4 +1,18 @@ [task255529_transformationAnchorMouseAndViewportMargins] -ubuntu-14.04 +xcb [cursor] -ubuntu-14.04 +xcb +[cursor2] +xcb +[rubberBandExtendSelection] +xcb +[rotated_rubberBand] +xcb +[sendEvent] +xcb +[forwardMousePress] +xcb +[hoverLeave] +xcb +[resizeAnchor] +xcb diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 119e9dfecb663d467ca54d93024151af558f6b8c..6db42952864c589f0366041bc950100cf891f3d2 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -2683,7 +2683,7 @@ void tst_QGraphicsView::optimizationFlags_dontSavePainterState() view.viewport()->repaint(); #ifdef Q_OS_MAC - // Repaint on Mac OS X actually does require spinning the event loop. + // Repaint on OS X actually does require spinning the event loop. QTest::qWait(100); #endif QVERIFY(!parent->dirtyPainter); @@ -3525,7 +3525,7 @@ void tst_QGraphicsView::embeddedViews() v2->QWidget::render(&actual); QTransform b = item->transform; - QVERIFY(a == b); + QCOMPARE(a, b); delete v1; } diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index 90580aea05f1c26c5e76bb0a3e69607d1a7d4e64..fac3f5857b923e37f7cc41b75a7483a3c9bb2ca6 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -197,16 +197,11 @@ class tst_QAbstractItemView : public QObject Q_OBJECT public: - - tst_QAbstractItemView(); - virtual ~tst_QAbstractItemView(); void basic_tests(TestView *view); -public slots: - void initTestCase(); - void cleanupTestCase(); - private slots: + void initTestCase(); + void cleanup(); void getSetCheck(); void emptyModels_data(); void emptyModels(); @@ -360,14 +355,6 @@ void tst_QAbstractItemView::getSetCheck() QCOMPARE(16, obj1->autoScrollMargin()); } -tst_QAbstractItemView::tst_QAbstractItemView() -{ -} - -tst_QAbstractItemView::~tst_QAbstractItemView() -{ -} - void tst_QAbstractItemView::initTestCase() { #ifdef Q_OS_WINCE_WM @@ -375,8 +362,9 @@ void tst_QAbstractItemView::initTestCase() #endif } -void tst_QAbstractItemView::cleanupTestCase() +void tst_QAbstractItemView::cleanup() { + QVERIFY(QApplication::topLevelWidgets().isEmpty()); } void tst_QAbstractItemView::emptyModels_data() @@ -1048,7 +1036,7 @@ void tst_QAbstractItemView::dragAndDropOnChild() ++successes; } - QVERIFY(successes == 0); + QCOMPARE(successes, 0); } #endif // 0 @@ -1226,7 +1214,7 @@ void tst_QAbstractItemView::setCurrentIndex() view->setModel(model); view->setCurrentIndex(model->index(0,0)); - QVERIFY(view->currentIndex() == model->index(0,0)); + QCOMPARE(view->currentIndex(), model->index(0,0)); view->setCurrentIndex(model->index(1,0)); QVERIFY(view->currentIndex() == model->index(result ? 1 : 0,0)); } @@ -1330,8 +1318,7 @@ void tst_QAbstractItemView::task200665_itemEntered() moveCursorAway(&view); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); - QRect rect = view.visualRect(model.index(0,0)); - QCursor::setPos( view.viewport()->mapToGlobal(rect.center()) ); + QCursor::setPos( view.geometry().center() ); QCoreApplication::processEvents(); QSignalSpy spy(&view, SIGNAL(entered(QModelIndex))); view.verticalScrollBar()->setValue(view.verticalScrollBar()->maximum()); diff --git a/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp b/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp index f5e6facaadc3e9ec89d723100b4eed6d6a72952b..6645da727c0bc7fa3c99093cd65159e78b1ae177 100644 --- a/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp +++ b/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp @@ -292,7 +292,7 @@ void tst_QColumnView::grips() for (int i = 0 ; i < list.count(); ++i) { if (QAbstractItemView *view = qobject_cast<QAbstractItemView*>(list.at(i))) { if (view->isVisible()) - QVERIFY(view->cornerWidget() == 0); + QVERIFY(!view->cornerWidget()); } } } @@ -587,7 +587,7 @@ void tst_QColumnView::selectAll() QVERIFY(view.selectionModel()->selectedIndexes().count() > 0); view.setCurrentIndex(QModelIndex()); - QVERIFY(view.selectionModel()->selectedIndexes().count() == 0); + QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0); } void tst_QColumnView::clicked() diff --git a/tests/auto/widgets/itemviews/qdirmodel/qdirmodel.pro b/tests/auto/widgets/itemviews/qdirmodel/qdirmodel.pro index 79848ac22cce7e905539ed1ac1d9c54603210c73..f1bc968b880b278e46053355fc0e5a680031f47c 100644 --- a/tests/auto/widgets/itemviews/qdirmodel/qdirmodel.pro +++ b/tests/auto/widgets/itemviews/qdirmodel/qdirmodel.pro @@ -13,7 +13,7 @@ wince* { DEPLOYMENT += addit tests sourceFile } -android|wince*: { +android|wince { DEFINES += SRCDIR=\\\"./\\\" } else { DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp b/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp index 0bc972d0cb9ae740b31e3aa94ef244fe1ef9f687..fba83a24c71f8985acfa46fb4a6d15936b3720ca 100644 --- a/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp +++ b/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp @@ -58,6 +58,8 @@ private slots: void type_data(); void type(); + + void taskQTBUG_46755_QFileIconEngine_crash(); }; // Subclass that exposes the protected functions. @@ -167,6 +169,21 @@ void tst_QFileIconProvider::type() QVERIFY(!provider.type(info).isEmpty()); } +static QIcon getIcon() +{ + QFileIconProvider fip; + return fip.icon(QDir::currentPath()); +} + +void tst_QFileIconProvider::taskQTBUG_46755_QFileIconEngine_crash() +{ + const QIcon &icon = getIcon(); + foreach (const QSize &size, icon.availableSizes()) + icon.pixmap(size); + + // No crash, all good. +} + QTEST_MAIN(tst_QFileIconProvider) #include "tst_qfileiconprovider.moc" diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index 21e4b823663ed8bf6662df1c54b9354518899f0e..7e73c19539e07fd2a080fc4dda697fc4543b9000 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -403,7 +403,7 @@ void tst_QHeaderView::init() view = new QHeaderView(Qt::Vertical,topLevel); // Some initial value tests before a model is added QCOMPARE(view->length(), 0); - QVERIFY(view->sizeHint() == QSize(0,0)); + QCOMPARE(view->sizeHint(), QSize(0,0)); QCOMPARE(view->sectionSizeHint(0), -1); /* @@ -925,9 +925,9 @@ void tst_QHeaderView::moveSection() QFETCH(QList<int>, logical); QFETCH(int, count); - QVERIFY(from.count() == to.count()); - QVERIFY(from.count() == moved.count()); - QVERIFY(view->count() == logical.count()); + QCOMPARE(from.count(), to.count()); + QCOMPARE(from.count(), moved.count()); + QCOMPARE(view->count(), logical.count()); QSignalSpy spy1(view, SIGNAL(sectionMoved(int,int,int))); QCOMPARE(view->sectionsMoved(), false); @@ -1370,15 +1370,15 @@ void tst_QHeaderView::unhideSection() QCOMPARE(view->sectionsHidden(), false); view->setSectionHidden(0, true); QCOMPARE(view->sectionsHidden(), true); - QVERIFY(view->sectionSize(0) == 0); + QCOMPARE(view->sectionSize(0), 0); view->setSectionResizeMode(QHeaderView::Interactive); view->setSectionHidden(0, false); QVERIFY(view->sectionSize(0) > 0); view->setSectionHidden(0, true); - QVERIFY(view->sectionSize(0) == 0); + QCOMPARE(view->sectionSize(0), 0); view->setSectionHidden(0, true); - QVERIFY(view->sectionSize(0) == 0); + QCOMPARE(view->sectionSize(0), 0); view->setSectionResizeMode(QHeaderView::Stretch); view->setSectionHidden(0, false); QVERIFY(view->sectionSize(0) > 0); @@ -1645,7 +1645,7 @@ void tst_QHeaderView::saveRestore() QByteArray s2 = h2.saveState(); - QVERIFY(s1 == s2); + QCOMPARE(s1, s2); QVERIFY(!h2.restoreState(QByteArrayLiteral("Garbage"))); // QTBUG-40462 @@ -1659,7 +1659,7 @@ void tst_QHeaderView::saveRestore() int sectionItemsLengthTotal = 0; for (int i = 0; i < h2.count(); ++i) sectionItemsLengthTotal += h2.sectionSize(i); - QVERIFY(sectionItemsLengthTotal == h2.length()); + QCOMPARE(sectionItemsLengthTotal, h2.length()); // Buggy setting where sum(sectionItems) != length. Check false is returned and this corrupted // state isn't restored @@ -1676,8 +1676,8 @@ void tst_QHeaderView::saveRestore() // Check setting is correctly recognized as corrupted QVERIFY(!h2.restoreState(settings_buggy_length)); // Check nothing has been actually restored - QVERIFY(h2.length() == old_length); - QVERIFY(h2.saveState() == old_state); + QCOMPARE(h2.length(), old_length); + QCOMPARE(h2.saveState(), old_state); } void tst_QHeaderView::defaultSectionSizeTest() @@ -1699,7 +1699,7 @@ void tst_QHeaderView::defaultSectionSizeTest() // no hidden Sections hv->resizeSection(1, 0); hv->setDefaultSectionSize(defaultSize); - QVERIFY(hv->sectionSize(1) == defaultSize); + QCOMPARE(hv->sectionSize(1), defaultSize); // with hidden sections hv->resizeSection(1, 0); @@ -2277,7 +2277,7 @@ void tst_QHeaderView::QTBUG14242_hideSectionAutoSize() for (int u = 0; u < hv->count(); ++u) calced_length += hv->sectionSize(u); - QVERIFY(calced_length == afterlength); + QCOMPARE(calced_length, afterlength); } void tst_QHeaderView::ensureNoIndexAtLength() @@ -2286,9 +2286,9 @@ void tst_QHeaderView::ensureNoIndexAtLength() QStandardItemModel amodel(4, 4); qtv.setModel(&amodel); QHeaderView *hv = qtv.verticalHeader(); - QVERIFY(hv->visualIndexAt(hv->length()) == -1); + QCOMPARE(hv->visualIndexAt(hv->length()), -1); hv->resizeSection(hv->count() - 1, 0); - QVERIFY(hv->visualIndexAt(hv->length()) == -1); + QCOMPARE(hv->visualIndexAt(hv->length()), -1); } void tst_QHeaderView::offsetConsistent() @@ -2307,7 +2307,7 @@ void tst_QHeaderView::offsetConsistent() hv->hideSection(sectionToHide); hv->setOffsetToSectionPosition(150); int offset2 = hv->offset(); - QVERIFY(offset1 == offset2); + QCOMPARE(offset1, offset2); // Ensure that hidden indexes (still) is considered. hv->resizeSection(sectionToHide, hv->sectionSize(200) * 2); hv->setOffsetToSectionPosition(800); @@ -2600,8 +2600,8 @@ void tst_QHeaderView::logicalIndexAtTest() //qDebug() << "logicalIndexAtTest" << check1 << check2; const int precalced_check1 = 106327; const int precalced_check2 = 29856418; - QVERIFY(precalced_check1 == check1); - QVERIFY(precalced_check2 == check2); + QCOMPARE(precalced_check1, check1); + QCOMPARE(precalced_check2, check2); const int precalced_results[] = { 1145298384, -1710423344, -650981936, 372919464, -1544372176, -426463328, 12124 }; calculateAndCheck(__LINE__, precalced_results); @@ -2628,8 +2628,8 @@ void tst_QHeaderView::visualIndexAtTest() //qDebug() << "visualIndexAtTest" << check1 << check2; const int precalced_check1 = 72665; const int precalced_check2 = 14015890; - QVERIFY(precalced_check1 == check1); - QVERIFY(precalced_check2 == check2); + QCOMPARE(precalced_check1, check1); + QCOMPARE(precalced_check2, check2); const int precalced_results[] = { 1145298384, -1710423344, -1457520212, 169223959, 557466160, -324939600, 5453 }; calculateAndCheck(__LINE__, precalced_results); diff --git a/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro b/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro index 313cadd6a14ccf0d3c65612157287d8218a84530..f7fb41e60c136f75167d6cead7e5b20d2b6f2765 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro +++ b/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro @@ -3,4 +3,4 @@ TARGET = tst_qitemdelegate QT += widgets testlib SOURCES += tst_qitemdelegate.cpp -win32:!wince*:!winrt: LIBS += -luser32 +win32:!wince:!winrt: LIBS += -luser32 diff --git a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp index 3bd41121226ad9970cbed0030aee683543c51825..25f27cb0c7b11afd3f85af4dc803d2b249776cee 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp @@ -804,9 +804,9 @@ void tst_QItemDelegate::dateTimeEditor() dateTimeEditor->setTime(time.addSecs(600)); widget.clearFocus(); - QVERIFY(item1->data(Qt::EditRole).userType() == QMetaType::QTime); - QVERIFY(item2->data(Qt::EditRole).userType() == QMetaType::QDate); - QVERIFY(item3->data(Qt::EditRole).userType() == QMetaType::QDateTime); + QCOMPARE(item1->data(Qt::EditRole).userType(), int(QMetaType::QTime)); + QCOMPARE(item2->data(Qt::EditRole).userType(), int(QMetaType::QDate)); + QCOMPARE(item3->data(Qt::EditRole).userType(), int(QMetaType::QDateTime)); } // A delegate where we can either enforce a certain widget or use the standard widget. @@ -901,9 +901,9 @@ void tst_QItemDelegate::dateAndTimeEditorTest2() s.setData(i1, datetime2); editor = w.fastEdit(i1); timeEdit = qobject_cast<QTimeEdit*>(editor); - QVERIFY(timeEdit == 0); + QVERIFY(!timeEdit); dateEdit = qobject_cast<QDateEdit*>(editor); - QVERIFY(dateEdit == 0); + QVERIFY(!dateEdit); dateTimeEdit = qobject_cast<QDateTimeEdit*>(editor); QVERIFY(dateTimeEdit); QCOMPARE(dateTimeEdit->dateTime(), datetime2); diff --git a/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp b/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp index f92eb7c8f961b01a11feb164586ca188f7b72067..8fd86ea46736c0f4d935e2a4285c078f78bd6aa5 100644 --- a/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp +++ b/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp @@ -552,7 +552,7 @@ void tst_QItemView::visualRect() QFETCH(bool, displays); if (!displays){ - QVERIFY(view->visualRect(topIndex) == QRect()); + QCOMPARE(view->visualRect(topIndex), QRect()); return; } @@ -560,15 +560,15 @@ void tst_QItemView::visualRect() view->show(); QVERIFY(view->visualRect(topIndex) != QRect()); - QVERIFY(topIndex == view->indexAt(view->visualRect(topIndex).center())); - QVERIFY(topIndex == view->indexAt(view->visualRect(topIndex).bottomLeft())); - QVERIFY(topIndex == view->indexAt(view->visualRect(topIndex).bottomRight())); - QVERIFY(topIndex == view->indexAt(view->visualRect(topIndex).topLeft())); - QVERIFY(topIndex == view->indexAt(view->visualRect(topIndex).topRight())); + QCOMPARE(topIndex, view->indexAt(view->visualRect(topIndex).center())); + QCOMPARE(topIndex, view->indexAt(view->visualRect(topIndex).bottomLeft())); + QCOMPARE(topIndex, view->indexAt(view->visualRect(topIndex).bottomRight())); + QCOMPARE(topIndex, view->indexAt(view->visualRect(topIndex).topLeft())); + QCOMPARE(topIndex, view->indexAt(view->visualRect(topIndex).topRight())); testViews->hideIndexes(view); QModelIndex hiddenIndex = treeModel->index(1, 0); - QVERIFY(view->visualRect(hiddenIndex) == QRect()); + QCOMPARE(view->visualRect(hiddenIndex), QRect()); } void tst_QItemView::walkScreen(QAbstractItemView *view) @@ -616,7 +616,7 @@ void walkIndex(QModelIndex index, QAbstractItemView *view) if (view->indexAt(point) != index) { qDebug() << "index" << index << "visualRect" << visualRect << point << view->indexAt(point); } - QVERIFY(view->indexAt(point) == index); + QCOMPARE(view->indexAt(point), index); } } diff --git a/tests/auto/widgets/itemviews/qlistview/qlistview.pro b/tests/auto/widgets/itemviews/qlistview/qlistview.pro index 1ea8beb8df52b1e1f97f30818478671c14c66392..509303b62e46e346bb5133f3eeecdba6ad7924bf 100644 --- a/tests/auto/widgets/itemviews/qlistview/qlistview.pro +++ b/tests/auto/widgets/itemviews/qlistview/qlistview.pro @@ -2,4 +2,5 @@ CONFIG += testcase TARGET = tst_qlistview QT += widgets gui-private widgets-private core-private testlib SOURCES += tst_qlistview.cpp -win32:!wince*:!winrt: LIBS += -luser32 +win32:!wince:!winrt: LIBS += -luser32 +linux*: CONFIG += insignificant_test # Crashes diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index b06a63365c8830a128b9c9493083c6b426da943c..fc671fdc9f98221cbe93d0dd2450655fde394945 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -306,6 +306,7 @@ void tst_QListView::init() void tst_QListView::cleanup() { + QVERIFY(QApplication::topLevelWidgets().isEmpty()); } @@ -791,14 +792,31 @@ void tst_QListView::hideFirstRow() QTest::qWait(10); } +static int modelIndexCount(const QAbstractItemView *view) +{ + QBitArray ba; + for (int y = 0, height = view->height(); y < height; ++y) { + const QModelIndex idx = view->indexAt( QPoint(1, y) ); + if (!idx.isValid()) + break; + if (idx.row() >= ba.size()) + ba.resize(idx.row() + 1); + ba.setBit(idx.row(), true); + } + return ba.size(); +} + void tst_QListView::batchedMode() { + const int rowCount = 3; + QStringList items; - for (int i=0; i <3; ++i) - items << "item"; + for (int i = 0; i < rowCount; ++i) + items << QLatin1String("item ") + QString::number(i); QStringListModel model(items); QListView view; + view.setWindowTitle(QTest::currentTestFunction()); view.setModel(&model); view.setUniformItemSizes(true); view.setViewMode(QListView::ListMode); @@ -807,22 +825,8 @@ void tst_QListView::batchedMode() view.resize(200,400); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); - QTest::qWait(100); - -#if defined(Q_OS_WINCE) - QTest::qWait(2000); -#endif - QBitArray ba; - for (int y = 0; y < view.height(); ++y) { - QModelIndex idx = view.indexAt( QPoint(1, y) ); - if (!idx.isValid()) - break; - if (idx.row() >= ba.size()) - ba.resize(idx.row() + 1); - ba.setBit(idx.row(), true); - } - QCOMPARE(ba.size(), 3); + QTRY_COMPARE(modelIndexCount(&view), rowCount); // Test the dynamic listview too. view.setViewMode(QListView::IconMode); @@ -830,22 +834,7 @@ void tst_QListView::batchedMode() view.setFlow(QListView::TopToBottom); view.setBatchSize(2); -#if !defined(Q_OS_WINCE) - QTest::qWait(100); -#else - QTest::qWait(2000); -#endif - - ba.clear(); - for (int y = 0; y < view.height(); ++y) { - QModelIndex idx = view.indexAt( QPoint(1, y) ); - if (!idx.isValid()) - break; - if (idx.row() >= ba.size()) - ba.resize(idx.row() + 1); - ba.setBit(idx.row(), true); - } - QCOMPARE(ba.size(), 3); + QTRY_COMPARE(modelIndexCount(&view), rowCount); } void tst_QListView::setCurrentIndex() @@ -2467,10 +2456,10 @@ void tst_QListView::horizontalScrollingByVerticalWheelEvents() QVERIFY(lv.horizontalScrollBar()->value() > hValue); QApplication::sendEvent(lv.viewport(), &wheelUpEvent); - QVERIFY(lv.horizontalScrollBar()->value() == hValue); + QCOMPARE(lv.horizontalScrollBar()->value(), hValue); QApplication::sendEvent(lv.viewport(), &wheelLeftDownEvent); - QVERIFY(lv.horizontalScrollBar()->value() == hValue); + QCOMPARE(lv.horizontalScrollBar()->value(), hValue); // ensure that vertical wheel events are not converted when vertical // scroll bar is not visible but vertical scrolling is possible diff --git a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp index dcbdbe824ad39809941ec1da00663d62e42a93ca..ecf72613da6571c7e877f5c1c2bfc4a6a21c1bd7 100644 --- a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp @@ -427,9 +427,9 @@ void tst_QListWidget::currentItem() // actual test QModelIndex currentIndex = testWidget->selectionModel()->currentIndex(); if (currentIndex.isValid()) - QVERIFY(testWidget->currentItem() == testWidget->item(currentIndex.row())); + QCOMPARE(testWidget->currentItem(), testWidget->item(currentIndex.row())); else - QVERIFY(testWidget->currentItem() == (QListWidgetItem*)0); + QCOMPARE(testWidget->currentItem(), (QListWidgetItem*)0); } void tst_QListWidget::currentRow() @@ -742,7 +742,7 @@ void tst_QListWidget::selectedItems() QFETCH(IntList, selectedRows); QFETCH(IntList, expectedRows); - QVERIFY(testWidget->count() == 0); + QCOMPARE(testWidget->count(), 0); //insert items for (int i=0; i<itemCount; ++i) @@ -1159,7 +1159,7 @@ void tst_QListWidget::setData() QFETCH(int, expectedSignalCount); qRegisterMetaType<QListWidgetItem *>("QListWidgetItem*"); - QVERIFY(roles.count() == values.count()); + QCOMPARE(roles.count(), values.count()); for (int manipulateModel=0; manipulateModel<2; ++manipulateModel) { testWidget->clear(); @@ -1711,7 +1711,7 @@ void tst_QListWidget::mimeData() QVERIFY(data->hasFormat(format)); QVERIFY(data2->hasFormat(format)); - QVERIFY(data->data(format) == data2->data(format)); + QCOMPARE(data->data(format), data2->data(format)); delete data; delete data2; diff --git a/tests/auto/widgets/itemviews/qtableview/BLACKLIST b/tests/auto/widgets/itemviews/qtableview/BLACKLIST index fc231a4e30411152bbaaf41a5eca5f612a3c6c2d..329010a86e3629238829132ed4bad90f8c228c65 100644 --- a/tests/auto/widgets/itemviews/qtableview/BLACKLIST +++ b/tests/auto/widgets/itemviews/qtableview/BLACKLIST @@ -1,2 +1,4 @@ [moveCursorBiggerJump] osx +[resizeColumnsToContents] +ubuntu-14.04 diff --git a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp index 36bc23910c3deb5a47d843c4f12b8af126cf31ec..6d2b2ea964730c9d68e03a8f75a0fd3652876ff2 100644 --- a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp +++ b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp @@ -196,9 +196,9 @@ void tst_QTableWidget::clearContents() { QTableWidgetItem *item = new QTableWidgetItem("test"); testWidget->setHorizontalHeaderItem(0, item); - QVERIFY(testWidget->horizontalHeaderItem(0) == item); + QCOMPARE(testWidget->horizontalHeaderItem(0), item); testWidget->clearContents(); - QVERIFY(testWidget->horizontalHeaderItem(0) == item); + QCOMPARE(testWidget->horizontalHeaderItem(0), item); } void tst_QTableWidget::clear() @@ -1559,7 +1559,7 @@ void tst_QTableWidget::mimeData() QVERIFY(data->hasFormat(format)); QVERIFY(data2->hasFormat(format)); - QVERIFY(data->data(format) == data2->data(format)); + QCOMPARE(data->data(format), data2->data(format)); delete data; delete data2; diff --git a/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro b/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro index 3abd58e73d9b6a026859a23ef07abc375fe5d43e..e8406dab7b1e4fa2e6988a3154b009fcfab7006c 100644 --- a/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro +++ b/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro @@ -4,3 +4,5 @@ QT += widgets testlib QT += widgets-private gui-private core-private SOURCES += tst_qtreeview.cpp HEADERS += ../../../../shared/fakedirmodel.h + +win32: CONFIG += insignificant_test diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 1324027af64daa037f43fd84798c197061804bfe..4edf5d1a3b041c830b3d6ef62c669030519792cc 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -850,7 +850,7 @@ void tst_QTreeView::editTriggers() case QAbstractItemView::EditKeyPressed: view.setFocus(); #ifdef Q_OS_MAC - // Mac OS X uses Enter for editing + // OS X uses Enter for editing QTest::keyPress(&view, Qt::Key_Enter); #else // All other platforms use F2 @@ -3657,7 +3657,7 @@ void tst_QTreeView::task202039_closePersistentEditor() QVERIFY(view.indexWidget(current)); view.closePersistentEditor(current); - QVERIFY(view.indexWidget(current) == 0); + QVERIFY(!view.indexWidget(current)); //here was the bug: closing the persistent editor would not reset the state //and it was impossible to go into editinon again diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp index b63d6b5b8956fcd1481a1a86d6c4a2d32b501e76..727bc41478cab6dd6a70d01bca17f6feac7571a1 100644 --- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp +++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp @@ -1586,7 +1586,7 @@ void tst_QTreeWidget::scrollToItem() testWidget->setHeaderLabels(QStringList() << "foo"); testWidget->scrollToItem(search); - QVERIFY(search->text(0) == "111"); + QCOMPARE(search->text(0), QLatin1String("111")); bar = search->parent(); QVERIFY(testWidget->isItemExpanded(bar)); @@ -2287,7 +2287,7 @@ void tst_QTreeWidget::insertExpandedItemsWithSorting() QCOMPARE(parent->childCount(), childText.count()); QVERIFY(parent->isExpanded()); } - QVERIFY(tree.model()->rowCount() == parentText.count()); + QCOMPARE(tree.model()->rowCount(), parentText.count()); // verify that the items are still expanded foreach (QTreeWidgetItem *item, items) { @@ -2659,7 +2659,7 @@ void tst_QTreeWidget::sortedIndexOfChild() tw.sortItems(0, (Qt::SortOrder)sortOrder); tw.expandAll(); - QVERIFY(itms.count() == expectedIndexes.count()); + QCOMPARE(itms.count(), expectedIndexes.count()); for (int j = 0; j < expectedIndexes.count(); ++j) QCOMPARE(top->indexOfChild(itms.at(j)), expectedIndexes.at(j)); } @@ -3235,7 +3235,7 @@ void tst_QTreeWidget::setCurrentItemExpandsParent() QTreeWidgetItem *i1 = new QTreeWidgetItem(&w, QStringList() << "parent"); QTreeWidgetItem *i2 = new QTreeWidgetItem(i1, QStringList() << "child"); QVERIFY(!i2->isExpanded()); - QVERIFY(w.currentItem() == 0); + QVERIFY(!w.currentItem()); w.setCurrentItem(i2); QVERIFY(!i2->isExpanded()); QCOMPARE(w.currentItem(), i2); diff --git a/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp b/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp index 490f87a7ef9e86d7c74f9bc57a1a74288c1db911..c52198fa2c357f5c5be413b26e6eff801eaf4105 100644 --- a/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp +++ b/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp @@ -1112,13 +1112,13 @@ void tst_QTreeWidgetItemIterator::updateIfModifiedFromWidget() delete item; item = *it; if (expecteditemIsNull) { - QVERIFY(item == 0); + QVERIFY(!item); } else { QVERIFY(item); QCOMPARE(item->text(0), expecteditemvalue); item = *itRemove; if (expectedUpdatedCurrent.isNull()) { - QVERIFY(item == 0); + QVERIFY(!item); } else { QCOMPARE(item->text(0), expectedUpdatedCurrent); } diff --git a/tests/auto/widgets/kernel/qaction/BLACKLIST b/tests/auto/widgets/kernel/qaction/BLACKLIST index a2afc905ba5096439eea049692b9184e21f73c67..1ad524fdbf4f589192a725a5e3288aa02c03f9c1 100644 --- a/tests/auto/widgets/kernel/qaction/BLACKLIST +++ b/tests/auto/widgets/kernel/qaction/BLACKLIST @@ -1,2 +1,2 @@ [setStandardKeys] -ubuntu +linux diff --git a/tests/auto/widgets/kernel/qaction/tst_qaction.cpp b/tests/auto/widgets/kernel/qaction/tst_qaction.cpp index be1fed2be3ff75614c2baa34a974a1c01d086847..71b55d71ea9ce3b58c399cb381ca4578c638dd90 100644 --- a/tests/auto/widgets/kernel/qaction/tst_qaction.cpp +++ b/tests/auto/widgets/kernel/qaction/tst_qaction.cpp @@ -69,6 +69,7 @@ private slots: void task200823_tooltip(); void task229128TriggeredSignalWithoutActiongroup(); void task229128TriggeredSignalWhenInActiongroup(); + void repeat(); private: int m_lastEventType; @@ -241,7 +242,7 @@ void tst_QAction::setStandardKeys() QList<QKeySequence> list; act.setShortcuts(list); act.setShortcuts(QKeySequence::Copy); - QVERIFY(act.shortcut() == act.shortcuts().first()); + QCOMPARE(act.shortcut(), act.shortcuts().first()); QList<QKeySequence> expected; const QKeySequence ctrlC = QKeySequence(QStringLiteral("CTRL+C")); @@ -380,5 +381,42 @@ void tst_QAction::task229128TriggeredSignalWhenInActiongroup() QCOMPARE(actionSpy.count(), 1); } +void tst_QAction::repeat() +{ + QWidget *wid = m_tstWidget; + QAction act(wid); + wid->addAction(&act); + act.setShortcut(QKeySequence(Qt::Key_F)); + QSignalSpy spy(&act, SIGNAL(triggered())); + + act.setAutoRepeat(true); + QTest::keyPress(wid, Qt::Key_F); + QTest::keyRelease(wid, Qt::Key_F); + QCOMPARE(spy.count(), 1); + + spy.clear(); + QTest::keyPress(wid, Qt::Key_F); + // repeat event + QTest::simulateEvent(wid, true, Qt::Key_F, Qt::NoModifier, QString("f"), true); + QTest::simulateEvent(wid, true, Qt::Key_F, Qt::NoModifier, QString("f"), true); + QTest::keyRelease(wid, Qt::Key_F); + QCOMPARE(spy.count(), 3); + + spy.clear(); + act.setAutoRepeat(false); + QTest::keyPress(wid, Qt::Key_F); + QTest::simulateEvent(wid, true, Qt::Key_F, Qt::NoModifier, QString("f"), true); + QTest::simulateEvent(wid, true, Qt::Key_F, Qt::NoModifier, QString("f"), true); + QTest::keyRelease(wid, Qt::Key_F); + QCOMPARE(spy.count(), 1); + + spy.clear(); + act.setAutoRepeat(true); + QTest::keyPress(wid, Qt::Key_F); + QTest::simulateEvent(wid, true, Qt::Key_F, Qt::NoModifier, QString("f"), true); + QTest::keyRelease(wid, Qt::Key_F); + QCOMPARE(spy.count(), 2); +} + QTEST_MAIN(tst_QAction) #include "tst_qaction.moc" diff --git a/tests/auto/widgets/kernel/qactiongroup/BLACKLIST b/tests/auto/widgets/kernel/qactiongroup/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..fdc424b6ac1e7cb4e520343c5557fbef383365f6 --- /dev/null +++ b/tests/auto/widgets/kernel/qactiongroup/BLACKLIST @@ -0,0 +1,2 @@ +[QTBUG_14292_filesystem] +linux diff --git a/tests/auto/widgets/kernel/qactiongroup/tst_qactiongroup.cpp b/tests/auto/widgets/kernel/qactiongroup/tst_qactiongroup.cpp index 8ce9941238436d1b0b6fe2c40a1c57032e9112ba..81e5542e914c01196f2f6c366458b6c10d55d0fa 100644 --- a/tests/auto/widgets/kernel/qactiongroup/tst_qactiongroup.cpp +++ b/tests/auto/widgets/kernel/qactiongroup/tst_qactiongroup.cpp @@ -42,6 +42,7 @@ class tst_QActionGroup : public QObject Q_OBJECT private slots: + void cleanup() { QVERIFY(QApplication::topLevelWidgets().isEmpty()); } void enabledPropagation(); void visiblePropagation(); void exclusive(); @@ -223,7 +224,7 @@ void tst_QActionGroup::unCheckCurrentAction() current->setChecked(false); QVERIFY(!action1.isChecked()); QVERIFY(!action2.isChecked()); - QVERIFY(group.checkedAction() == 0); + QVERIFY(!group.checkedAction()); } diff --git a/tests/auto/widgets/kernel/qapplication/BLACKLIST b/tests/auto/widgets/kernel/qapplication/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..6abb1d99881e71d095c859b9beb2ee70a8b154ac --- /dev/null +++ b/tests/auto/widgets/kernel/qapplication/BLACKLIST @@ -0,0 +1,4 @@ +[quitOnLastWindowClosed] +osx-10.10 +[touchEventPropagation] +xcb diff --git a/tests/auto/widgets/kernel/qapplication/qapplication.pro b/tests/auto/widgets/kernel/qapplication/qapplication.pro index 5f369bf61a24ff1a14ca6156285bf5f26663c5a2..5154c915cdd40c307a67b1cb0977d9415eac1918 100644 --- a/tests/auto/widgets/kernel/qapplication/qapplication.pro +++ b/tests/auto/widgets/kernel/qapplication/qapplication.pro @@ -2,6 +2,5 @@ TEMPLATE = subdirs SUBDIRS = desktopsettingsaware modal -win32:!wince*:SUBDIRS += wincmdline test.depends += $$SUBDIRS SUBDIRS += test diff --git a/tests/auto/widgets/kernel/qapplication/test/BLACKLIST b/tests/auto/widgets/kernel/qapplication/test/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..f4a9cb61668128c04fe55ee0cdb26c5ffeb66d89 --- /dev/null +++ b/tests/auto/widgets/kernel/qapplication/test/BLACKLIST @@ -0,0 +1,2 @@ +[quitOnLastWindowClosed] +osx-10.10 diff --git a/tests/auto/widgets/kernel/qapplication/test/test.pro b/tests/auto/widgets/kernel/qapplication/test/test.pro index 7b00ba52935252d22e16317340e17c605ad0808c..b617c228ac2f3f9f425c53b8f3218d3bca662471 100644 --- a/tests/auto/widgets/kernel/qapplication/test/test.pro +++ b/tests/auto/widgets/kernel/qapplication/test/test.pro @@ -10,6 +10,6 @@ TARGET = ../tst_qapplication TESTDATA = ../test/test.pro ../tmp/README SUBPROGRAMS = desktopsettingsaware modal -win32: !wince*: SUBPROGRAMS += wincmdline +win32:!wince: SUBPROGRAMS += wincmdline for(file, SUBPROGRAMS): TEST_HELPER_INSTALLS += "../$${file}/$${file}" diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index c33fd5a9517be7442ae808eacb8502cda61a7c14..878136b4a0de381593aa064e691aea7b1c9af979 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -62,6 +62,7 @@ #endif #include <qpa/qwindowsysteminterface.h> +#include <private/qhighdpiscaling_p.h> #include "../../../qtest-config.h" @@ -162,9 +163,6 @@ private slots: void setAttribute(); - void windowsCommandLine_data(); - void windowsCommandLine(); - void touchEventPropagation(); void qtbug_12673(); @@ -1160,7 +1158,7 @@ void tst_QApplication::sendPostedEvents() QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection); QPointer<SendPostedEventsTester> p = tester; (void) app.exec(); - QVERIFY(p == 0); + QVERIFY(p.isNull()); } void tst_QApplication::thread() @@ -1178,8 +1176,8 @@ void tst_QApplication::thread() // *before* the QApplication has a thread QObject object; QObject child(&object); - QVERIFY(object.thread() == currentThread); - QVERIFY(child.thread() == currentThread); + QCOMPARE(object.thread(), currentThread); + QCOMPARE(child.thread(), currentThread); { int argc = 0; @@ -1209,8 +1207,8 @@ void tst_QApplication::thread() QVERIFY(!currentThread->isFinished()); // should still have a thread - QVERIFY(object.thread() == currentThread); - QVERIFY(child.thread() == currentThread); + QCOMPARE(object.thread(), currentThread); + QCOMPARE(child.thread(), currentThread); // do the test again, making sure that the thread is the same as // before @@ -1231,8 +1229,8 @@ void tst_QApplication::thread() QVERIFY(!currentThread->isFinished()); // should still have a thread - QVERIFY(object.thread() == currentThread); - QVERIFY(child.thread() == currentThread); + QCOMPARE(object.thread(), currentThread); + QCOMPARE(child.thread(), currentThread); QTestEventLoop::instance().enterLoop(1); } @@ -1246,8 +1244,8 @@ void tst_QApplication::thread() QVERIFY(!currentThread->isFinished()); // should still have a thread - QVERIFY(object.thread() == currentThread); - QVERIFY(child.thread() == currentThread); + QCOMPARE(object.thread(), currentThread); + QCOMPARE(child.thread(), currentThread); } class DeleteLaterWidget : public QWidget @@ -1302,7 +1300,7 @@ void DeleteLaterWidget::checkDeleteLater() void tst_QApplication::testDeleteLater() { #ifdef Q_OS_MAC - QSKIP("This test fails and then hangs on Mac OS X, see QTBUG-24318"); + QSKIP("This test fails and then hangs on OS X, see QTBUG-24318"); #endif int argc = 0; QApplication app(argc, 0); @@ -1561,9 +1559,9 @@ void tst_QApplication::focusChanged() QCOMPARE(spy.at(0).count(), 2); old = qvariant_cast<QWidget*>(spy.at(0).at(0)); now = qvariant_cast<QWidget*>(spy.at(0).at(1)); - QVERIFY(now == &le1); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == 0); + QCOMPARE(now, &le1); + QCOMPARE(now, QApplication::focusWidget()); + QVERIFY(!old); spy.clear(); QCOMPARE(spy.count(), 0); @@ -1571,27 +1569,27 @@ void tst_QApplication::focusChanged() QCOMPARE(spy.count(), 1); old = qvariant_cast<QWidget*>(spy.at(0).at(0)); now = qvariant_cast<QWidget*>(spy.at(0).at(1)); - QVERIFY(now == &pb1); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &le1); + QCOMPARE(now, &pb1); + QCOMPARE(now, QApplication::focusWidget()); + QCOMPARE(old, &le1); spy.clear(); lb1.setFocus(); QCOMPARE(spy.count(), 1); old = qvariant_cast<QWidget*>(spy.at(0).at(0)); now = qvariant_cast<QWidget*>(spy.at(0).at(1)); - QVERIFY(now == &lb1); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &pb1); + QCOMPARE(now, &lb1); + QCOMPARE(now, QApplication::focusWidget()); + QCOMPARE(old, &pb1); spy.clear(); lb1.clearFocus(); QCOMPARE(spy.count(), 1); old = qvariant_cast<QWidget*>(spy.at(0).at(0)); now = qvariant_cast<QWidget*>(spy.at(0).at(1)); - QVERIFY(now == 0); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &lb1); + QVERIFY(!now); + QCOMPARE(now, QApplication::focusWidget()); + QCOMPARE(old, &lb1); spy.clear(); QWidget parent2; @@ -1608,9 +1606,9 @@ void tst_QApplication::focusChanged() QVERIFY(spy.count() > 0); // one for deactivation, one for activation on Windows old = qvariant_cast<QWidget*>(spy.at(spy.count()-1).at(0)); now = qvariant_cast<QWidget*>(spy.at(spy.count()-1).at(1)); - QVERIFY(now == &le2); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == 0); + QCOMPARE(now, &le2); + QCOMPARE(now, QApplication::focusWidget()); + QVERIFY(!old); spy.clear(); QTestKeyEvent tab(QTest::Press, Qt::Key_Tab, 0, 0); @@ -1632,82 +1630,82 @@ void tst_QApplication::focusChanged() tab.simulate(now); if (!tabAllControls) { - QVERIFY(spy.count() == 0); - QVERIFY(now == QApplication::focusWidget()); + QCOMPARE(spy.count(), 0); + QCOMPARE(now, QApplication::focusWidget()); } else { QVERIFY(spy.count() > 0); old = qvariant_cast<QWidget*>(spy.at(0).at(0)); now = qvariant_cast<QWidget*>(spy.at(0).at(1)); - QVERIFY(now == &pb2); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &le2); + QCOMPARE(now, &pb2); + QCOMPARE(now, QApplication::focusWidget()); + QCOMPARE(old, &le2); spy.clear(); } if (!tabAllControls) { - QVERIFY(spy.count() == 0); - QVERIFY(now == QApplication::focusWidget()); + QCOMPARE(spy.count(), 0); + QCOMPARE(now, QApplication::focusWidget()); } else { tab.simulate(now); QVERIFY(spy.count() > 0); old = qvariant_cast<QWidget*>(spy.at(0).at(0)); now = qvariant_cast<QWidget*>(spy.at(0).at(1)); - QVERIFY(now == &le2); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &pb2); + QCOMPARE(now, &le2); + QCOMPARE(now, QApplication::focusWidget()); + QCOMPARE(old, &pb2); spy.clear(); } if (!tabAllControls) { - QVERIFY(spy.count() == 0); - QVERIFY(now == QApplication::focusWidget()); + QCOMPARE(spy.count(), 0); + QCOMPARE(now, QApplication::focusWidget()); } else { backtab.simulate(now); QVERIFY(spy.count() > 0); old = qvariant_cast<QWidget*>(spy.at(0).at(0)); now = qvariant_cast<QWidget*>(spy.at(0).at(1)); - QVERIFY(now == &pb2); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &le2); + QCOMPARE(now, &pb2); + QCOMPARE(now, QApplication::focusWidget()); + QCOMPARE(old, &le2); spy.clear(); } if (!tabAllControls) { - QVERIFY(spy.count() == 0); - QVERIFY(now == QApplication::focusWidget()); + QCOMPARE(spy.count(), 0); + QCOMPARE(now, QApplication::focusWidget()); old = &pb2; } else { backtab.simulate(now); QVERIFY(spy.count() > 0); old = qvariant_cast<QWidget*>(spy.at(0).at(0)); now = qvariant_cast<QWidget*>(spy.at(0).at(1)); - QVERIFY(now == &le2); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &pb2); + QCOMPARE(now, &le2); + QCOMPARE(now, QApplication::focusWidget()); + QCOMPARE(old, &pb2); spy.clear(); } click.simulate(old); if (!(pb2.focusPolicy() & Qt::ClickFocus)) { - QVERIFY(spy.count() == 0); - QVERIFY(now == QApplication::focusWidget()); + QCOMPARE(spy.count(), 0); + QCOMPARE(now, QApplication::focusWidget()); } else { QVERIFY(spy.count() > 0); old = qvariant_cast<QWidget*>(spy.at(0).at(0)); now = qvariant_cast<QWidget*>(spy.at(0).at(1)); - QVERIFY(now == &pb2); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &le2); + QCOMPARE(now, &pb2); + QCOMPARE(now, QApplication::focusWidget()); + QCOMPARE(old, &le2); spy.clear(); click.simulate(old); QVERIFY(spy.count() > 0); old = qvariant_cast<QWidget*>(spy.at(0).at(0)); now = qvariant_cast<QWidget*>(spy.at(0).at(1)); - QVERIFY(now == &le2); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &pb2); + QCOMPARE(now, &le2); + QCOMPARE(now, QApplication::focusWidget()); + QCOMPARE(old, &pb2); spy.clear(); } @@ -1722,9 +1720,9 @@ void tst_QApplication::focusChanged() else old = qvariant_cast<QWidget*>(spy.at(spy.count()-2).at(0)); now = qvariant_cast<QWidget*>(spy.at(spy.count()-1).at(1)); - QVERIFY(now == &le1); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &le2); + QCOMPARE(now, &le1); + QCOMPARE(now, QApplication::focusWidget()); + QCOMPARE(old, &le2); spy.clear(); } @@ -1933,39 +1931,6 @@ void tst_QApplication::setAttribute() delete w; } -void tst_QApplication::windowsCommandLine_data() -{ -#if defined(Q_OS_WIN) - QTest::addColumn<QString>("args"); - QTest::addColumn<QString>("expected"); - - QTest::newRow("hello world") - << QString("Hello \"World\"") - << QString("Hello \"World\""); - QTest::newRow("sql") - << QString("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PNR' AND TABLE_TYPE = 'VIEW' ORDER BY TABLE_NAME") - << QString("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PNR' AND TABLE_TYPE = 'VIEW' ORDER BY TABLE_NAME"); -#endif -} - -void tst_QApplication::windowsCommandLine() -{ -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) - QFETCH(QString, args); - QFETCH(QString, expected); - - QProcess testProcess; - const QString path = QStringLiteral("wincmdline/wincmdline"); - testProcess.start(path, QStringList(args)); - QVERIFY2(testProcess.waitForStarted(), - qPrintable(QString::fromLatin1("Cannot start '%1': %2").arg(path, testProcess.errorString()))); - QVERIFY(testProcess.waitForFinished(10000)); - QByteArray error = testProcess.readAllStandardError(); - QString procError(error); - QCOMPARE(procError, expected); -#endif -} - class TouchEventPropagationTestWidget : public QWidget { Q_OBJECT @@ -2038,8 +2003,10 @@ void tst_QApplication::touchEventPropagation() QVERIFY(QTest::qWaitForWindowExposed(&window)); // QPA always takes screen positions and since we map the TouchPoint back to QPA's structure first, // we must ensure there is a screen position in the TouchPoint that maps to a local 0, 0. - pressedTouchPoints[0].setScreenPos(window.mapToGlobal(QPoint(0, 0))); - releasedTouchPoints[0].setScreenPos(window.mapToGlobal(QPoint(0, 0))); + const QPoint deviceGlobalPos = + QHighDpi::toNativePixels(window.mapToGlobal(QPoint(0, 0)), window.windowHandle()->screen()); + pressedTouchPoints[0].setScreenPos(deviceGlobalPos); + releasedTouchPoints[0].setScreenPos(deviceGlobalPos); QWindowSystemInterface::handleTouchEvent(window.windowHandle(), 0, @@ -2088,11 +2055,14 @@ void tst_QApplication::touchEventPropagation() window.resize(200, 200); window.setObjectName("2. window"); TouchEventPropagationTestWidget widget(&window); + widget.resize(200, 200); widget.setObjectName("2. widget"); window.show(); QVERIFY(QTest::qWaitForWindowExposed(&window)); - pressedTouchPoints[0].setScreenPos(window.mapToGlobal(QPoint(0, 0))); - releasedTouchPoints[0].setScreenPos(window.mapToGlobal(QPoint(0, 0))); + const QPoint deviceGlobalPos = + QHighDpi::toNativePixels(window.mapToGlobal(QPoint(50, 50)), window.windowHandle()->screen()); + pressedTouchPoints[0].setScreenPos(deviceGlobalPos); + releasedTouchPoints[0].setScreenPos(deviceGlobalPos); QWindowSystemInterface::handleTouchEvent(window.windowHandle(), 0, @@ -2102,9 +2072,8 @@ void tst_QApplication::touchEventPropagation() 0, device, touchPointList(releasedTouchPoints)); - QCoreApplication::processEvents(); + QTRY_VERIFY(widget.seenMouseEvent); QVERIFY(!widget.seenTouchEvent); - QVERIFY(widget.seenMouseEvent); QVERIFY(!window.seenTouchEvent); QVERIFY(window.seenMouseEvent); diff --git a/tests/auto/widgets/kernel/qapplication/wincmdline/wincmdline.pro b/tests/auto/widgets/kernel/qapplication/wincmdline/wincmdline.pro deleted file mode 100644 index 3e32a6798dd8db7b60782994e59743686e5b2963..0000000000000000000000000000000000000000 --- a/tests/auto/widgets/kernel/qapplication/wincmdline/wincmdline.pro +++ /dev/null @@ -1,5 +0,0 @@ -QT += widgets -CONFIG -= app_bundle debug_and_release_target -SOURCES += main.cpp -DESTDIR = ./ - diff --git a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp index 35a8636f0b3cf21fb9cf242a92347dc807dbb94f..aeaf1e7bf0cb79481db3cebec7feb46ba81f04ff 100644 --- a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp +++ b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp @@ -48,17 +48,8 @@ class tst_QBoxLayout : public QObject { Q_OBJECT -public: - tst_QBoxLayout(); - virtual ~tst_QBoxLayout(); - -public slots: - void initTestCase(); - void cleanupTestCase(); - void init(); - void cleanup(); - private slots: + void cleanup(); void insertSpacerItem(); void insertLayout(); void sizeHint(); @@ -120,34 +111,15 @@ int CustomLayoutStyle::pixelMetric(PixelMetric metric, const QStyleOption * opti return QProxyStyle::pixelMetric(metric, option, widget); } - -tst_QBoxLayout::tst_QBoxLayout() -{ -} - -tst_QBoxLayout::~tst_QBoxLayout() -{ -} - -void tst_QBoxLayout::initTestCase() -{ -} - -void tst_QBoxLayout::cleanupTestCase() -{ -} - -void tst_QBoxLayout::init() -{ -} - void tst_QBoxLayout::cleanup() { + QVERIFY(QApplication::topLevelWidgets().isEmpty()); } void tst_QBoxLayout::insertSpacerItem() { - QWidget *window = new QWidget; + QWidget window; + window.setWindowTitle(QTest::currentTestFunction()); QSpacerItem *spacer1 = new QSpacerItem(20, 10, QSizePolicy::Expanding, QSizePolicy::Expanding); QSpacerItem *spacer2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -157,44 +129,43 @@ void tst_QBoxLayout::insertSpacerItem() layout->addSpacerItem(spacer1); layout->addWidget(new QLineEdit("Baaaaaaaaaaaaaaaaaaaaaaaaar")); layout->insertSpacerItem(0, spacer2); - window->setLayout(layout); + window.setLayout(layout); - QVERIFY(layout->itemAt(0) == spacer2); - QVERIFY(layout->itemAt(2) == spacer1); + QCOMPARE(layout->itemAt(0), spacer2); + QCOMPARE(layout->itemAt(2), spacer1); - window->show(); + window.show(); } void tst_QBoxLayout::insertLayout() { - QWidget *window = new QWidget; - QVBoxLayout *vbox = new QVBoxLayout(window); - QVBoxLayout *dummyParentLayout = new QVBoxLayout; + QWidget window; + QVBoxLayout *vbox = new QVBoxLayout(&window); + QScopedPointer<QVBoxLayout> dummyParentLayout(new QVBoxLayout); QHBoxLayout *subLayout = new QHBoxLayout; dummyParentLayout->addLayout(subLayout); - QCOMPARE(subLayout->parent(), dummyParentLayout); + QCOMPARE(subLayout->parent(), dummyParentLayout.data()); QCOMPARE(dummyParentLayout->count(), 1); // add subLayout to another layout QTest::ignoreMessage(QtWarningMsg, "QLayout::addChildLayout: layout \"\" already has a parent"); vbox->addLayout(subLayout); QCOMPARE((subLayout->parent() == vbox), (vbox->count() == 1)); - - delete dummyParentLayout; - delete window; } void tst_QBoxLayout::sizeHint() { - QWidget *window = new QWidget; + QWidget window; + window.setWindowTitle(QTest::currentTestFunction()); QHBoxLayout *lay1 = new QHBoxLayout; QHBoxLayout *lay2 = new QHBoxLayout; QLabel *label = new QLabel("widget twooooooooooooooooooooooooooooooooooooooooooooooooooooooo"); lay2->addWidget(label); lay1->addLayout(lay2); - window->setLayout(lay1); - window->show(); + window.setLayout(lay1); + window.show(); + QTest::qWaitForWindowExposed(&window); label->setText("foooooooo baaaaaaar"); QSize sh = lay1->sizeHint(); QApplication::processEvents(); @@ -207,24 +178,26 @@ void tst_QBoxLayout::sizeHint() void tst_QBoxLayout::sizeConstraints() { - QWidget *window = new QWidget; + QWidget window; + window.setWindowTitle(QTest::currentTestFunction()); QHBoxLayout *lay = new QHBoxLayout; lay->addWidget(new QLabel("foooooooooooooooooooooooooooooooooooo")); lay->addWidget(new QLabel("baaaaaaaaaaaaaaaaaaaaaaaaaaaaaar")); lay->setSizeConstraint(QLayout::SetFixedSize); - window->setLayout(lay); - window->show(); - QApplication::processEvents(); - QSize sh = window->sizeHint(); + window.setLayout(lay); + window.show(); + QTest::qWaitForWindowExposed(&window); + QSize sh = window.sizeHint(); lay->takeAt(1); - QVERIFY(sh.width() >= window->sizeHint().width() && - sh.height() >= window->sizeHint().height()); + QVERIFY(sh.width() >= window.sizeHint().width() && + sh.height() >= window.sizeHint().height()); } void tst_QBoxLayout::setGeometry() { QWidget toplevel; + toplevel.setWindowTitle(QTest::currentTestFunction()); setFrameless(&toplevel); QWidget w(&toplevel); QVBoxLayout *lay = new QVBoxLayout; @@ -247,33 +220,30 @@ void tst_QBoxLayout::setGeometry() void tst_QBoxLayout::setStyleShouldChangeSpacing() { - QWidget *window = new QWidget; - QHBoxLayout *hbox = new QHBoxLayout(window); + QWidget window; + window.setWindowTitle(QTest::currentTestFunction()); + QHBoxLayout *hbox = new QHBoxLayout(&window); QPushButton *pb1 = new QPushButton(tr("The spacing between this")); QPushButton *pb2 = new QPushButton(tr("and this button should depend on the style of the parent widget"));; pb1->setAttribute(Qt::WA_LayoutUsesWidgetRect); pb2->setAttribute(Qt::WA_LayoutUsesWidgetRect); hbox->addWidget(pb1); hbox->addWidget(pb2); - CustomLayoutStyle *style1 = new CustomLayoutStyle; + QScopedPointer<CustomLayoutStyle> style1(new CustomLayoutStyle); style1->hspacing = 6; - window->setStyle(style1); - window->show(); + window.setStyle(style1.data()); + window.show(); + QTest::qWaitForWindowExposed(&window); - QTest::qWait(100); int spacing = pb2->geometry().left() - pb1->geometry().right() - 1; QCOMPARE(spacing, 6); - CustomLayoutStyle *style2 = new CustomLayoutStyle(); + QScopedPointer<CustomLayoutStyle> style2(new CustomLayoutStyle()); style2->hspacing = 10; - window->setStyle(style2); + window.setStyle(style2.data()); QTest::qWait(100); spacing = pb2->geometry().left() - pb1->geometry().right() - 1; QCOMPARE(spacing, 10); - - delete window; - delete style1; - delete style2; } void tst_QBoxLayout::taskQTBUG_7103_minMaxWidthNotRespected() @@ -287,6 +257,7 @@ void tst_QBoxLayout::taskQTBUG_7103_minMaxWidthNotRespected() layout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding)); QWidget widget; + widget.setWindowTitle(QTest::currentTestFunction()); widget.setLayout(layout); widget.show(); QVERIFY(QTest::qWaitForWindowExposed(&widget)); @@ -325,6 +296,7 @@ void tst_QBoxLayout::taskQTBUG_27420_takeAtShouldUnparentLayout() void tst_QBoxLayout::taskQTBUG_40609_addingWidgetToItsOwnLayout(){ QWidget widget; + widget.setWindowTitle(QTest::currentTestFunction()); widget.setObjectName("347b469225a24a0ef05150a"); QVBoxLayout layout(&widget); layout.setObjectName("ef9e2b42298e0e6420105bb"); @@ -340,6 +312,7 @@ void tst_QBoxLayout::taskQTBUG_40609_addingWidgetToItsOwnLayout(){ void tst_QBoxLayout::taskQTBUG_40609_addingLayoutToItself(){ QWidget widget; + widget.setWindowTitle(QTest::currentTestFunction()); widget.setObjectName("fe44e5cb6c08006597126a"); QVBoxLayout layout(&widget); layout.setObjectName("cc751dd0f50f62b05a62da"); diff --git a/tests/auto/widgets/kernel/qdesktopwidget/tst_qdesktopwidget.cpp b/tests/auto/widgets/kernel/qdesktopwidget/tst_qdesktopwidget.cpp index b717c1deb1cd5cea8dbe5e676bd8634c4a590c65..e94dfa57540a1dab7213df3b319daec99e89eb35 100644 --- a/tests/auto/widgets/kernel/qdesktopwidget/tst_qdesktopwidget.cpp +++ b/tests/auto/widgets/kernel/qdesktopwidget/tst_qdesktopwidget.cpp @@ -73,6 +73,7 @@ void tst_QDesktopWidget::init() void tst_QDesktopWidget::cleanup() { + QVERIFY(QApplication::topLevelWidgets().isEmpty()); } void tst_QDesktopWidget::numScreens() diff --git a/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp b/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp index 8588df7afa86b9d672428e5435a267f3cb73948f..e1b494c9f19be5cdc91df5516cdcd38187ab386b 100644 --- a/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp +++ b/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp @@ -60,17 +60,8 @@ class tst_QFormLayout : public QObject { Q_OBJECT -public: - tst_QFormLayout(); - ~tst_QFormLayout(); - -public slots: - void initTestCase(); - void cleanupTestCase(); - void init(); - void cleanup(); - private slots: + void cleanup(); void rowCount(); void buddies(); void getItemPosition(); @@ -132,34 +123,15 @@ private slots: }; -tst_QFormLayout::tst_QFormLayout() -{ -} - -tst_QFormLayout::~tst_QFormLayout() -{ -} - -void tst_QFormLayout::initTestCase() -{ -} - -void tst_QFormLayout::cleanupTestCase() -{ -} - -void tst_QFormLayout::init() -{ -} - void tst_QFormLayout::cleanup() { + QVERIFY(QApplication::topLevelWidgets().isEmpty()); } void tst_QFormLayout::rowCount() { - QWidget *w = new QWidget; - QFormLayout *fl = new QFormLayout(w); + QWidget w; + QFormLayout *fl = new QFormLayout(&w); fl->addRow(tr("Label 1"), new QLineEdit); fl->addRow(tr("Label 2"), new QLineEdit); @@ -174,14 +146,12 @@ void tst_QFormLayout::rowCount() QCOMPARE(fl->rowCount(), 6); //TODO: remove items - - delete w; } void tst_QFormLayout::buddies() { - QWidget *w = new QWidget; - QFormLayout *fl = new QFormLayout(w); + QWidget w; + QFormLayout *fl = new QFormLayout(&w); //normal buddy case QLineEdit *le = new QLineEdit; @@ -195,23 +165,21 @@ void tst_QFormLayout::buddies() QLineEdit *le2 = new QLineEdit; fl->addRow(0, le2); QWidget *label2 = fl->labelForField(le2); - QVERIFY(label2 == 0); + QVERIFY(!label2); //no label QLineEdit *le3 = new QLineEdit; fl->addRow(le3); QWidget *label3 = fl->labelForField(le3); - QVERIFY(label3 == 0); + QVERIFY(!label3); //TODO: empty label? - - delete w; } void tst_QFormLayout::getItemPosition() { - QWidget *w = new QWidget; - QFormLayout *fl = new QFormLayout(w); + QWidget w; + QFormLayout *fl = new QFormLayout(&w); QList<QLabel*> labels; QList<QLineEdit*> fields; @@ -249,14 +217,12 @@ void tst_QFormLayout::getItemPosition() QCOMPARE(row, 2); QCOMPARE(role, QFormLayout::FieldRole); } - - delete w; } void tst_QFormLayout::wrapping() { - QWidget *w = new QWidget; - QFormLayout *fl = new QFormLayout(w); + QWidget w; + QFormLayout *fl = new QFormLayout(&w); fl->setRowWrapPolicy(QFormLayout::WrapLongRows); QLineEdit *le = new QLineEdit; @@ -264,14 +230,13 @@ void tst_QFormLayout::wrapping() le->setMinimumWidth(200); fl->addRow(lbl, le); - w->setFixedWidth(240); - w->show(); + w.setFixedWidth(240); + w.setWindowTitle(QTest::currentTestFunction()); + w.show(); QCOMPARE(le->geometry().y() > lbl->geometry().y(), true); //TODO: additional tests covering different wrapping cases - - delete w; } class CustomLayoutStyle : public QProxyStyle @@ -309,12 +274,12 @@ int CustomLayoutStyle::pixelMetric(PixelMetric metric, const QStyleOption * opti void tst_QFormLayout::spacing() { //TODO: confirm spacing behavior - QWidget *w = new QWidget; - CustomLayoutStyle *style = new CustomLayoutStyle; + QWidget w; + QScopedPointer<CustomLayoutStyle> style(new CustomLayoutStyle); style->hspacing = 5; style->vspacing = 10; - w->setStyle(style); - QFormLayout *fl = new QFormLayout(w); + w.setStyle(style.data()); + QFormLayout *fl = new QFormLayout(&w); QCOMPARE(style->hspacing, fl->horizontalSpacing()); QCOMPARE(style->vspacing, fl->verticalSpacing()); @@ -351,12 +316,10 @@ void tst_QFormLayout::spacing() QCheckBox *checkBox = new QCheckBox(tr("Yes")); fl->setWidget(0, QFormLayout::LabelRole, label); fl->setWidget(1, QFormLayout::FieldRole, checkBox); - w->resize(200, 100); - w->show(); - QVERIFY(QTest::qWaitForWindowExposed(w)); - - delete w; - delete style; + w.resize(200, 100); + w.setWindowTitle(QTest::currentTestFunction()); + w.show(); + QVERIFY(QTest::qWaitForWindowExposed(&w)); } void tst_QFormLayout::contentsRect() @@ -366,6 +329,7 @@ void tst_QFormLayout::contentsRect() QFormLayout form; w.setLayout(&form); form.addRow("Label", new QPushButton(&w)); + w.setWindowTitle(QTest::currentTestFunction()); w.show(); QVERIFY(QTest::qWaitForWindowExposed(&w)); int l, t, r, b; @@ -425,18 +389,18 @@ void tst_QFormLayout::setFormStyle() #if 0 // QT_NO_STYLE_PLASTIQUE widget.setStyle(new QPlastiqueStyle()); - QVERIFY(layout.labelAlignment() == Qt::AlignRight); + QCOMPARE(layout.labelAlignment(), Qt::AlignRight); QVERIFY(layout.formAlignment() == (Qt::AlignLeft | Qt::AlignTop)); - QVERIFY(layout.fieldGrowthPolicy() == QFormLayout::ExpandingFieldsGrow); - QVERIFY(layout.rowWrapPolicy() == QFormLayout::DontWrapRows); + QCOMPARE(layout.fieldGrowthPolicy(), QFormLayout::ExpandingFieldsGrow); + QCOMPARE(layout.rowWrapPolicy(), QFormLayout::DontWrapRows); #endif widget.setStyle(QStyleFactory::create("windows")); - QVERIFY(layout.labelAlignment() == Qt::AlignLeft); + QCOMPARE(layout.labelAlignment(), Qt::AlignLeft); QVERIFY(layout.formAlignment() == (Qt::AlignLeft | Qt::AlignTop)); - QVERIFY(layout.fieldGrowthPolicy() == QFormLayout::AllNonFixedFieldsGrow); - QVERIFY(layout.rowWrapPolicy() == QFormLayout::DontWrapRows); + QCOMPARE(layout.fieldGrowthPolicy(), QFormLayout::AllNonFixedFieldsGrow); + QCOMPARE(layout.rowWrapPolicy(), QFormLayout::DontWrapRows); /* can't directly create mac style or qtopia style, since this test is cross platform.. so create dummy styles that @@ -444,17 +408,17 @@ void tst_QFormLayout::setFormStyle() */ widget.setStyle(new DummyMacStyle()); - QVERIFY(layout.labelAlignment() == Qt::AlignRight); + QCOMPARE(layout.labelAlignment(), Qt::AlignRight); QVERIFY(layout.formAlignment() == (Qt::AlignHCenter | Qt::AlignTop)); - QVERIFY(layout.fieldGrowthPolicy() == QFormLayout::FieldsStayAtSizeHint); - QVERIFY(layout.rowWrapPolicy() == QFormLayout::DontWrapRows); + QCOMPARE(layout.fieldGrowthPolicy(), QFormLayout::FieldsStayAtSizeHint); + QCOMPARE(layout.rowWrapPolicy(), QFormLayout::DontWrapRows); widget.setStyle(new DummyQtopiaStyle()); - QVERIFY(layout.labelAlignment() == Qt::AlignRight); + QCOMPARE(layout.labelAlignment(), Qt::AlignRight); QVERIFY(layout.formAlignment() == (Qt::AlignLeft | Qt::AlignTop)); - QVERIFY(layout.fieldGrowthPolicy() == QFormLayout::AllNonFixedFieldsGrow); - QVERIFY(layout.rowWrapPolicy() == QFormLayout::WrapLongRows); + QCOMPARE(layout.fieldGrowthPolicy(), QFormLayout::AllNonFixedFieldsGrow); + QCOMPARE(layout.rowWrapPolicy(), QFormLayout::WrapLongRows); } void tst_QFormLayout::setFieldGrowthPolicy() @@ -479,14 +443,14 @@ void tst_QFormLayout::setFieldGrowthPolicy() layout.activate(); if (i == 0) { - QVERIFY(fld1.width() == fld2.width()); - QVERIFY(fld2.width() == fld3.width()); + QCOMPARE(fld1.width(), fld2.width()); + QCOMPARE(fld2.width(), fld3.width()); } else if (i == 1) { - QVERIFY(fld1.width() == fld2.width()); + QCOMPARE(fld1.width(), fld2.width()); QVERIFY(fld2.width() < fld3.width()); } else { QVERIFY(fld1.width() < fld2.width()); - QVERIFY(fld2.width() == fld3.width()); + QCOMPARE(fld2.width(), fld3.width()); } } } @@ -505,33 +469,39 @@ void tst_QFormLayout::setFormAlignment() void tst_QFormLayout::addRow() { - QFormLayout layout; - QWidget w1, w2, w3; - QHBoxLayout l1, l2, l3; - QLabel lbl1, lbl2; - - QCOMPARE(layout.rowCount(), 0); - - layout.addRow(&lbl1, &w1); - layout.addRow(&lbl2, &l1); - layout.addRow("Foo:", &w2); - layout.addRow("Bar:", &l2); - layout.addRow(&w3); - layout.addRow(&l3); - - QCOMPARE(layout.rowCount(), 6); - - QVERIFY(layout.itemAt(0, QFormLayout::LabelRole)->widget() == &lbl1); - QVERIFY(layout.itemAt(1, QFormLayout::LabelRole)->widget() == &lbl2); - QVERIFY(layout.itemAt(2, QFormLayout::LabelRole)->widget()->property("text") == "Foo:"); - QVERIFY(layout.itemAt(3, QFormLayout::LabelRole)->widget()->property("text") == "Bar:"); - QVERIFY(layout.itemAt(4, QFormLayout::LabelRole) == 0); - QVERIFY(layout.itemAt(5, QFormLayout::LabelRole) == 0); - - QVERIFY(layout.itemAt(0, QFormLayout::FieldRole)->widget() == &w1); - QVERIFY(layout.itemAt(1, QFormLayout::FieldRole)->layout() == &l1); - QVERIFY(layout.itemAt(2, QFormLayout::FieldRole)->widget() == &w2); - QVERIFY(layout.itemAt(3, QFormLayout::FieldRole)->layout() == &l2); + QWidget topLevel; + QFormLayout *layout = new QFormLayout(&topLevel); + QWidget *w1 = new QWidget(&topLevel); + QWidget *w2 = new QWidget(&topLevel); + QWidget *w3 = new QWidget(&topLevel); + QHBoxLayout *l1 = new QHBoxLayout; + QHBoxLayout *l2 = new QHBoxLayout; + QHBoxLayout *l3 = new QHBoxLayout; + QLabel *lbl1 = new QLabel(&topLevel); + QLabel *lbl2 = new QLabel(&topLevel); + + QCOMPARE(layout->rowCount(), 0); + + layout->addRow(lbl1, w1); + layout->addRow(lbl2, l1); + layout->addRow("Foo:", w2); + layout->addRow("Bar:", l2); + layout->addRow(w3); + layout->addRow(l3); + + QCOMPARE(layout->rowCount(), 6); + + QVERIFY(layout->itemAt(0, QFormLayout::LabelRole)->widget() == lbl1); + QVERIFY(layout->itemAt(1, QFormLayout::LabelRole)->widget() == lbl2); + QVERIFY(layout->itemAt(2, QFormLayout::LabelRole)->widget()->property("text") == "Foo:"); + QVERIFY(layout->itemAt(3, QFormLayout::LabelRole)->widget()->property("text") == "Bar:"); + QVERIFY(layout->itemAt(4, QFormLayout::LabelRole) == 0); + QVERIFY(layout->itemAt(5, QFormLayout::LabelRole) == 0); + + QVERIFY(layout->itemAt(0, QFormLayout::FieldRole)->widget() == w1); + QVERIFY(layout->itemAt(1, QFormLayout::FieldRole)->layout() == l1); + QVERIFY(layout->itemAt(2, QFormLayout::FieldRole)->widget() == w2); + QVERIFY(layout->itemAt(3, QFormLayout::FieldRole)->layout() == l2); // ### should have a third role, FullRowRole? // QVERIFY(layout.itemAt(4, QFormLayout::FieldRole) == 0); // QVERIFY(layout.itemAt(5, QFormLayout::FieldRole) == 0); @@ -539,17 +509,24 @@ void tst_QFormLayout::addRow() void tst_QFormLayout::insertRow_QWidget_QWidget() { - QFormLayout layout; - QLabel lbl1, lbl2, lbl3, lbl4; - QLineEdit fld1, fld2, fld3, fld4; + QWidget topLevel; + QFormLayout *layout = new QFormLayout(&topLevel); + QLabel *lbl1 = new QLabel(&topLevel); + QLabel *lbl2 = new QLabel(&topLevel); + QLabel *lbl3 = new QLabel(&topLevel); + QLabel *lbl4 = new QLabel(&topLevel); + QLineEdit *fld1 = new QLineEdit(&topLevel); + QLineEdit *fld2 = new QLineEdit(&topLevel); + QLineEdit *fld3 = new QLineEdit(&topLevel); + QLineEdit *fld4 = new QLineEdit(&topLevel); - layout.insertRow(0, &lbl1, &fld1); - QCOMPARE(layout.rowCount(), 1); + layout->insertRow(0, lbl1, fld1); + QCOMPARE(layout->rowCount(), 1); { int row = -1; QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); - layout.getWidgetPosition(&lbl1, &row, &role); + layout->getWidgetPosition(lbl1, &row, &role); QCOMPARE(row, 0); QCOMPARE(int(role), int(QFormLayout::LabelRole)); } @@ -557,63 +534,68 @@ void tst_QFormLayout::insertRow_QWidget_QWidget() { int row = -1; QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); - layout.getWidgetPosition(&fld1, &row, &role); + layout->getWidgetPosition(fld1, &row, &role); QCOMPARE(row, 0); QCOMPARE(int(role), int(QFormLayout::FieldRole)); } // check that negative values append - layout.insertRow(-2, &lbl2, &fld2); - QCOMPARE(layout.rowCount(), 2); + layout->insertRow(-2, lbl2, fld2); + QCOMPARE(layout->rowCount(), 2); - QVERIFY(layout.itemAt(0, QFormLayout::LabelRole)->widget() == &lbl1); - QVERIFY(layout.itemAt(1, QFormLayout::LabelRole)->widget() == &lbl2); + QVERIFY(layout->itemAt(0, QFormLayout::LabelRole)->widget() == lbl1); + QVERIFY(layout->itemAt(1, QFormLayout::LabelRole)->widget() == lbl2); // check that too large values append - layout.insertRow(100, &lbl3, &fld3); - QCOMPARE(layout.rowCount(), 3); - QCOMPARE(layout.count(), 6); + layout->insertRow(100, lbl3, fld3); + QCOMPARE(layout->rowCount(), 3); + QCOMPARE(layout->count(), 6); - layout.insertRow(3, (QWidget *)0, (QWidget *)0); - QCOMPARE(layout.rowCount(), 4); - QCOMPARE(layout.count(), 6); + layout->insertRow(3, (QWidget *)0, (QWidget *)0); + QCOMPARE(layout->rowCount(), 4); + QCOMPARE(layout->count(), 6); - layout.insertRow(4, (QWidget *)0, &fld4); - QCOMPARE(layout.rowCount(), 5); - QCOMPARE(layout.count(), 7); + layout->insertRow(4, (QWidget *)0, fld4); + QCOMPARE(layout->rowCount(), 5); + QCOMPARE(layout->count(), 7); - layout.insertRow(5, &lbl4, (QWidget *)0); - QCOMPARE(layout.rowCount(), 6); - QCOMPARE(layout.count(), 8); - - QVERIFY(layout.itemAt(0, QFormLayout::LabelRole)->widget() == &lbl1); - QVERIFY(layout.itemAt(1, QFormLayout::LabelRole)->widget() == &lbl2); - QVERIFY(layout.itemAt(2, QFormLayout::LabelRole)->widget() == &lbl3); - QVERIFY(layout.itemAt(3, QFormLayout::LabelRole) == 0); - QVERIFY(layout.itemAt(4, QFormLayout::LabelRole) == 0); - QVERIFY(layout.itemAt(5, QFormLayout::LabelRole)->widget() == &lbl4); - - QVERIFY(layout.itemAt(0, QFormLayout::FieldRole)->widget() == &fld1); - QVERIFY(layout.itemAt(1, QFormLayout::FieldRole)->widget() == &fld2); - QVERIFY(layout.itemAt(2, QFormLayout::FieldRole)->widget() == &fld3); - QVERIFY(layout.itemAt(3, QFormLayout::FieldRole) == 0); - QVERIFY(layout.itemAt(4, QFormLayout::FieldRole)->widget() == &fld4); - QVERIFY(layout.itemAt(5, QFormLayout::FieldRole) == 0); + layout->insertRow(5, lbl4, (QWidget *)0); + QCOMPARE(layout->rowCount(), 6); + QCOMPARE(layout->count(), 8); + + QVERIFY(layout->itemAt(0, QFormLayout::LabelRole)->widget() == lbl1); + QVERIFY(layout->itemAt(1, QFormLayout::LabelRole)->widget() == lbl2); + QVERIFY(layout->itemAt(2, QFormLayout::LabelRole)->widget() == lbl3); + QVERIFY(layout->itemAt(3, QFormLayout::LabelRole) == 0); + QVERIFY(layout->itemAt(4, QFormLayout::LabelRole) == 0); + QVERIFY(layout->itemAt(5, QFormLayout::LabelRole)->widget() == lbl4); + + QVERIFY(layout->itemAt(0, QFormLayout::FieldRole)->widget() == fld1); + QVERIFY(layout->itemAt(1, QFormLayout::FieldRole)->widget() == fld2); + QVERIFY(layout->itemAt(2, QFormLayout::FieldRole)->widget() == fld3); + QVERIFY(layout->itemAt(3, QFormLayout::FieldRole) == 0); + QVERIFY(layout->itemAt(4, QFormLayout::FieldRole)->widget() == fld4); + QVERIFY(layout->itemAt(5, QFormLayout::FieldRole) == 0); } void tst_QFormLayout::insertRow_QWidget_QLayout() { - QFormLayout layout; - QLabel lbl1, lbl2, lbl3, lbl4; - QHBoxLayout fld1, fld2, fld3, fld4; + QWidget topLevel; + QFormLayout *layout = new QFormLayout(&topLevel); + QLabel *lbl1 = new QLabel(&topLevel); + QLabel *lbl2 = new QLabel(&topLevel); + QLabel *lbl3 = new QLabel(&topLevel); + QHBoxLayout *fld1 = new QHBoxLayout; + QHBoxLayout *fld2 = new QHBoxLayout; + QHBoxLayout *fld3 = new QHBoxLayout; - layout.insertRow(0, &lbl1, &fld1); - QCOMPARE(layout.rowCount(), 1); + layout->insertRow(0, lbl1, fld1); + QCOMPARE(layout->rowCount(), 1); { int row = -1; QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); - layout.getWidgetPosition(&lbl1, &row, &role); + layout->getWidgetPosition(lbl1, &row, &role); QCOMPARE(row, 0); QCOMPARE(int(role), int(QFormLayout::LabelRole)); } @@ -621,77 +603,83 @@ void tst_QFormLayout::insertRow_QWidget_QLayout() { int row = -1; QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); - layout.getLayoutPosition(&fld1, &row, &role); + layout->getLayoutPosition(fld1, &row, &role); QCOMPARE(row, 0); QCOMPARE(int(role), int(QFormLayout::FieldRole)); } // check that negative values append - layout.insertRow(-2, &lbl2, &fld2); - QCOMPARE(layout.rowCount(), 2); + layout->insertRow(-2, lbl2, fld2); + QCOMPARE(layout->rowCount(), 2); - QVERIFY(layout.itemAt(0, QFormLayout::LabelRole)->widget() == &lbl1); - QVERIFY(layout.itemAt(1, QFormLayout::LabelRole)->widget() == &lbl2); + QVERIFY(layout->itemAt(0, QFormLayout::LabelRole)->widget() == lbl1); + QVERIFY(layout->itemAt(1, QFormLayout::LabelRole)->widget() == lbl2); // check that too large values append - layout.insertRow(100, &lbl3, &fld3); - QCOMPARE(layout.rowCount(), 3); + layout->insertRow(100, lbl3, fld3); + QCOMPARE(layout->rowCount(), 3); - QVERIFY(layout.itemAt(0, QFormLayout::LabelRole)->widget() == &lbl1); - QVERIFY(layout.itemAt(1, QFormLayout::LabelRole)->widget() == &lbl2); - QVERIFY(layout.itemAt(2, QFormLayout::LabelRole)->widget() == &lbl3); + QVERIFY(layout->itemAt(0, QFormLayout::LabelRole)->widget() == lbl1); + QVERIFY(layout->itemAt(1, QFormLayout::LabelRole)->widget() == lbl2); + QVERIFY(layout->itemAt(2, QFormLayout::LabelRole)->widget() == lbl3); - QVERIFY(layout.itemAt(0, QFormLayout::FieldRole)->layout() == &fld1); - QVERIFY(layout.itemAt(1, QFormLayout::FieldRole)->layout() == &fld2); - QVERIFY(layout.itemAt(2, QFormLayout::FieldRole)->layout() == &fld3); + QVERIFY(layout->itemAt(0, QFormLayout::FieldRole)->layout() == fld1); + QVERIFY(layout->itemAt(1, QFormLayout::FieldRole)->layout() == fld2); + QVERIFY(layout->itemAt(2, QFormLayout::FieldRole)->layout() == fld3); } void tst_QFormLayout::insertRow_QString_QWidget() { - QFormLayout layout; - QLineEdit fld1, fld2, fld3; + QWidget topLevel; + QFormLayout *layout = new QFormLayout(&topLevel); + QLineEdit *fld1 = new QLineEdit(&topLevel); + QLineEdit *fld2 = new QLineEdit(&topLevel); + QLineEdit *fld3 = new QLineEdit(&topLevel); - layout.insertRow(-5, "&Name:", &fld1); - QLabel *label1 = qobject_cast<QLabel *>(layout.itemAt(0, QFormLayout::LabelRole)->widget()); + layout->insertRow(-5, "&Name:", fld1); + QLabel *label1 = qobject_cast<QLabel *>(layout->itemAt(0, QFormLayout::LabelRole)->widget()); QVERIFY(label1 != 0); - QVERIFY(label1->buddy() == &fld1); + QCOMPARE(label1->buddy(), fld1); - layout.insertRow(0, "&Email:", &fld2); - QLabel *label2 = qobject_cast<QLabel *>(layout.itemAt(0, QFormLayout::LabelRole)->widget()); + layout->insertRow(0, "&Email:", fld2); + QLabel *label2 = qobject_cast<QLabel *>(layout->itemAt(0, QFormLayout::LabelRole)->widget()); QVERIFY(label2 != 0); - QVERIFY(label2->buddy() == &fld2); + QCOMPARE(label2->buddy(), fld2); - layout.insertRow(5, "&Age:", &fld3); - QLabel *label3 = qobject_cast<QLabel *>(layout.itemAt(2, QFormLayout::LabelRole)->widget()); + layout->insertRow(5, "&Age:", fld3); + QLabel *label3 = qobject_cast<QLabel *>(layout->itemAt(2, QFormLayout::LabelRole)->widget()); QVERIFY(label3 != 0); - QVERIFY(label3->buddy() == &fld3); + QCOMPARE(label3->buddy(), fld3); } void tst_QFormLayout::insertRow_QString_QLayout() { - QFormLayout layout; - QHBoxLayout fld1, fld2, fld3; + QWidget topLevel; + QFormLayout *layout = new QFormLayout(&topLevel); + QHBoxLayout *fld1 = new QHBoxLayout; + QHBoxLayout *fld2 = new QHBoxLayout; + QHBoxLayout *fld3 = new QHBoxLayout; - layout.insertRow(-5, "&Name:", &fld1); - QLabel *label1 = qobject_cast<QLabel *>(layout.itemAt(0, QFormLayout::LabelRole)->widget()); + layout->insertRow(-5, "&Name:", fld1); + QLabel *label1 = qobject_cast<QLabel *>(layout->itemAt(0, QFormLayout::LabelRole)->widget()); QVERIFY(label1 != 0); - QVERIFY(label1->buddy() == 0); + QVERIFY(!label1->buddy()); - QCOMPARE(layout.rowCount(), 1); + QCOMPARE(layout->rowCount(), 1); - layout.insertRow(0, "&Email:", &fld2); - QLabel *label2 = qobject_cast<QLabel *>(layout.itemAt(0, QFormLayout::LabelRole)->widget()); + layout->insertRow(0, "&Email:", fld2); + QLabel *label2 = qobject_cast<QLabel *>(layout->itemAt(0, QFormLayout::LabelRole)->widget()); QVERIFY(label2 != 0); - QVERIFY(label2->buddy() == 0); + QVERIFY(!label2->buddy()); - QCOMPARE(layout.rowCount(), 2); + QCOMPARE(layout->rowCount(), 2); - layout.insertRow(5, "&Age:", &fld3); - QLabel *label3 = qobject_cast<QLabel *>(layout.itemAt(2, QFormLayout::LabelRole)->widget()); + layout->insertRow(5, "&Age:", fld3); + QLabel *label3 = qobject_cast<QLabel *>(layout->itemAt(2, QFormLayout::LabelRole)->widget()); QVERIFY(label3 != 0); - QVERIFY(label3->buddy() == 0); + QVERIFY(!label3->buddy()); - QCOMPARE(layout.rowCount(), 3); + QCOMPARE(layout->rowCount(), 3); } void tst_QFormLayout::insertRow_QWidget() @@ -840,39 +828,40 @@ void tst_QFormLayout::setLayout() void tst_QFormLayout::itemAt() { - QFormLayout layout; + QWidget topLevel; + QFormLayout *layout = new QFormLayout(&topLevel); - QWidget w1; - QWidget w2; - QWidget w3; - QWidget w4; - QWidget w5; - QHBoxLayout l6; + QWidget *w1 = new QWidget(&topLevel); + QWidget *w2 = new QWidget(&topLevel); + QWidget *w3 = new QWidget(&topLevel); + QWidget *w4 = new QWidget(&topLevel); + QWidget *w5 = new QWidget(&topLevel); + QHBoxLayout *l6 = new QHBoxLayout; - layout.setWidget(5, QFormLayout::LabelRole, &w1); - layout.setWidget(3, QFormLayout::FieldRole, &w2); - layout.setWidget(3, QFormLayout::LabelRole, &w3); - layout.addRow(&w4, &w5); - layout.addRow("Foo:", &l6); + layout->setWidget(5, QFormLayout::LabelRole, w1); + layout->setWidget(3, QFormLayout::FieldRole, w2); + layout->setWidget(3, QFormLayout::LabelRole, w3); + layout->addRow(w4, w5); + layout->addRow("Foo:", l6); - QCOMPARE(layout.count(), 7); + QCOMPARE(layout->count(), 7); QBitArray scoreBoard(7); for (int i = 0; i < 7; ++i) { - QLayoutItem *item = layout.itemAt(i); + QLayoutItem *item = layout->itemAt(i); QVERIFY(item != 0); - if (item->widget() == &w1) { + if (item->widget() == w1) { scoreBoard[0] = true; - } else if (item->widget() == &w2) { + } else if (item->widget() == w2) { scoreBoard[1] = true; - } else if (item->widget() == &w3) { + } else if (item->widget() == w3) { scoreBoard[2] = true; - } else if (item->widget() == &w4) { + } else if (item->widget() == w4) { scoreBoard[3] = true; - } else if (item->widget() == &w5) { + } else if (item->widget() == w5) { scoreBoard[4] = true; - } else if (item->layout() == &l6) { + } else if (item->layout() == l6) { scoreBoard[5] = true; } else if (qobject_cast<QLabel *>(item->widget())) { scoreBoard[6] = true; @@ -883,26 +872,27 @@ void tst_QFormLayout::itemAt() void tst_QFormLayout::takeAt() { - QFormLayout layout; + QWidget topLevel; + QFormLayout *layout = new QFormLayout(&topLevel); - QWidget w1; - QWidget w2; - QWidget w3; - QWidget w4; - QWidget w5; - QHBoxLayout l6; + QWidget *w1 = new QWidget(&topLevel); + QWidget *w2 = new QWidget(&topLevel); + QWidget *w3 = new QWidget(&topLevel); + QWidget *w4 = new QWidget(&topLevel); + QWidget *w5 = new QWidget(&topLevel); + QHBoxLayout *l6 = new QHBoxLayout; - layout.setWidget(5, QFormLayout::LabelRole, &w1); - layout.setWidget(3, QFormLayout::FieldRole, &w2); - layout.setWidget(3, QFormLayout::LabelRole, &w3); - layout.addRow(&w4, &w5); - layout.addRow("Foo:", &l6); + layout->setWidget(5, QFormLayout::LabelRole, w1); + layout->setWidget(3, QFormLayout::FieldRole, w2); + layout->setWidget(3, QFormLayout::LabelRole, w3); + layout->addRow(w4, w5); + layout->addRow("Foo:", l6); - QCOMPARE(layout.count(), 7); + QCOMPARE(layout->count(), 7); for (int i = 6; i >= 0; --i) { - layout.takeAt(0); - QCOMPARE(layout.count(), i); + layout->takeAt(0); + QCOMPARE(layout->count(), i); } } @@ -917,6 +907,7 @@ void tst_QFormLayout::layoutAlone() QHBoxLayout hlay; layout.setLayout(1, QFormLayout::LabelRole, &hlay); QCOMPARE(layout.count(), 2); + w.setWindowTitle(QTest::currentTestFunction()); w.show(); layout.activate(); QTest::qWait(500); diff --git a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp index 7f3c289fb4793993e983ac731aeab44e55baecb8..1e67c675eff5824af7e753b171a81b2c7ad5561c 100644 --- a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp +++ b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp @@ -60,18 +60,9 @@ class tst_QGridLayout : public QObject { Q_OBJECT -public: - tst_QGridLayout(); - virtual ~tst_QGridLayout(); - - -public slots: +private slots: void initTestCase(); - void cleanupTestCase(); - void init(); void cleanup(); - -private slots: void getItemPosition(); void itemAtPosition(); void badDistributionBug(); @@ -97,76 +88,72 @@ private slots: void taskQTBUG_40609_addingLayoutToItself(); void replaceWidget(); void dontCrashWhenExtendsToEnd(); - -private: - QWidget *testWidget; - QGridLayout *testLayout; - QWidget *w1; - QWidget *w2; - QWidget *w3; - QSpacerItem *sp; - - QGridLayout *m_grid; - QWidget *m_toplevel; }; - -tst_QGridLayout::tst_QGridLayout() +void tst_QGridLayout::initTestCase() { - m_grid = 0; - m_toplevel = 0; +#ifdef Q_OS_WINCE //disable magic for WindowsCE + qApp->setAutoMaximizeThreshold(-1); +#endif } -tst_QGridLayout::~tst_QGridLayout() +static inline int visibleTopLevelWidgetCount() { - delete m_toplevel; + int result= 0; + foreach (const QWidget *topLevel, QApplication::topLevelWidgets()) { + if (topLevel->isVisible()) + ++result; + } + return result; } -void tst_QGridLayout::initTestCase() +void tst_QGridLayout::cleanup() { -#ifdef Q_OS_WINCE //disable magic for WindowsCE - qApp->setAutoMaximizeThreshold(-1); -#endif - // Create the test class - testWidget = new QWidget(0); + // Verify that no visible top levels are leaked. Cannot check for + // topLevelWidgets().isEmpty() here since the data driven test layoutSpacing() + // will appear to "leak" top levels due to it creating widgets in the test data. + QCOMPARE(visibleTopLevelWidgetCount(), 0); +} - testLayout = new QGridLayout(testWidget); +class ItemTestWidget : public QWidget { +public: + ItemTestWidget(); + + QGridLayout *testLayout; + QWidget *w1; + QWidget *w2; + QWidget *w3; + QSpacerItem *sp; +}; + +ItemTestWidget::ItemTestWidget() + : testLayout(new QGridLayout(this)) + , w1(new QWidget(this)) + , w2(new QWidget(this)) + , w3(new QWidget(this)) + , sp(new QSpacerItem(4, 4)) +{ + setObjectName("testWidget"); + setWindowTitle(QTest::currentTestFunction()); - w1 = new QWidget(testWidget); w1->setPalette(QPalette(Qt::red)); testLayout->addWidget(w1, 0, 0); - w2 = new QWidget(testWidget); testLayout->addWidget(w2, 1, 1, 2, 2); w2->setPalette(QPalette(Qt::green)); - w3 = new QWidget(testWidget); testLayout->addWidget(w3, 0, 1, 1, 2); w3->setPalette(QPalette(Qt::blue)); - sp = new QSpacerItem(4, 4); testLayout->addItem(sp, 1, 3, 2, 1); - - testWidget->resize( 200, 200 ); - testWidget->show(); -} - -void tst_QGridLayout::cleanupTestCase() -{ - delete testWidget; - testWidget = 0; -} - -void tst_QGridLayout::init() -{ -} - -void tst_QGridLayout::cleanup() -{ } void tst_QGridLayout::getItemPosition() { + ItemTestWidget testWidget; + testWidget.resize(200, 200); + testWidget.show(); + QLayoutItem *item; int counter = 0; @@ -175,28 +162,28 @@ void tst_QGridLayout::getItemPosition() bool seenW3 = false; bool seenSpacer = false; - while ((item = testLayout->itemAt(counter))) { + while ((item = testWidget.testLayout->itemAt(counter))) { QWidget *w = item->widget(); int r,c,rs,cs; - testLayout->getItemPosition(counter, &r, &c, &rs, &cs); + testWidget.testLayout->getItemPosition(counter, &r, &c, &rs, &cs); // qDebug() << "item" << counter << "has" <<r << c << rs << cs; - if (w == w1) { + if (w == testWidget.w1) { QVERIFY(!seenW1); seenW1 = true; QCOMPARE(r, 0); QCOMPARE(c, 0); QCOMPARE(rs, 1); QCOMPARE(cs, 1); - } else if (w == w2) { + } else if (w == testWidget.w2) { QVERIFY(!seenW2); seenW2 = true; QCOMPARE(r, 1); QCOMPARE(c, 1); QCOMPARE(rs, 2); QCOMPARE(cs, 2); - } else if (w == w3) { + } else if (w == testWidget.w3) { QVERIFY(!seenW3); seenW3 = true; QCOMPARE(r, 0); @@ -223,16 +210,20 @@ void tst_QGridLayout::getItemPosition() void tst_QGridLayout::itemAtPosition() { + ItemTestWidget testWidget; + testWidget.resize(200, 200); + testWidget.show(); + void *table[4][5] = { - { w1, w3, w3, 0, 0 }, - { 0, w2, w2, sp, 0 }, - { 0, w2, w2, sp, 0 }, + { testWidget.w1, testWidget.w3,testWidget.w3, 0, 0 }, + { 0, testWidget.w2, testWidget.w2, testWidget.sp, 0 }, + { 0, testWidget.w2, testWidget.w2, testWidget.sp, 0 }, { 0, 0, 0, 0, 0 } }; for (int row = 0; row < 4; ++row) { for (int col = 0; col < 5; ++col) { - QLayoutItem *item = testLayout->itemAtPosition(row, col); + QLayoutItem *item = testWidget.testLayout->itemAtPosition(row, col); QVERIFY(item == table[row][col] || (item && item->widget() == table[row][col])); } @@ -860,32 +851,31 @@ void tst_QGridLayout::minMaxSize() } } QApplication::setStyle(style); - if (!m_grid) - m_grid = new QGridLayout(); - if (!m_toplevel) { - m_toplevel = new QWidget(); - setFrameless(m_toplevel); - } + QWidget toplevel; + toplevel.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + + QLatin1Char(' ') + QLatin1String(QTest::currentDataTag())); + setFrameless(&toplevel); + QGridLayout *grid = new QGridLayout; if (fixedSize.isValid()) { - m_toplevel->setFixedSize(fixedSize); + toplevel.setFixedSize(fixedSize); } else { - m_toplevel->setMinimumSize(QSize(0,0)); - m_toplevel->setMaximumSize(QSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX)); + toplevel.setMinimumSize(QSize(0,0)); + toplevel.setMaximumSize(QSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX)); } // Do a two-pass one using the real testdata, the other pass enables heightForWidth // on the widget, but the heightForWidth() function just return sizeHint().width() for (int pass = 0; pass < 2; ++pass) { - m_toplevel->hide(); + toplevel.hide(); QApplication::processEvents(); QTest::qWait(20); // Test if removeItem uninitializes data properly - while (m_grid->count()) { - QLayoutItem *item = m_grid->itemAt(0); - m_grid->removeItem(item); + while (grid->count()) { + QLayoutItem *item = grid->itemAt(0); + grid->removeItem(item); delete item->widget(); delete item; } - m_toplevel->setLayout(m_grid); + toplevel.setLayout(grid); // a layout with a top-level parent widget QList<QPointer<SizeHinterFrame> > sizehinters; @@ -899,29 +889,29 @@ void tst_QGridLayout::minMaxSize() QSizePolicy sp = sh->sizePolicy(); sp.setHorizontalPolicy((QSizePolicy::Policy)sizePolicy); sh->setSizePolicy(sp); - sh->setParent(m_toplevel); + sh->setParent(&toplevel); if (si.minSize.isValid()) sh->setMinimumSize(si.minSize); if (si.maxSize.isValid()) sh->setMaximumSize(si.maxSize); sizehinters.append(sh); - m_grid->addWidget(sh, i, j); + grid->addWidget(sh, i, j); } } - m_toplevel->show(); - QVERIFY(QTest::qWaitForWindowExposed(m_toplevel)); - m_toplevel->adjustSize(); + toplevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&toplevel)); + toplevel.adjustSize(); QTest::qWait(240); // wait for the implicit adjustSize // If the following fails we might have to wait longer. // If that does not help there is likely a problem with the implicit adjustSize in show() if (!fixedSize.isValid()) { // Note that this can fail if the desktop has large fonts on windows. - QTRY_COMPARE(m_toplevel->size(), m_toplevel->sizeHint()); + QTRY_COMPARE(toplevel.size(), toplevel.sizeHint()); } // We are relying on the order here... for (int pi = 0; pi < sizehinters.count(); ++pi) { - QPoint pt = sizehinters.at(pi)->mapTo(m_toplevel, QPoint(0, 0)); + QPoint pt = sizehinters.at(pi)->mapTo(&toplevel, QPoint(0, 0)); QCOMPARE(pt, sizeinfos.at(pi).expectedPos); } } diff --git a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp index d661c074ac7cf1143c7fc879bf1da2cfb4609b35..4d15ac9a9390c60ec7ec3155879b8f3bfda1abe6 100644 --- a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp +++ b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp @@ -66,6 +66,7 @@ public: virtual ~tst_QLayout(); private slots: + void cleanup() { QVERIFY(QApplication::topLevelWidgets().isEmpty()); } void getSetCheck(); void geometry(); void smartMaxSize(); @@ -217,12 +218,12 @@ void tst_QLayout::setLayoutBugs() } widget.setLayout(hBoxLayout); - QVERIFY(widget.layout() == hBoxLayout); + QCOMPARE(widget.layout(), hBoxLayout); QWidget containerWidget(0); containerWidget.setLayout(widget.layout()); - QVERIFY(widget.layout() == 0); - QVERIFY(containerWidget.layout() == hBoxLayout); + QVERIFY(!widget.layout()); + QCOMPARE(containerWidget.layout(), hBoxLayout); } class MyLayout : public QLayout diff --git a/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp b/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp index 7b9eaa418f2c5948fcb5044a97f908a8e75542a0..f206a5fe9a74b2bfa890c87292f5615ffe2d19b8 100644 --- a/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp +++ b/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp @@ -108,6 +108,7 @@ public slots: public slots: void initTestCase(); void cleanupTestCase(); + void cleanup() { QCOMPARE(QApplication::topLevelWidgets().size(), 1); } private slots: void number_data(); diff --git a/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp b/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp index 6c88f8731bf38cf23fd3eadf11e8746691b3a3e9..0f8c9d1c9e114cc2abf9cee0ff2fea9622e0915b 100644 --- a/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp +++ b/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp @@ -44,6 +44,7 @@ class tst_QSizePolicy : public QObject Q_OBJECT private Q_SLOTS: + void cleanup() { QVERIFY(QApplication::topLevelWidgets().isEmpty()); } void qtest(); void defaultValues(); void getSetCheck_data() { data(); } @@ -51,6 +52,8 @@ private Q_SLOTS: void dataStream(); void horizontalStretch(); void verticalStretch(); + void qhash_data() { data(); } + void qhash(); private: void data() const; }; @@ -149,8 +152,6 @@ void tst_QSizePolicy::getSetCheck() QCOMPARE(sp.expandingDirections(), ed); } -#undef FETCH_TEST_DATA - static void makeRow(QSizePolicy sp, QSizePolicy::Policy hp, QSizePolicy::Policy vp, int hst, int vst, QSizePolicy::ControlType ct, bool hfw, bool wfh, Qt::Orientations orients) @@ -314,5 +315,21 @@ void tst_QSizePolicy::verticalStretch() QCOMPARE(sp.verticalStretch(), 255); } +void tst_QSizePolicy::qhash() +{ + FETCH_TEST_DATA; + Q_UNUSED(ed); + + QSizePolicy sp2(hp, vp, ct); + sp2.setVerticalStretch(vst); + sp2.setHorizontalStretch(hst); + if (hfw) sp2.setHeightForWidth(true); + if (wfh) sp2.setWidthForHeight(true); + QCOMPARE(sp, sp2); + QCOMPARE(qHash(sp), qHash(sp2)); +} + +#undef FETCH_TEST_DATA + QTEST_MAIN(tst_QSizePolicy) #include "tst_qsizepolicy.moc" diff --git a/tests/auto/widgets/kernel/qtooltip/BLACKLIST b/tests/auto/widgets/kernel/qtooltip/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..f8d062cc46b07e766ec0d8567d695038963f8b3b --- /dev/null +++ b/tests/auto/widgets/kernel/qtooltip/BLACKLIST @@ -0,0 +1,4 @@ +[whatsThis] +ubuntu-14.04 +[task183679] +opensuse-13.1 diff --git a/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp b/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp index 0de9e188a042ef46838bd5a932dad37c5499baf6..d7746a2ee1202c88b56f493d8dc4bb0982f73d56 100644 --- a/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp +++ b/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp @@ -103,6 +103,10 @@ void tst_QToolTip::task183679() Widget_task183679 widget; widget.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(50, 50)); + // Ensure cursor is not over tooltip, which causes it to hide +#ifndef QT_NO_CURSOR + QCursor::setPos(widget.geometry().topRight() + QPoint(-50, 50)); +#endif widget.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1Char(' ') + QLatin1String(QTest::currentDataTag())); widget.show(); diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index 591aa9e40f5539bef3283256eacba5d7c6eab370..78ccbe302a08f078ac69bb9576692aae4f834e4f 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -12,7 +12,7 @@ osx ubuntu-14.04 osx [focusProxyAndInputMethods] -ubuntu-14.04 +linux [touchEventSynthesizedMouseEvent] ubuntu-14.04 [grabMouse] @@ -28,73 +28,17 @@ osx [stackUnder] osx [raise] -osx-10.9 +osx [widgetAt] osx [sheetOpacity] osx [resizeEvent] osx -[setWindowGeometry:100,123 200x200, flags 0] -osx-10.10 -[windowMoveResize:100,123 200x200, flags 0] -osx-10.10 -[setWindowGeometry:100,122 200x200, flags 0] -osx-10.9 -[windowMoveResize:100,122 200x200, flags 0] -osx-10.9 -[setWindowGeometry:100,100 824x564, flags 0] -osx-10.10 -[windowMoveResize:100,100 824x564, flags 0] -osx-10.10 -[setWindowGeometry:100,100 824x516, flags 0] -osx-10.10 -[windowMoveResize:100,100 824x516, flags 0] -osx-10.10 -[setWindowGeometry:100,73 200x0, flags 0] -osx-10.10 -[windowMoveResize:100,73 200x0, flags 0] -osx-10.10 -[setWindowGeometry:100,100 824x519, flags 0] -osx-10.10 -[windowMoveResize:100,100 824x519, flags 0] -osx-10.10 -[setWindowGeometry:100,100 824x518, flags 0] -osx-10.10 -[windowMoveResize:100,100 824x518, flags 0] -osx-10.10 -[setWindowGeometry:100,72 200x0, flags 0] -osx-10.9 -[windowMoveResize:100,72 200x0, flags 0] -osx-10.9 -[setWindowGeometry:100,122 952x574, flags 0] -osx-10.9 -[windowMoveResize:100,122 952x574, flags 0] -osx-10.9 -[setWindowGeometry:100,122 952x578, flags 0] -osx-10.9 -[windowMoveResize:100,122 952x578, flags 0] -osx-10.9 -[setWindowGeometry:100,122 952x576, flags 0] -osx-10.9 -[windowMoveResize:100,122 952x576, flags 0] -osx-10.9 -[setWindowGeometry:100,100 824x521, flags 0] -osx-10.10 -[windowMoveResize:100,100 824x521, flags 0] -osx-10.10 -[setWindowGeometry:100,122 952x577, flags 0] -osx-10.9 -[windowMoveResize:100,122 952x577, flags 0] -osx-10.9 -[setWindowGeometry:100,122 952x580, flags 0] -osx-10.9 -[windowMoveResize:100,122 952x580, flags 0] -osx-10.9 -[windowMoveResize:130,72 0x0, flags 0] -osx-10.9 -[windowMoveResize:130,122 0x200, flags 0] -osx-10.9 +[setWindowGeometry] +osx +[windowMoveResize] +osx [childEvents] osx [renderInvisible] @@ -114,9 +58,9 @@ osx [showMinimizedKeepsFocus] osx-10.10 [moveWindowInShowEvent:1] -osx-10.9 +osx [moveWindowInShowEvent:2] -osx-10.9 +osx [taskQTBUG_4055_sendSyntheticEnterLeave] osx [syntheticEnterLeave] @@ -128,10 +72,14 @@ osx-10.10 [hideOpaqueChildWhileHidden] osx [resizeStaticContentsChildWidget_QTBUG35282] -osx-10.9 +osx [lower] osx [setClearAndResizeMask] osx [setToolTip] osx-10.9 +[moveInResizeEvent] +ubuntu-14.04 +[moveChild:right] +osx diff --git a/tests/auto/widgets/kernel/qwidget/qwidget.pro b/tests/auto/widgets/kernel/qwidget/qwidget.pro index aae083d45e0e2c90b133d61404be02a5c3c1e293..a3fd6228967c7f0e1008c6bd6302e3dd810f0788 100644 --- a/tests/auto/widgets/kernel/qwidget/qwidget.pro +++ b/tests/auto/widgets/kernel/qwidget/qwidget.pro @@ -20,4 +20,4 @@ x11 { LIBS += $$QMAKE_LIBS_X11 } -!wince*:win32:!winrt: LIBS += -luser32 -lgdi32 +win32:!wince:!winrt: LIBS += -luser32 -lgdi32 diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 68ccaef43ffd216c7874905fd826da06457d1a33..34bd57564638363b63b96016ee10c1b8ed09b029 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -51,6 +51,7 @@ #include <qdesktopwidget.h> #include <private/qwidget_p.h> #include <private/qapplication_p.h> +#include <private/qhighdpiscaling_p.h> #include <qcalendarwidget.h> #include <qmainwindow.h> #include <qdockwidget.h> @@ -193,6 +194,19 @@ static QByteArray msgComparisonFailed(T v1, const char *op, T v2) return s.toLocal8Bit(); } +// Compare a window position that may go through scaling in the platform plugin with fuzz. +static inline bool qFuzzyCompareWindowPosition(const QPoint &p1, const QPoint p2, int fuzz) +{ + return (p1 - p2).manhattanLength() <= fuzz; +} + +static QString msgPointMismatch(const QPoint &p1, const QPoint p2) +{ + QString result; + QDebug(&result) << p1 << "!=" << p2 << ", manhattanLength=" << (p1 - p2).manhattanLength(); + return result; +} + class tst_QWidget : public QObject { Q_OBJECT @@ -1905,8 +1919,10 @@ void tst_QWidget::windowState() widget1.setWindowState(widget1.windowState() ^ Qt::WindowMaximized); QTest::qWait(100); + const int fuzz = int(QHighDpiScaling::factor(widget1.windowHandle())); QVERIFY(!(widget1.windowState() & Qt::WindowMaximized)); - QTRY_COMPARE(widget1.pos(), pos); + QTRY_VERIFY2(qFuzzyCompareWindowPosition(widget1.pos(), pos, fuzz), + qPrintable(msgPointMismatch(widget1.pos(), pos))); QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowNoState); widget1.setWindowState(Qt::WindowMinimized); @@ -1927,7 +1943,8 @@ void tst_QWidget::windowState() widget1.setWindowState(widget1.windowState() ^ Qt::WindowMaximized); QTest::qWait(100); QVERIFY(!(widget1.windowState() & (Qt::WindowMinimized|Qt::WindowMaximized))); - QTRY_COMPARE(widget1.pos(), pos); + QTRY_VERIFY2(qFuzzyCompareWindowPosition(widget1.pos(), pos, fuzz), + qPrintable(msgPointMismatch(widget1.pos(), pos))); QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowNoState); widget1.setWindowState(Qt::WindowFullScreen); @@ -1948,7 +1965,8 @@ void tst_QWidget::windowState() widget1.setWindowState(Qt::WindowNoState); QTest::qWait(100); VERIFY_STATE(Qt::WindowNoState); - QTRY_COMPARE(widget1.pos(), pos); + QTRY_VERIFY2(qFuzzyCompareWindowPosition(widget1.pos(), pos, fuzz), + qPrintable(msgPointMismatch(widget1.pos(), pos))); QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowNoState); widget1.setWindowState(Qt::WindowFullScreen); @@ -1981,7 +1999,8 @@ void tst_QWidget::windowState() QVERIFY(!(widget1.windowState() & stateMask)); QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowNoState); - QTRY_COMPARE(widget1.pos(), pos); + QTRY_VERIFY2(qFuzzyCompareWindowPosition(widget1.pos(), pos, fuzz), + qPrintable(msgPointMismatch(widget1.pos(), pos))); QTRY_COMPARE(widget1.size(), size); } @@ -3079,12 +3098,12 @@ void tst_QWidget::saveRestoreGeometry() const QByteArray four("abca"); const QByteArray garbage("abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"); - QVERIFY(widget.restoreGeometry(empty) == false); - QVERIFY(widget.restoreGeometry(one) == false); - QVERIFY(widget.restoreGeometry(two) == false); - QVERIFY(widget.restoreGeometry(three) == false); - QVERIFY(widget.restoreGeometry(four) == false); - QVERIFY(widget.restoreGeometry(garbage) == false); + QVERIFY(!widget.restoreGeometry(empty)); + QVERIFY(!widget.restoreGeometry(one)); + QVERIFY(!widget.restoreGeometry(two)); + QVERIFY(!widget.restoreGeometry(three)); + QVERIFY(!widget.restoreGeometry(four)); + QVERIFY(!widget.restoreGeometry(garbage)); QVERIFY(widget.restoreGeometry(savedGeometry)); widget.showNormal(); @@ -3354,7 +3373,7 @@ void tst_QWidget::widgetAt() #if defined(Q_OS_WINCE) QEXPECT_FAIL("", "Windows CE does only support rectangular regions", Continue); //See also task 147191 #endif - QTRY_VERIFY(QApplication::widgetAt(testPos) == w1.data()); + QTRY_COMPARE(QApplication::widgetAt(testPos), w1.data()); QTRY_VERIFY(QApplication::widgetAt(testPos + QPoint(1, 1)) == w2.data()); } @@ -3401,24 +3420,24 @@ void tst_QWidget::testDeletionInEventHandlers() QPointer<Widget> w = new Widget; w->deleteThis = true; w->close(); - QVERIFY(w == 0); + QVERIFY(w.isNull()); delete w; // focusOut (crashes) //w = new Widget; //w->show(); //w->setFocus(); - //QVERIFY(qApp->focusWidget() == w); + //QCOMPARE(qApp->focusWidget(), w); //w->deleteThis = true; //w->clearFocus(); - //QVERIFY(w == 0); + //QVERIFY(w.isNull()); // key press w = new Widget; w->show(); w->deleteThis = true; QTest::keyPress(w, Qt::Key_A); - QVERIFY(w == 0); + QVERIFY(w.isNull()); delete w; // key release @@ -3426,7 +3445,7 @@ void tst_QWidget::testDeletionInEventHandlers() w->show(); w->deleteThis = true; QTest::keyRelease(w, Qt::Key_A); - QVERIFY(w == 0); + QVERIFY(w.isNull()); delete w; // mouse press @@ -3434,7 +3453,7 @@ void tst_QWidget::testDeletionInEventHandlers() w->show(); w->deleteThis = true; QTest::mousePress(w, Qt::LeftButton); - QVERIFY(w == 0); + QVERIFY(w.isNull()); delete w; // mouse release @@ -3443,7 +3462,7 @@ void tst_QWidget::testDeletionInEventHandlers() w->deleteThis = true; QMouseEvent me(QEvent::MouseButtonRelease, QPoint(1, 1), Qt::LeftButton, Qt::LeftButton, 0); qApp->notify(w, &me); - QVERIFY(w == 0); + QVERIFY(w.isNull()); delete w; // mouse double click @@ -3451,7 +3470,7 @@ void tst_QWidget::testDeletionInEventHandlers() w->show(); w->deleteThis = true; QTest::mouseDClick(w, Qt::LeftButton); - QVERIFY(w == 0); + QVERIFY(w.isNull()); delete w; // hide event (crashes) @@ -3459,13 +3478,13 @@ void tst_QWidget::testDeletionInEventHandlers() //w->show(); //w->deleteThis = true; //w->hide(); - //QVERIFY(w == 0); + //QVERIFY(w.isNull()); // action event w = new Widget; w->deleteThis = true; w->addAction(new QAction(w)); - QVERIFY(w == 0); + QVERIFY(w.isNull()); delete w; // change event @@ -3473,7 +3492,7 @@ void tst_QWidget::testDeletionInEventHandlers() w->show(); w->deleteThis = true; w->setMouseTracking(true); - QVERIFY(w == 0); + QVERIFY(w.isNull()); delete w; w = new Widget; @@ -3482,7 +3501,7 @@ void tst_QWidget::testDeletionInEventHandlers() w->deleteThis = true; me = QMouseEvent(QEvent::MouseMove, QPoint(0, 0), Qt::NoButton, Qt::NoButton, Qt::NoModifier); QApplication::sendEvent(w, &me); - QVERIFY(w == 0); + QVERIFY(w.isNull()); delete w; } @@ -3676,6 +3695,8 @@ void tst_QWidget::optimizedResizeMove() void tst_QWidget::optimizedResize_topLevel() { + if (QHighDpiScaling::isActive()) + QSKIP("Skip due to rounding errors in the regions."); StaticWidget topLevel; topLevel.gotPaintEvent = false; topLevel.show(); @@ -3910,7 +3931,7 @@ void tst_QWidget::winIdChangeEvent() QCOMPARE(winIdBefore, winIdAfter); QCOMPARE(child.winIdChangeEventCount(), 3); // winId is set to zero during reparenting - QVERIFY(0 == child.m_winIdList[1]); + QCOMPARE(WId(0), child.m_winIdList[1]); } { @@ -3950,7 +3971,7 @@ void tst_QWidget::winIdChangeEvent() QCOMPARE(winIdBefore, winIdAfter); QCOMPARE(child.winIdChangeEventCount(), 3); // winId is set to zero during reparenting - QVERIFY(0 == child.m_winIdList[1]); + QCOMPARE(WId(0), child.m_winIdList[1]); } } @@ -4496,7 +4517,7 @@ void tst_QWidget::qobject_castInDestroyedSlot() QObject::connect(widget, SIGNAL(destroyed(QObject*)), &checker, SLOT(destroyedSlot(QObject*))); delete widget; - QVERIFY(checker.wasQWidget == true); + QVERIFY(checker.wasQWidget); } // Since X11 WindowManager operations are all async, and we have no way to know if the window @@ -10463,7 +10484,7 @@ void tst_QWidget::qmlSetParentHelper() QWidget child; QVERIFY(QAbstractDeclarativeData::setWidgetParent); QAbstractDeclarativeData::setWidgetParent(&child, &parent); - QVERIFY(child.parentWidget() == &parent); + QCOMPARE(child.parentWidget(), &parent); QAbstractDeclarativeData::setWidgetParent(&child, 0); QVERIFY(!child.parentWidget()); #else diff --git a/tests/auto/widgets/kernel/qwidgetaction/tst_qwidgetaction.cpp b/tests/auto/widgets/kernel/qwidgetaction/tst_qwidgetaction.cpp index df54d22a2f9f6a58a6373d669c0519606ed21d48..207ce00dbf7cf7e109569ce582498b07ea2a584c 100644 --- a/tests/auto/widgets/kernel/qwidgetaction/tst_qwidgetaction.cpp +++ b/tests/auto/widgets/kernel/qwidgetaction/tst_qwidgetaction.cpp @@ -55,6 +55,8 @@ class tst_QWidgetAction : public QObject { Q_OBJECT private slots: + void initTestCase(); + void cleanup(); void defaultWidget(); void visibilityUpdate(); void customWidget(); @@ -65,6 +67,19 @@ private slots: void releaseWidgetCrash(); }; +void tst_QWidgetAction::initTestCase() +{ + // Disable menu/combo animations to prevent the alpha widgets from getting in the + // way in popup(), failing the top level leak check in cleanup(). + QApplication::setEffectEnabled(Qt::UI_AnimateMenu, false); + QApplication::setEffectEnabled(Qt::UI_AnimateCombo, false); +} + +void tst_QWidgetAction::cleanup() +{ + QVERIFY(QApplication::topLevelWidgets().isEmpty()); +} + void tst_QWidgetAction::defaultWidget() { { @@ -123,14 +138,14 @@ void tst_QWidgetAction::defaultWidget() action->setDefaultWidget(combo); tb1.addAction(action); - QVERIFY(combo->parent() == &tb1); + QCOMPARE(combo->parent(), &tb1); qApp->processEvents(); qApp->processEvents(); QVERIFY(combo->isVisible()); // not supported, not supposed to work, hence the parent() check tb2.addAction(action); - QVERIFY(combo->parent() == &tb1); + QCOMPARE(combo->parent(), &tb1); tb2.removeAction(action); tb1.removeAction(action); @@ -141,11 +156,11 @@ void tst_QWidgetAction::defaultWidget() tb2.addAction(action); qApp->processEvents(); //the call to hide is delayd by the toolbar layout qApp->processEvents(); - QVERIFY(combo->parent() == &tb2); + QCOMPARE(combo->parent(), &tb2); QVERIFY(combo->isVisible()); tb1.addAction(action); - QVERIFY(combo->parent() == &tb2); + QCOMPARE(combo->parent(), &tb2); delete action; QVERIFY(!combo); @@ -156,17 +171,17 @@ void tst_QWidgetAction::defaultWidget() QPointer<QComboBox> combo1 = new QComboBox; a->setDefaultWidget(combo1); - QVERIFY(a->defaultWidget() == combo1); + QCOMPARE(a->defaultWidget(), combo1.data()); a->setDefaultWidget(combo1); QVERIFY(combo1); - QVERIFY(a->defaultWidget() == combo1); + QCOMPARE(a->defaultWidget(), combo1.data()); QPointer<QComboBox> combo2 = new QComboBox; QVERIFY(combo1 != combo2); a->setDefaultWidget(combo2); QVERIFY(!combo1); - QVERIFY(a->defaultWidget() == combo2); + QCOMPARE(a->defaultWidget(), combo2.data()); delete a; QVERIFY(!combo2); @@ -238,7 +253,7 @@ void tst_QWidgetAction::customWidget() combos = action->createdWidgets(); QCOMPARE(combos.count(), 2); - QVERIFY(combos.at(0) == combo1); + QCOMPARE(combos.at(0), combo1.data()); QPointer<QComboBox> combo2 = qobject_cast<QComboBox *>(combos.at(1)); QVERIFY(combo2); @@ -262,7 +277,7 @@ void tst_QWidgetAction::keepOwnership() { QToolBar *tb = new QToolBar; tb->addAction(action); - QVERIFY(combo->parent() == tb); + QCOMPARE(combo->parent(), tb); delete tb; } diff --git a/tests/auto/widgets/kernel/qwidgetsvariant/tst_qwidgetsvariant.cpp b/tests/auto/widgets/kernel/qwidgetsvariant/tst_qwidgetsvariant.cpp index 8b566713f982c0fb9c6ceba75002fe1adac2b28e..690ef30f7175ae77e047bf4c9536e53a654f14d2 100644 --- a/tests/auto/widgets/kernel/qwidgetsvariant/tst_qwidgetsvariant.cpp +++ b/tests/auto/widgets/kernel/qwidgetsvariant/tst_qwidgetsvariant.cpp @@ -84,13 +84,13 @@ void tst_QWidgetsVariant::constructor_invalid() QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^Trying to construct an instance of an invalid type, type id:")); QVariant variant(static_cast<QVariant::Type>(typeId)); QVERIFY(!variant.isValid()); - QVERIFY(variant.userType() == QMetaType::UnknownType); + QCOMPARE(variant.userType(), int(QMetaType::UnknownType)); } { QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^Trying to construct an instance of an invalid type, type id:")); QVariant variant(typeId, /* copy */ 0); QVERIFY(!variant.isValid()); - QVERIFY(variant.userType() == QMetaType::UnknownType); + QCOMPARE(variant.userType(), int(QMetaType::UnknownType)); } } @@ -208,7 +208,7 @@ void tst_QWidgetsVariant::qvariant_cast_QObject_derived() CustomQWidget customWidget; QWidget *widget = &customWidget; QVariant data = QVariant::fromValue(widget); - QVERIFY(data.userType() == qMetaTypeId<QWidget*>()); + QCOMPARE(data.userType(), qMetaTypeId<QWidget*>()); QCOMPARE(data.value<QObject*>(), widget); QCOMPARE(data.value<QWidget*>(), widget); diff --git a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp index 33427788f697ccc2dcbd94572ce6c1e862228885..7d48ab760d2f0d6a4b7c11f507d112bf4dcc4115 100644 --- a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp +++ b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp @@ -327,7 +327,7 @@ void tst_QWindowContainer::testDockWidget() QTest::qWait(1000); dock->setFloating(false); - QTRY_VERIFY(window->parent() == mainWindow.window()->windowHandle()); + QTRY_COMPARE(window->parent(), mainWindow.window()->windowHandle()); } QTEST_MAIN(tst_QWindowContainer) diff --git a/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp b/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp index 7aa529d5ee98f7e9de41c0ae26c1b0a3e07351b5..21369d45208ef3d22e0425512abd7f3dfc39dc88 100644 --- a/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp +++ b/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp @@ -214,12 +214,12 @@ void tst_QStyle::testProxyStyle() QProxyStyle *proxyStyle = new QProxyStyle(); QVERIFY(proxyStyle->baseStyle()); QStyle *style = QStyleFactory::create("Windows"); - QVERIFY(style->proxy() == style); + QCOMPARE(style->proxy(), style); proxyStyle->setBaseStyle(style); - QVERIFY(style->proxy() == proxyStyle); - QVERIFY(style->parent() == proxyStyle); - QVERIFY(proxyStyle->baseStyle() == style); + QCOMPARE(style->proxy(), proxyStyle); + QCOMPARE(style->parent(), proxyStyle); + QCOMPARE(proxyStyle->baseStyle(), style); QVERIFY(testAllFunctions(proxyStyle)); proxyStyle->setBaseStyle(0); @@ -236,7 +236,7 @@ void tst_QStyle::testProxyStyle() QLineEdit edit; edit.setStyle(&customStyle); QVERIFY(!customStyle.parent()); - QVERIFY(edit.style()->pixelMetric(QStyle::PM_ButtonIconSize) == 13); + QCOMPARE(edit.style()->pixelMetric(QStyle::PM_ButtonIconSize), 13); } void tst_QStyle::drawItemPixmap() diff --git a/tests/auto/widgets/styles/qstylesheetstyle/BLACKLIST b/tests/auto/widgets/styles/qstylesheetstyle/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..cf78fb47c2074d778595ba7babeff5b8f08c3749 --- /dev/null +++ b/tests/auto/widgets/styles/qstylesheetstyle/BLACKLIST @@ -0,0 +1,2 @@ +[hoverColors] +ubuntu-14.04 diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index 25f7715e3bc715105595d04cd4c3f10a6e428fb1..a511e91e2c5c36cd6388ec6247d84360defbc2c3 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -178,45 +178,49 @@ void tst_QStyleSheetStyle::numinstances() void tst_QStyleSheetStyle::widgetsBeforeAppStyleSheet() { QPushButton w1; // widget with no stylesheet + const QColor red(Qt::red); + const QColor white(Qt::white); qApp->setStyleSheet("* { color: red; }"); - QVERIFY(COLOR(w1) == QColor("red")); + QCOMPARE(COLOR(w1), red); w1.setStyleSheet("color: white"); - QVERIFY(COLOR(w1) == QColor("white")); + QCOMPARE(COLOR(w1), white); qApp->setStyleSheet(""); - QVERIFY(COLOR(w1) == QColor("white")); + QCOMPARE(COLOR(w1), white); w1.setStyleSheet(""); - QVERIFY(COLOR(w1) == APPCOLOR(w1)); + QCOMPARE(COLOR(w1), APPCOLOR(w1)); } class FriendlySpinBox : public QSpinBox { friend class tst_QStyleSheetStyle; }; void tst_QStyleSheetStyle::widgetsAfterAppStyleSheet() { + const QColor red(Qt::red); + const QColor white(Qt::white); qApp->setStyleSheet("* { color: red; font-size: 32pt; }"); QPushButton w1; FriendlySpinBox spin; - QVERIFY(COLOR(w1) == QColor("red")); - QVERIFY(COLOR(spin) == QColor("red")); - QVERIFY(COLOR(*spin.lineEdit()) == QColor("red")); + QCOMPARE(COLOR(w1), red); + QCOMPARE(COLOR(spin), red); + QCOMPARE(COLOR(*spin.lineEdit()), red); QCOMPARE(FONTSIZE(w1), 32); QCOMPARE(FONTSIZE(spin), 32); QCOMPARE(FONTSIZE(*spin.lineEdit()), 32); w1.setStyleSheet("color: white"); - QVERIFY(COLOR(w1) == QColor("white")); - QVERIFY(COLOR(spin) == QColor("red")); - QVERIFY(COLOR(*spin.lineEdit()) == QColor("red")); + QCOMPARE(COLOR(w1), white); + QCOMPARE(COLOR(spin), red); + QCOMPARE(COLOR(*spin.lineEdit()), red); w1.setStyleSheet(""); - QVERIFY(COLOR(w1) == QColor("red")); - QVERIFY(COLOR(spin) == QColor("red")); - QVERIFY(COLOR(*spin.lineEdit()) == QColor("red")); + QCOMPARE(COLOR(w1), red); + QCOMPARE(COLOR(spin), red); + QCOMPARE(COLOR(*spin.lineEdit()), red); w1.setStyleSheet("color: white"); - QVERIFY(COLOR(w1) == QColor("white")); + QCOMPARE(COLOR(w1), white); qApp->setStyleSheet(""); - QVERIFY(COLOR(w1) == QColor("white")); - QVERIFY(COLOR(spin) == APPCOLOR(spin)); - QVERIFY(COLOR(*spin.lineEdit()) == APPCOLOR(*spin.lineEdit())); + QCOMPARE(COLOR(w1), white); + QCOMPARE(COLOR(spin), APPCOLOR(spin)); + QCOMPARE(COLOR(*spin.lineEdit()), APPCOLOR(*spin.lineEdit())); w1.setStyleSheet(""); - QVERIFY(COLOR(w1) == APPCOLOR(w1)); + QCOMPARE(COLOR(w1), APPCOLOR(w1)); // QCOMPARE(FONTSIZE(w1), APPFONTSIZE(w1)); //### task 244261 QCOMPARE(FONTSIZE(spin), APPFONTSIZE(spin)); //QCOMPARE(FONTSIZE(*spin.lineEdit()), APPFONTSIZE(*spin.lineEdit())); //### task 244261 @@ -224,121 +228,135 @@ void tst_QStyleSheetStyle::widgetsAfterAppStyleSheet() void tst_QStyleSheetStyle::applicationStyleSheet() { + const QColor red(Qt::red); + const QColor white(Qt::white); QPushButton w1; qApp->setStyleSheet("* { color: red; }"); - QVERIFY(COLOR(w1) == QColor("red")); + QCOMPARE(COLOR(w1), red); qApp->setStyleSheet("* { color: white; }"); - QVERIFY(COLOR(w1) == QColor("white")); + QCOMPARE(COLOR(w1), white); qApp->setStyleSheet(""); - QVERIFY(COLOR(w1) == APPCOLOR(w1)); + QCOMPARE(COLOR(w1), APPCOLOR(w1)); qApp->setStyleSheet("* { color: red }"); - QVERIFY(COLOR(w1) == QColor("red")); + QCOMPARE(COLOR(w1), red); } void tst_QStyleSheetStyle::windowStyleSheet() { + const QColor red(Qt::red); + const QColor white(Qt::white); QPushButton w1; qApp->setStyleSheet(""); w1.setStyleSheet("* { color: red; }"); - QVERIFY(COLOR(w1) == QColor("red")); + QCOMPARE(COLOR(w1), red); w1.setStyleSheet("* { color: white; }"); - QVERIFY(COLOR(w1) == QColor("white")); + QCOMPARE(COLOR(w1), white); w1.setStyleSheet(""); - QVERIFY(COLOR(w1) == APPCOLOR(w1)); + QCOMPARE(COLOR(w1), APPCOLOR(w1)); w1.setStyleSheet("* { color: red }"); - QVERIFY(COLOR(w1) == QColor("red")); + QCOMPARE(COLOR(w1), red); qApp->setStyleSheet("* { color: green }"); - QVERIFY(COLOR(w1) == QColor("red")); + QCOMPARE(COLOR(w1), red); w1.setStyleSheet(""); - QVERIFY(COLOR(w1) == QColor("green")); + QCOMPARE(COLOR(w1), QColor("green")); qApp->setStyleSheet(""); - QVERIFY(COLOR(w1) == APPCOLOR(w1)); + QCOMPARE(COLOR(w1), APPCOLOR(w1)); } void tst_QStyleSheetStyle::widgetStyleSheet() { + const QColor blue(Qt::blue); + const QColor red(Qt::red); + const QColor white(Qt::white); QPushButton w1; QPushButton *pb = new QPushButton(&w1); QPushButton &w2 = *pb; qApp->setStyleSheet(""); w1.setStyleSheet("* { color: red }"); - QVERIFY(COLOR(w1) == QColor("red")); - QVERIFY(COLOR(w2) == QColor("red")); + QCOMPARE(COLOR(w1), red); + QCOMPARE(COLOR(w2), red); w2.setStyleSheet("* { color: white }"); - QVERIFY(COLOR(w2) == QColor("white")); + QCOMPARE(COLOR(w2), white); w1.setStyleSheet("* { color: blue }"); - QVERIFY(COLOR(w1) == QColor("blue")); - QVERIFY(COLOR(w2) == QColor("white")); + QCOMPARE(COLOR(w1), blue); + QCOMPARE(COLOR(w2), white); w1.setStyleSheet(""); - QVERIFY(COLOR(w1) == APPCOLOR(w1)); - QVERIFY(COLOR(w2) == QColor("white")); + QCOMPARE(COLOR(w1), APPCOLOR(w1)); + QCOMPARE(COLOR(w2), white); w2.setStyleSheet(""); - QVERIFY(COLOR(w1) == APPCOLOR(w1)); - QVERIFY(COLOR(w2) == APPCOLOR(w2)); + QCOMPARE(COLOR(w1), APPCOLOR(w1)); + QCOMPARE(COLOR(w2), APPCOLOR(w2)); } void tst_QStyleSheetStyle::reparentWithNoChildStyleSheet() { + const QColor blue(Qt::blue); + const QColor red(Qt::red); + const QColor white(Qt::white); QPushButton p1, p2; QPushButton *pb = new QPushButton(&p1); QPushButton &c1 = *pb; // child with no stylesheet qApp->setStyleSheet(""); p1.setStyleSheet("* { color: red }"); - QVERIFY(COLOR(c1) == QColor("red")); + QCOMPARE(COLOR(c1), red); c1.setParent(&p2); - QVERIFY(COLOR(c1) == APPCOLOR(c1)); + QCOMPARE(COLOR(c1), APPCOLOR(c1)); p2.setStyleSheet("* { color: white }"); - QVERIFY(COLOR(c1) == QColor("white")); + QCOMPARE(COLOR(c1), white); c1.setParent(&p1); - QVERIFY(COLOR(c1) == QColor("red")); + QCOMPARE(COLOR(c1), red); qApp->setStyleSheet("* { color: blue }"); c1.setParent(0); - QVERIFY(COLOR(c1) == QColor("blue")); + QCOMPARE(COLOR(c1), blue); delete pb; } void tst_QStyleSheetStyle::reparentWithChildStyleSheet() { + const QColor gray("gray"); + const QColor white(Qt::white); qApp->setStyleSheet(""); QPushButton p1, p2; QPushButton *pb = new QPushButton(&p1); QPushButton &c1 = *pb; c1.setStyleSheet("background: gray"); - QVERIFY(BACKGROUND(c1) == QColor("gray")); + QCOMPARE(BACKGROUND(c1), gray); c1.setParent(&p2); - QVERIFY(BACKGROUND(c1) == QColor("gray")); + QCOMPARE(BACKGROUND(c1), gray); qApp->setStyleSheet("* { color: white }"); c1.setParent(&p1); - QVERIFY(BACKGROUND(c1) == QColor("gray")); - QVERIFY(COLOR(c1) == QColor("white")); + QCOMPARE(BACKGROUND(c1), gray); + QCOMPARE(COLOR(c1), white); } void tst_QStyleSheetStyle::repolish() { + const QColor red(Qt::red); + const QColor white(Qt::white); qApp->setStyleSheet(""); QPushButton p1; p1.setStyleSheet("color: red; background: white"); - QVERIFY(BACKGROUND(p1) == QColor("white")); + QCOMPARE(BACKGROUND(p1), white); p1.setStyleSheet("background: white"); - QVERIFY(COLOR(p1) == APPCOLOR(p1)); + QCOMPARE(COLOR(p1), APPCOLOR(p1)); p1.setStyleSheet("color: red"); - QVERIFY(COLOR(p1) == QColor("red")); - QVERIFY(BACKGROUND(p1) == APPBACKGROUND(p1)); + QCOMPARE(COLOR(p1), red); + QCOMPARE(BACKGROUND(p1), APPBACKGROUND(p1)); p1.setStyleSheet(""); - QVERIFY(COLOR(p1) == APPCOLOR(p1)); - QVERIFY(BACKGROUND(p1) == APPBACKGROUND(p1)); + QCOMPARE(COLOR(p1), APPCOLOR(p1)); + QCOMPARE(BACKGROUND(p1), APPBACKGROUND(p1)); } void tst_QStyleSheetStyle::widgetStyle() @@ -492,12 +510,12 @@ void tst_QStyleSheetStyle::appStyle() QPointer<QStyle> style2 = QStyleFactory::create("Windows"); qApp->setStyle(style1); // Basic sanity - QVERIFY(qApp->style() == style1); + QCOMPARE(QApplication::style(), style1.data()); qApp->setStyle(style2); QVERIFY(style1.isNull()); // qApp must have taken ownership and deleted it // Setting null should not crash qApp->setStyle(0); - QVERIFY(qApp->style() == style2); + QCOMPARE(QApplication::style(), style2.data()); // Set the stylesheet qApp->setStyleSheet("whatever"); @@ -505,7 +523,7 @@ void tst_QStyleSheetStyle::appStyle() QVERIFY(!sss.isNull()); QCOMPARE(sss->metaObject()->className(), "QStyleSheetStyle"); // must be our proxy now QVERIFY(!style2.isNull()); // this should exist as it is the base of the proxy - QVERIFY(sss->baseStyle() == style2); + QCOMPARE(sss->baseStyle(), style2.data()); style1 = QStyleFactory::create("Windows"); qApp->setStyle(style1); QVERIFY(style2.isNull()); // should disappear automatically @@ -514,16 +532,16 @@ void tst_QStyleSheetStyle::appStyle() // Update the stylesheet and check nothing changes sss = (QStyleSheetStyle *)qApp->style(); qApp->setStyleSheet("whatever2"); - QVERIFY(qApp->style() == sss); - QVERIFY(sss->baseStyle() == style1); + QCOMPARE(QApplication::style(), sss.data()); + QCOMPARE(sss->baseStyle(), style1.data()); // Revert the stylesheet qApp->setStyleSheet(""); QVERIFY(sss.isNull()); // should have disappeared - QVERIFY(qApp->style() == style1); + QCOMPARE(QApplication::style(), style1.data()); qApp->setStyleSheet(""); - QVERIFY(qApp->style() == style1); + QCOMPARE(QApplication::style(), style1.data()); } void tst_QStyleSheetStyle::dynamicProperty() @@ -589,21 +607,24 @@ namespace ns { void tst_QStyleSheetStyle::namespaces() { + const QColor blue(Qt::blue); + const QColor red(Qt::red); + const QColor white(Qt::white); ns::PushButton1 pb1; qApp->setStyleSheet("ns--PushButton1 { background: white }"); - QVERIFY(BACKGROUND(pb1) == QColor("white")); + QCOMPARE(BACKGROUND(pb1), white); qApp->setStyleSheet(".ns--PushButton1 { background: red }"); - QVERIFY(BACKGROUND(pb1) == QColor("red")); + QCOMPARE(BACKGROUND(pb1), red); ns::PushButton2 pb2; qApp->setStyleSheet("ns--PushButton1 { background: blue}"); - QVERIFY(BACKGROUND(pb2) == QColor("blue")); + QCOMPARE(BACKGROUND(pb2), blue); qApp->setStyleSheet("ns--PushButton2 { background: magenta }"); - QVERIFY(BACKGROUND(pb2) == QColor("magenta")); + QCOMPARE(BACKGROUND(pb2), QColor(Qt::magenta)); qApp->setStyleSheet(".PushButtonTwo { background: white; }"); - QVERIFY(BACKGROUND(pb2) == QColor("white")); + QCOMPARE(BACKGROUND(pb2), white); qApp->setStyleSheet(".PushButtonDuo { background: red; }"); - QVERIFY(BACKGROUND(pb2) == QColor("red")); + QCOMPARE(BACKGROUND(pb2), red); } void tst_QStyleSheetStyle::palettePropagation() @@ -639,8 +660,8 @@ void tst_QStyleSheetStyle::fontPropagation() int viewFontSize = FONTSIZE(*popup); cb.setStyleSheet("QComboBox { font-size: 20pt; }"); - QVERIFY(FONTSIZE(cb) == 20); - QVERIFY(FONTSIZE(*popup) == viewFontSize); + QCOMPARE(FONTSIZE(cb), 20); + QCOMPARE(FONTSIZE(*popup), viewFontSize); QGroupBox gb; QPushButton *push = new QPushButton(&gb); QPushButton &pb = *push; @@ -648,25 +669,25 @@ void tst_QStyleSheetStyle::fontPropagation() int gbFontSize = FONTSIZE(gb); gb.setStyleSheet("QGroupBox { font-size: 20pt }"); - QVERIFY(FONTSIZE(gb) == 20); + QCOMPARE(FONTSIZE(gb), 20); QVERIFY(FONTSIZE(pb) == buttonFontSize); // font does not propagate gb.setStyleSheet("QGroupBox * { font-size: 20pt; }"); - QVERIFY(FONTSIZE(gb) == gbFontSize); - QVERIFY(FONTSIZE(pb) == 20); + QCOMPARE(FONTSIZE(gb), gbFontSize); + QCOMPARE(FONTSIZE(pb), 20); QWidget window; window.setStyleSheet("* { font-size: 10pt }"); pb.setParent(&window); QCOMPARE(FONTSIZE(pb), 10); window.setStyleSheet(""); - QVERIFY(FONTSIZE(pb) == buttonFontSize); + QCOMPARE(FONTSIZE(pb), buttonFontSize); QTabWidget tw; tw.setStyleSheet("QTabWidget { font-size: 20pt; }"); - QVERIFY(FONTSIZE(tw) == 20); + QCOMPARE(FONTSIZE(tw), 20); QWidget *child = tw.findChild<QWidget *>("qt_tabwidget_tabbar"); QVERIFY2(child, "QTabWidget did not contain a widget named \"qt_tabwidget_tabbar\""); - QVERIFY(FONTSIZE(*child) == 20); + QCOMPARE(FONTSIZE(*child), 20); } void tst_QStyleSheetStyle::onWidgetDestroyed() @@ -1009,6 +1030,8 @@ void tst_QStyleSheetStyle::tabAlignement() void tst_QStyleSheetStyle::attributesList() { + const QColor blue(Qt::blue); + const QColor red(Qt::red); QWidget w; QPushButton *p1=new QPushButton(&w); QPushButton *p2=new QPushButton(&w); @@ -1019,10 +1042,10 @@ void tst_QStyleSheetStyle::attributesList() p3->setProperty("prop", QStringList() << "foo" << "bar"); w.setStyleSheet(" QPushButton{ background-color:blue; } QPushButton[prop~=red] { background-color:red; }"); - QCOMPARE(BACKGROUND(*p1) , QColor("red")); - QCOMPARE(BACKGROUND(*p2) , QColor("red")); - QCOMPARE(BACKGROUND(*p3) , QColor("blue")); - QCOMPARE(BACKGROUND(*p4) , QColor("blue")); + QCOMPARE(BACKGROUND(*p1) , red); + QCOMPARE(BACKGROUND(*p2) , red); + QCOMPARE(BACKGROUND(*p3) , blue); + QCOMPARE(BACKGROUND(*p4) , blue); } void tst_QStyleSheetStyle::minmaxSizes() @@ -1065,6 +1088,7 @@ void tst_QStyleSheetStyle::minmaxSizes() void tst_QStyleSheetStyle::task206238_twice() { + const QColor red(Qt::red); QMainWindow w; QTabWidget* tw = new QTabWidget; tw->addTab(new QLabel("foo"), "test"); @@ -1073,12 +1097,12 @@ void tst_QStyleSheetStyle::task206238_twice() centerOnScreen(&w); w.show(); QTest::qWait(20); - QCOMPARE(BACKGROUND(w) , QColor("red")); - QCOMPARE(BACKGROUND(*tw), QColor("red")); + QCOMPARE(BACKGROUND(w) , red); + QCOMPARE(BACKGROUND(*tw), red); w.setStyleSheet("background: red;"); QTest::qWait(20); - QCOMPARE(BACKGROUND(w) , QColor("red")); - QCOMPARE(BACKGROUND(*tw), QColor("red")); + QCOMPARE(BACKGROUND(w) , red); + QCOMPARE(BACKGROUND(*tw), red); } void tst_QStyleSheetStyle::transparent() diff --git a/tests/auto/widgets/styles/styles.pro b/tests/auto/widgets/styles/styles.pro index 508b6ecd41a2af1c6ae9995dd331be868b3bb6a9..0de9dfcdab5086b4c9eff5247d6a191e42b836d4 100644 --- a/tests/auto/widgets/styles/styles.pro +++ b/tests/auto/widgets/styles/styles.pro @@ -12,5 +12,5 @@ SUBDIRS=\ !mac:SUBDIRS -= \ qmacstyle \ -ios|android|qnx|*wince*:SUBDIRS -= \ +ios|android|qnx|wince: SUBDIRS -= \ qstylesheetstyle \ diff --git a/tests/auto/widgets/util/qcompleter/BLACKLIST b/tests/auto/widgets/util/qcompleter/BLACKLIST index ffbcc94a1f544766489646ac0e0817dc3a35a914..fdc424b6ac1e7cb4e520343c5557fbef383365f6 100644 --- a/tests/auto/widgets/util/qcompleter/BLACKLIST +++ b/tests/auto/widgets/util/qcompleter/BLACKLIST @@ -1,2 +1,2 @@ [QTBUG_14292_filesystem] -ubuntu-14.04 +linux diff --git a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp index dbfeda810410f5cae4c6d1e89205e1917fd3bc7d..e8ac9aa5d21f91231281ebc6c691278f0cc10f3c 100644 --- a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp @@ -1043,9 +1043,9 @@ void tst_QCompleter::setters() QAbstractItemModel *oldModel = completer->model(); completer->setModel(dirModel); QVERIFY(completer->popup()->model() != oldModel); - QVERIFY(completer->popup()->model() == completer->completionModel()); + QCOMPARE(completer->popup()->model(), completer->completionModel()); completer->setPopup(new QListView); - QVERIFY(completer->popup()->model() == completer->completionModel()); + QCOMPARE(completer->popup()->model(), completer->completionModel()); completer->setModel(new QStringListModel(completer)); QVERIFY(dirModel == 0); // must have been deleted @@ -1062,7 +1062,7 @@ void tst_QCompleter::modelDeletion() QStringListModel *listModel = new QStringListModel(list); completer->setCompletionPrefix("i"); completer->setModel(listModel); - QVERIFY(completer->completionCount() == 3); + QCOMPARE(completer->completionCount(), 3); QScopedPointer<QListView> view(new QListView); view->setModel(completer->completionModel()); delete listModel; @@ -1070,8 +1070,8 @@ void tst_QCompleter::modelDeletion() view->show(); qApp->processEvents(); view.reset(); - QVERIFY(completer->completionCount() == 0); - QVERIFY(completer->currentRow() == -1); + QCOMPARE(completer->completionCount(), 0); + QCOMPARE(completer->currentRow(), -1); } void tst_QCompleter::multipleWidgets() @@ -1098,7 +1098,7 @@ void tst_QCompleter::multipleWidgets() window.activateWindow(); QApplication::setActiveWindow(&window); QTest::qWait(50); - QTRY_VERIFY(qApp->focusWidget() == comboBox); + QTRY_COMPARE(QApplication::focusWidget(), comboBox); comboBox->lineEdit()->setText("it"); QCOMPARE(comboBox->currentText(), QString("it")); // should not complete with setText QTest::keyPress(comboBox, 'e'); @@ -1111,7 +1111,7 @@ void tst_QCompleter::multipleWidgets() lineEdit->show(); lineEdit->setFocus(); QTest::qWait(50); - QTRY_VERIFY(qApp->focusWidget() == lineEdit); + QTRY_COMPARE(QApplication::focusWidget(), lineEdit); lineEdit->setText("it"); QCOMPARE(lineEdit->text(), QString("it")); // should not completer with setText QCOMPARE(comboBox->currentText(), QString("")); // combo box text must not change! @@ -1148,13 +1148,13 @@ void tst_QCompleter::focusIn() lineEdit2->show(); comboBox->setFocus(); - QTRY_VERIFY(completer.widget() == comboBox); + QTRY_COMPARE(completer.widget(), comboBox); lineEdit->setFocus(); - QTRY_VERIFY(completer.widget() == lineEdit); + QTRY_COMPARE(completer.widget(), lineEdit); comboBox->setFocus(); - QTRY_VERIFY(completer.widget() == comboBox); + QTRY_COMPARE(completer.widget(), comboBox); lineEdit2->setFocus(); - QTRY_VERIFY(completer.widget() == comboBox); + QTRY_COMPARE(completer.widget(), comboBox); } void tst_QCompleter::dynamicSortOrder() diff --git a/tests/auto/widgets/util/qscroller/tst_qscroller.cpp b/tests/auto/widgets/util/qscroller/tst_qscroller.cpp index d2e88a1656c165a32a72288233aa90be82f8b7fe..58a655321cc8666331d7fc255f87e3b1a7a8453b 100644 --- a/tests/auto/widgets/util/qscroller/tst_qscroller.cpp +++ b/tests/auto/widgets/util/qscroller/tst_qscroller.cpp @@ -297,7 +297,7 @@ void tst_QScroller::staticScrollers() QScrollerProperties sp2 = QScroller::scroller(o2)->scrollerProperties(); // default properties should be the same - QVERIFY(sp1 == sp2); + QCOMPARE(sp1, sp2); QCOMPARE(QScroller::scroller(o1)->scrollerProperties(), sp1); diff --git a/tests/auto/widgets/util/qsystemtrayicon/tst_qsystemtrayicon.cpp b/tests/auto/widgets/util/qsystemtrayicon/tst_qsystemtrayicon.cpp index 7ea63911ae16fce78f8adf249744ff5df80a8130..05511a17a15dc56f273b33f471be59f350f17c4e 100644 --- a/tests/auto/widgets/util/qsystemtrayicon/tst_qsystemtrayicon.cpp +++ b/tests/auto/widgets/util/qsystemtrayicon/tst_qsystemtrayicon.cpp @@ -136,7 +136,7 @@ void tst_QSystemTrayIcon::lastWindowClosed() QTimer::singleShot(2500, &window, SLOT(close())); QTimer::singleShot(20000, qApp, SLOT(quit())); // in case the test fails qApp->exec(); - QVERIFY(spy.count() == 1); + QCOMPARE(spy.count(), 1); } QTEST_MAIN(tst_QSystemTrayIcon) diff --git a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp index a633ba0cf01d8241f8f915ac6a0b7cc013e8067a..43d6912c6e345b09e98e2e9b4f845b08db72b68f 100644 --- a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp +++ b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp @@ -283,9 +283,9 @@ void tst_QAbstractButton::setAutoRepeat() QTest::qWait(REPEAT_DELAY); QVERIFY(testWidget->isDown()); QTest::keyRelease(testWidget, Qt::Key_Space); - QVERIFY(release_count == press_count); - QVERIFY(toggle_count == 0); - QVERIFY(press_count == click_count); + QCOMPARE(release_count, press_count); + QCOMPARE(toggle_count, uint(0)); + QCOMPARE(press_count, click_count); QVERIFY(click_count > 1); break; case 4: diff --git a/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp b/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp index df69063540450a6340f9f9614a2f07e95ee37270..5dec6224ca2bfcaba5cc4201df2232beaff70fab 100644 --- a/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp +++ b/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp @@ -324,13 +324,13 @@ void tst_QButtonGroup::testSignals() int expectedId = -2; - QVERIFY(clickedIdSpy.takeFirst().at(0).toInt() == expectedId); + QCOMPARE(clickedIdSpy.takeFirst().at(0).toInt(), expectedId); QCOMPARE(pressedSpy.count(), 1); QCOMPARE(pressedIdSpy.count(), 1); - QVERIFY(pressedIdSpy.takeFirst().at(0).toInt() == expectedId); + QCOMPARE(pressedIdSpy.takeFirst().at(0).toInt(), expectedId); QCOMPARE(releasedSpy.count(), 1); QCOMPARE(releasedIdSpy.count(), 1); - QVERIFY(releasedIdSpy.takeFirst().at(0).toInt() == expectedId); + QCOMPARE(releasedIdSpy.takeFirst().at(0).toInt(), expectedId); clickedSpy.clear(); clickedIdSpy.clear(); @@ -344,13 +344,13 @@ void tst_QButtonGroup::testSignals() QCOMPARE(clickedSpy.count(), 1); QCOMPARE(clickedIdSpy.count(), 1); - QVERIFY(clickedIdSpy.takeFirst().at(0).toInt() == 23); + QCOMPARE(clickedIdSpy.takeFirst().at(0).toInt(), 23); QCOMPARE(pressedSpy.count(), 1); QCOMPARE(pressedIdSpy.count(), 1); - QVERIFY(pressedIdSpy.takeFirst().at(0).toInt() == 23); + QCOMPARE(pressedIdSpy.takeFirst().at(0).toInt(), 23); QCOMPARE(releasedSpy.count(), 1); QCOMPARE(releasedIdSpy.count(), 1); - QVERIFY(releasedIdSpy.takeFirst().at(0).toInt() == 23); + QCOMPARE(releasedIdSpy.takeFirst().at(0).toInt(), 23); QSignalSpy toggledSpy(&buttons, SIGNAL(buttonToggled(QAbstractButton*, bool))); @@ -427,25 +427,25 @@ void tst_QButtonGroup::checkedButton() buttons.addButton(&pb1); buttons.addButton(&pb2, 23); - QVERIFY(buttons.checkedButton() == 0); + QVERIFY(!buttons.checkedButton()); pb1.setChecked(true); - QVERIFY(buttons.checkedButton() == &pb1); + QCOMPARE(buttons.checkedButton(), &pb1); pb2.setChecked(true); - QVERIFY(buttons.checkedButton() == &pb2); + QCOMPARE(buttons.checkedButton(), &pb2); pb2.setChecked(false); - QVERIFY(buttons.checkedButton() == &pb1); + QCOMPARE(buttons.checkedButton(), &pb1); pb1.setChecked(false); - QVERIFY(buttons.checkedButton() == 0); + QVERIFY(!buttons.checkedButton()); buttons.setExclusive(true); - QVERIFY(buttons.checkedButton() == 0); + QVERIFY(!buttons.checkedButton()); pb1.setChecked(true); - QVERIFY(buttons.checkedButton() == &pb1); + QCOMPARE(buttons.checkedButton(), &pb1); pb2.setChecked(true); - QVERIFY(buttons.checkedButton() == &pb2); + QCOMPARE(buttons.checkedButton(), &pb2); // checked button cannot be unchecked pb2.setChecked(false); - QVERIFY(buttons.checkedButton() == &pb2); + QCOMPARE(buttons.checkedButton(), &pb2); } class task209485_ButtonDeleter : public QObject @@ -523,9 +523,9 @@ void tst_QButtonGroup::autoIncrementId() radio1->setChecked(true); - QVERIFY(buttons->id(radio1) == -2); - QVERIFY(buttons->id(radio2) == -3); - QVERIFY(buttons->id(radio3) == -4); + QCOMPARE(buttons->id(radio1), -2); + QCOMPARE(buttons->id(radio2), -3); + QCOMPARE(buttons->id(radio3), -4); dlg.show(); } diff --git a/tests/auto/widgets/widgets/qcheckbox/tst_qcheckbox.cpp b/tests/auto/widgets/widgets/qcheckbox/tst_qcheckbox.cpp index e76e11fc676fa59014900defd68856d1709b7819..5696382fabab05fe59b2c0b2480aadf6df2d744b 100644 --- a/tests/auto/widgets/widgets/qcheckbox/tst_qcheckbox.cpp +++ b/tests/auto/widgets/widgets/qcheckbox/tst_qcheckbox.cpp @@ -83,9 +83,7 @@ private: uint press_count; uint release_count; int cur_state; - uint tmp; QCheckBox *testWidget; - uint tmp2; }; tst_QCheckBox::tst_QCheckBox() @@ -326,7 +324,7 @@ void tst_QCheckBox::isToggleButton() void tst_QCheckBox::foregroundRole() { - QVERIFY(testWidget->foregroundRole() == QPalette::WindowText); + QCOMPARE(testWidget->foregroundRole(), QPalette::WindowText); } void tst_QCheckBox::minimumSizeHint() diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index c409698ec02f102c9e9ccc3ef2689415aebea8d9..fdc5bdd9152f22e218c284f22f298511f0cbc451 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -164,6 +164,7 @@ private slots: void keyboardSelection(); void setCustomModelAndView(); void updateDelegateOnEditableChange(); + void respectChangedOwnershipOfItemView(); }; class MyAbstractItemDelegate : public QAbstractItemDelegate @@ -452,7 +453,7 @@ void tst_QComboBox::setPalette() for (int i = 0; i < comboChildren.size(); ++i) { QObject *o = comboChildren.at(i); if (o->isWidgetType()) { - QVERIFY(((QWidget*)o)->palette() == pal); + QCOMPARE(((QWidget*)o)->palette(), pal); } } @@ -461,12 +462,12 @@ void tst_QComboBox::setPalette() //Setting it on the lineedit should be separate form the combo testWidget->lineEdit()->setPalette(pal); QVERIFY(testWidget->palette() != pal); - QVERIFY(testWidget->lineEdit()->palette() == pal); + QCOMPARE(testWidget->lineEdit()->palette(), pal); pal.setColor(QPalette::Base, Qt::green); //Setting it on the combo directly should override lineedit testWidget->setPalette(pal); - QVERIFY(testWidget->palette() == pal); - QVERIFY(testWidget->lineEdit()->palette() == pal); + QCOMPARE(testWidget->palette(), pal); + QCOMPARE(testWidget->lineEdit()->palette(), pal); } void tst_QComboBox::sizeAdjustPolicy() @@ -477,7 +478,7 @@ void tst_QComboBox::sizeAdjustPolicy() QComboBox *testWidget = topLevel.comboBox(); // test that adding new items will not change the sizehint for AdjustToContentsOnFirstShow QVERIFY(!testWidget->count()); - QVERIFY(testWidget->sizeAdjustPolicy() == QComboBox::AdjustToContentsOnFirstShow); + QCOMPARE(testWidget->sizeAdjustPolicy(), QComboBox::AdjustToContentsOnFirstShow); QVERIFY(testWidget->isVisible()); QSize firstShow = testWidget->sizeHint(); testWidget->addItem("normal item"); @@ -750,7 +751,7 @@ void tst_QComboBox::insertPolicy() // First check that there is the right number of entries, or // we may unwittingly pass - QVERIFY((int)result.count() == testWidget->count()); + QCOMPARE((int)result.count(), testWidget->count()); // No need to compare if there are no strings to compare if (result.count() > 0) { @@ -795,7 +796,7 @@ void tst_QComboBox::virtualAutocompletion() QApplication::sendEvent(testWidget, &kr1); qApp->processEvents(); // Process events to trigger autocompletion - QTRY_VERIFY(testWidget->currentIndex() == 1); + QTRY_COMPARE(testWidget->currentIndex(), 1); QKeyEvent kp2(QEvent::KeyPress, Qt::Key_O, 0, "o"); QKeyEvent kr2(QEvent::KeyRelease, Qt::Key_O, 0, "o"); @@ -844,7 +845,7 @@ void tst_QComboBox::autoCompletionCaseSensitivity() testWidget->clearEditText(); QSignalSpy spyReturn(testWidget, SIGNAL(activated(int))); testWidget->setAutoCompletionCaseSensitivity(Qt::CaseInsensitive); - QVERIFY(testWidget->autoCompletionCaseSensitivity() == Qt::CaseInsensitive); + QCOMPARE(testWidget->autoCompletionCaseSensitivity(), Qt::CaseInsensitive); QTest::keyClick(testWidget->lineEdit(), Qt::Key_A); qApp->processEvents(); @@ -878,7 +879,7 @@ void tst_QComboBox::autoCompletionCaseSensitivity() // case sensitive testWidget->clearEditText(); testWidget->setAutoCompletionCaseSensitivity(Qt::CaseSensitive); - QVERIFY(testWidget->autoCompletionCaseSensitivity() == Qt::CaseSensitive); + QCOMPARE(testWidget->autoCompletionCaseSensitivity(), Qt::CaseSensitive); QTest::keyClick(testWidget->lineEdit(), Qt::Key_A); qApp->processEvents(); QCOMPARE(testWidget->currentText(), QString("aww")); @@ -1376,7 +1377,7 @@ void tst_QComboBox::textpixmapdata() QCOMPARE(icon.cacheKey(), icons.at(i).cacheKey()); QPixmap original = icons.at(i).pixmap(1024); QPixmap pixmap = icon.pixmap(1024); - QVERIFY(pixmap.toImage() == original.toImage()); + QCOMPARE(pixmap.toImage(), original.toImage()); } for (int i = 0; i<text.count(); ++i) { @@ -1610,7 +1611,7 @@ void tst_QComboBox::setModel() QCOMPARE(box.currentIndex(), 0); QVERIFY(box.model() != oldModel); QVERIFY(box.rootModelIndex() != rootModelIndex); - QVERIFY(box.rootModelIndex() == QModelIndex()); + QCOMPARE(box.rootModelIndex(), QModelIndex()); // check that setting the very same model doesn't move the current item box.setCurrentIndex(1); @@ -3169,5 +3170,27 @@ void tst_QComboBox::updateDelegateOnEditableChange() } } +void tst_QComboBox::respectChangedOwnershipOfItemView() +{ + QComboBox box1; + QComboBox box2; + QTableView *v1 = new QTableView; + box1.setView(v1); + + QSignalSpy spy1(v1, SIGNAL(destroyed())); + box2.setView(v1); // Ownership should now be transferred to box2 + + + QTableView *v2 = new QTableView(&box1); + box1.setView(v2); // Here we do not expect v1 to be deleted + QApplication::processEvents(); + QCOMPARE(spy1.count(), 0); + + QSignalSpy spy2(v2, SIGNAL(destroyed())); + box1.setView(v1); + QCOMPARE(spy2.count(), 1); +} + + QTEST_MAIN(tst_QComboBox) #include "tst_qcombobox.moc" diff --git a/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp b/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp index d8cb7c01ad05d186a6e806f2a0448348c82ee3ce..a57553097ac3cb9289b81e5b7efd26cd14df47cf 100644 --- a/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp +++ b/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp @@ -98,11 +98,11 @@ void tst_QCommandLinkButton::getSetCheck() QString text("mytext"); QVERIFY(obj1.description().isEmpty()); obj1.setDescription(text); - QVERIFY(obj1.description() == text); + QCOMPARE(obj1.description(), text); QVERIFY(obj1.text().isEmpty()); obj1.setText(text); - QVERIFY(obj1.text() == text); + QCOMPARE(obj1.text(), text); QMenu *var1 = new QMenu; obj1.setMenu(var1); @@ -236,8 +236,8 @@ void tst_QCommandLinkButton::setAutoRepeat() QVERIFY( testWidget->isDown() ); QVERIFY( toggle_count == 0 ); QTest::keyRelease( testWidget, Qt::Key_Space ); - QVERIFY(press_count == release_count); - QVERIFY(release_count == click_count); + QCOMPARE(press_count, release_count); + QCOMPARE(release_count, click_count); QVERIFY(press_count > 1); // #### shouldn't I check here to see if multiple signals have been fired??? diff --git a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp index c9ae60dd76716d8ee07ed546ed9d9a9812e9455b..e8a0916dc58f69e1f904acc6a63981f568e5ab1e 100644 --- a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp +++ b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp @@ -2416,7 +2416,7 @@ void tst_QDateTimeEdit::displayedSections() QFETCH(uint, section); testWidget->setDisplayFormat(format); - QVERIFY((QDateTimeEdit::Section)section == testWidget->displayedSections()); + QCOMPARE(QDateTimeEdit::Sections(section), testWidget->displayedSections()); } void tst_QDateTimeEdit::currentSection_data() @@ -2460,7 +2460,7 @@ void tst_QDateTimeEdit::currentSection() if ((QDateTimeEdit::Section)section == QDateTimeEdit::NoSection) testWidget->setCurrentSection(QDateTimeEdit::YearSection); // Ensure it's not reset (see above) testWidget->setCurrentSection((QDateTimeEdit::Section)section); - QVERIFY((QDateTimeEdit::Section)currentSection == testWidget->currentSection()); + QCOMPARE((QDateTimeEdit::Section)currentSection, testWidget->currentSection()); } void tst_QDateTimeEdit::readOnly() @@ -2825,7 +2825,7 @@ void tst_QDateTimeEdit::calendarPopup() rect = style->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxArrow, &timeEdit); QTest::mouseClick(&timeEdit, Qt::LeftButton, 0, QPoint(rect.left()+rect.width()/2, rect.top()+rect.height()/2)); QWidget *wid2 = timeEdit.findChild<QWidget *>("qt_datetimedit_calendar"); - QVERIFY(wid2 == 0); + QVERIFY(!wid2); timeEdit.hide(); @@ -2839,7 +2839,7 @@ void tst_QDateTimeEdit::calendarPopup() rect = style->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxArrow, &dateEdit); QTest::mouseClick(&dateEdit, Qt::LeftButton, 0, QPoint(rect.left()+rect.width()/2, rect.top()+rect.height()/2)); QWidget *wid3 = dateEdit.findChild<QWidget *>("qt_datetimedit_calendar"); - QVERIFY(wid3 == 0); + QVERIFY(!wid3); dateEdit.hide(); } diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp index 38b473e5aed514c8788d4d36612ebc659a601b7f..32412afcd5196b6254ac836d185ef07c04e93fa4 100644 --- a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp +++ b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp @@ -132,12 +132,12 @@ void tst_QDialogButtonBox::layoutReuse() QDialogButtonBox *box = new QDialogButtonBox(QDialogButtonBox::Ok); QPointer<QLayout> layout = box->layout(); box->setCenterButtons(!box->centerButtons()); - QVERIFY(layout == box->layout()); + QCOMPARE(layout.data(), box->layout()); QEvent event(QEvent::StyleChange); QApplication::sendEvent(box, &event); - QVERIFY(layout == box->layout()); + QCOMPARE(layout.data(), box->layout()); box->setOrientation(box->orientation() == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal); - QVERIFY(layout == 0); + QVERIFY(layout.isNull()); QVERIFY(layout != box->layout()); delete box; } diff --git a/tests/auto/widgets/widgets/qdockwidget/BLACKLIST b/tests/auto/widgets/widgets/qdockwidget/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..60adfb9f4bb598b57e78e0630c10b5d9610280b2 --- /dev/null +++ b/tests/auto/widgets/widgets/qdockwidget/BLACKLIST @@ -0,0 +1,2 @@ +[restoreDockWidget] +ubuntu-14.04 diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp index 2bbc2e05b733dbf28718ac56080fcb55cdfbd50a..82832bced1991edbe3f281fb0bd83abd7e72f930 100644 --- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp @@ -120,7 +120,7 @@ void tst_QDockWidget::widget() { { QDockWidget dw; - QVERIFY(dw.widget() == 0); + QVERIFY(!dw.widget()); } { @@ -130,32 +130,32 @@ void tst_QDockWidget::widget() dw.setWidget(w1); QVERIFY(dw.widget() != 0); - QVERIFY(dw.widget() == w1); + QCOMPARE(dw.widget(), w1); QCOMPARE(w1->parentWidget(), (QWidget*)&dw); dw.setWidget(0); - QVERIFY(dw.widget() == 0); + QVERIFY(!dw.widget()); dw.setWidget(w2); QVERIFY(dw.widget() != 0); - QVERIFY(dw.widget() == w2); + QCOMPARE(dw.widget(), w2); QCOMPARE(w2->parentWidget(), (QWidget*)&dw); dw.setWidget(0); - QVERIFY(dw.widget() == 0); + QVERIFY(!dw.widget()); dw.setWidget(w1); QVERIFY(dw.widget() != 0); - QVERIFY(dw.widget() == w1); + QCOMPARE(dw.widget(), w1); QCOMPARE(w1->parentWidget(), (QWidget*)&dw); dw.setWidget(w2); QVERIFY(dw.widget() != 0); - QVERIFY(dw.widget() == w2); + QCOMPARE(dw.widget(), w2); QCOMPARE(w2->parentWidget(), (QWidget*)&dw); dw.setWidget(0); - QVERIFY(dw.widget() == 0); + QVERIFY(!dw.widget()); } { @@ -165,37 +165,37 @@ void tst_QDockWidget::widget() dw.setWidget(w1); QVERIFY(dw.widget() != 0); - QVERIFY(dw.widget() == w1); + QCOMPARE(dw.widget(), w1); QCOMPARE(w1->parentWidget(), (QWidget*)&dw); w1->setParent(0); - QVERIFY(dw.widget() == 0); + QVERIFY(!dw.widget()); dw.setWidget(w2); QVERIFY(dw.widget() != 0); - QVERIFY(dw.widget() == w2); + QCOMPARE(dw.widget(), w2); QCOMPARE(w2->parentWidget(), (QWidget*)&dw); w2->setParent(0); - QVERIFY(dw.widget() == 0); + QVERIFY(!dw.widget()); dw.setWidget(w1); QVERIFY(dw.widget() != 0); - QVERIFY(dw.widget() == w1); + QCOMPARE(dw.widget(), w1); QCOMPARE(w1->parentWidget(), (QWidget*)&dw); dw.setWidget(w2); QVERIFY(dw.widget() != 0); - QVERIFY(dw.widget() == w2); + QCOMPARE(dw.widget(), w2); QCOMPARE(w2->parentWidget(), (QWidget*)&dw); w1->setParent(0); QVERIFY(dw.widget() != 0); - QVERIFY(dw.widget() == w2); + QCOMPARE(dw.widget(), w2); QCOMPARE(w2->parentWidget(), (QWidget*)&dw); w2->setParent(0); - QVERIFY(dw.widget() == 0); + QVERIFY(!dw.widget()); delete w1; delete w2; } diff --git a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp index 619c62d7c0e8165e1f10e4781b87e2b10bb4e053..789a280e805a2a01c1897db7486c254bfce3f5d9 100644 --- a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp +++ b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp @@ -111,7 +111,6 @@ private: QLabel *testWidget; QPointer<Widget> test_box; QPointer<QLabel> test_label; - QLineEdit *test_edit; }; // Testing get/set functions @@ -187,7 +186,7 @@ void tst_QLabel::cleanup() } } -// Set buddy doesn't make much sense on Mac OS X +// Set buddy doesn't make much sense on OS X #ifndef Q_OS_MAC void tst_QLabel::setBuddy() { @@ -196,7 +195,7 @@ void tst_QLabel::setBuddy() test_box = new Widget; test_label= new QLabel( test_box ); test_label->setText( "&Test with a buddy" ); - test_edit = new QLineEdit( test_box ); + QWidget *test_edit = new QLineEdit( test_box ); QVBoxLayout *layout = new QVBoxLayout(test_box); layout->addWidget(test_label); layout->addWidget(test_edit); @@ -322,7 +321,7 @@ void tst_QLabel::eventPropagation() test_label->setText(text); test_box->events.clear(); test_label->setTextInteractionFlags(Qt::TextInteractionFlags(textInteractionFlags)); - QVERIFY(int(test_label->focusPolicy()) == focusPolicy); + QCOMPARE(int(test_label->focusPolicy()), focusPolicy); QTest::mousePress(test_label, Qt::LeftButton); QVERIFY(test_box->events.contains(QEvent::MouseButtonPress) == propagation); // should have propagated! } diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index adedc601a96588dbee9048b2d33a05b7cfb847c2..5c8f6eeeb8425c5ba4672f01fe169278171fd7a8 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -1668,7 +1668,7 @@ void tst_QLineEdit::displayText() testWidget->setEchoMode(mode); testWidget->setText(insertString); QCOMPARE(testWidget->displayText(), expectedString); - QVERIFY(testWidget->echoMode() == mode); + QCOMPARE(testWidget->echoMode(), mode); } void tst_QLineEdit::passwordEchoOnEdit() @@ -1838,9 +1838,9 @@ void tst_QLineEdit::maxLength() // Make sure that the textChanged is not emitted unless the text is actually changed if (insertString == expectedString) { - QVERIFY(changed_count == 0); + QCOMPARE(changed_count, 0); } else { - QVERIFY(changed_count == 1); + QCOMPARE(changed_count, 1); } } @@ -1961,7 +1961,7 @@ void tst_QLineEdit::psKeyClick(QTestEventList &keys, Qt::Key key, Qt::KeyboardMo void tst_QLineEdit::cursorPosition() { QLineEdit *testWidget = ensureTestWidget(); - QVERIFY(testWidget->cursorPosition() == 0); + QCOMPARE(testWidget->cursorPosition(), 0); // start with a basic text QTest::keyClicks(testWidget, "The"); @@ -2207,7 +2207,7 @@ void tst_QLineEdit::selectedText() testWidget->cursorForward(true, 9); QVERIFY(testWidget->hasSelectedText()); QCOMPARE(testWidget->selectedText(), QString("Abc defg ")); - QVERIFY(selection_count == 1); + QCOMPARE(selection_count, 1); // reset selection testWidget->home(false); @@ -2263,19 +2263,19 @@ void tst_QLineEdit::textChangedAndTextEdited() QLineEdit *testWidget = ensureTestWidget(); QTest::keyClick(testWidget, Qt::Key_A); QCOMPARE(changed_count, 1); - QVERIFY(edited_count == changed_count); + QCOMPARE(edited_count, changed_count); QTest::keyClick(testWidget, 'b'); QCOMPARE(changed_count, 2); - QVERIFY(edited_count == changed_count); + QCOMPARE(edited_count, changed_count); QTest::keyClick(testWidget, 'c'); QCOMPARE(changed_count, 3); - QVERIFY(edited_count == changed_count); + QCOMPARE(edited_count, changed_count); QTest::keyClick(testWidget, ' '); QCOMPARE(changed_count, 4); - QVERIFY(edited_count == changed_count); + QCOMPARE(edited_count, changed_count); QTest::keyClick(testWidget, 'd'); QCOMPARE(changed_count, 5); - QVERIFY(edited_count == changed_count); + QCOMPARE(edited_count, changed_count); changed_count = 0; edited_count = 0; @@ -2321,27 +2321,27 @@ void tst_QLineEdit::returnPressed() QLineEdit *testWidget = ensureTestWidget(); QTest::keyClick(testWidget, Qt::Key_Return); - QVERIFY(return_count == 1); + QCOMPARE(return_count, 1); return_count = 0; QTest::keyClick(testWidget, 'A'); - QVERIFY(return_count == 0); + QCOMPARE(return_count, 0); QTest::keyClick(testWidget, 'b'); - QVERIFY(return_count == 0); + QCOMPARE(return_count, 0); QTest::keyClick(testWidget, 'c'); - QVERIFY(return_count == 0); + QCOMPARE(return_count, 0); QTest::keyClick(testWidget, ' '); - QVERIFY(return_count == 0); + QCOMPARE(return_count, 0); QTest::keyClick(testWidget, 'd'); - QVERIFY(return_count == 0); + QCOMPARE(return_count, 0); psKeyClick(testWidget, Qt::Key_Home); - QVERIFY(return_count == 0); + QCOMPARE(return_count, 0); psKeyClick(testWidget, Qt::Key_End); - QVERIFY(return_count == 0); + QCOMPARE(return_count, 0); QTest::keyClick(testWidget, Qt::Key_Escape); - QVERIFY(return_count == 0); + QCOMPARE(return_count, 0); QTest::keyClick(testWidget, Qt::Key_Return); - QVERIFY(return_count == 1); + QCOMPARE(return_count, 1); } // int validator that fixes all !isNumber to '0' @@ -2497,14 +2497,14 @@ void tst_QLineEdit::setValidator() QCOMPARE(testWidget->validator(), static_cast<const QValidator*>(&iv1)); testWidget->setValidator(0); - QVERIFY(testWidget->validator() == 0); + QVERIFY(!testWidget->validator()); QIntValidator iv2(0, 99, 0); testWidget->setValidator(&iv2); QCOMPARE(testWidget->validator(), static_cast<const QValidator *>(&iv2)); testWidget->setValidator(0); - QVERIFY(testWidget->validator() == 0); + QVERIFY(!testWidget->validator()); } void tst_QLineEdit::setValidator_QIntValidator_data() @@ -2746,7 +2746,7 @@ void tst_QLineEdit::setAlignment() QTEST(testWidget, "left"); #endif #endif - QVERIFY(testWidget->alignment() == Qt::AlignLeft); + QCOMPARE(testWidget->alignment(), Qt::AlignLeft); testWidget->setText("hcenter"); testWidget->setAlignment(Qt::AlignHCenter); @@ -2755,7 +2755,7 @@ void tst_QLineEdit::setAlignment() QTEST(testWidget, "hcenter"); #endif #endif - QVERIFY(testWidget->alignment() == Qt::AlignHCenter); + QCOMPARE(testWidget->alignment(), Qt::AlignHCenter); testWidget->setText("right"); testWidget->setAlignment(Qt::AlignRight); @@ -2764,16 +2764,16 @@ void tst_QLineEdit::setAlignment() QTEST(testWidget, "right"); #endif #endif - QVERIFY(testWidget->alignment() == Qt::AlignRight); + QCOMPARE(testWidget->alignment(), Qt::AlignRight); testWidget->setAlignment(Qt::AlignTop); - QVERIFY(testWidget->alignment() == Qt::AlignTop); + QCOMPARE(testWidget->alignment(), Qt::AlignTop); testWidget->setAlignment(Qt::AlignBottom); - QVERIFY(testWidget->alignment() == Qt::AlignBottom); + QCOMPARE(testWidget->alignment(), Qt::AlignBottom); testWidget->setAlignment(Qt::AlignCenter); - QVERIFY(testWidget->alignment() == Qt::AlignCenter); + QCOMPARE(testWidget->alignment(), Qt::AlignCenter); } void tst_QLineEdit::isModified() @@ -3081,10 +3081,10 @@ void tst_QLineEdit::maxLengthAndInputMask() QLineEdit *testWidget = ensureTestWidget(); QVERIFY(testWidget->inputMask().isNull()); testWidget->setMaxLength(10); - QVERIFY(testWidget->maxLength() == 10); + QCOMPARE(testWidget->maxLength(), 10); testWidget->setInputMask(QString::null); QVERIFY(testWidget->inputMask().isNull()); - QVERIFY(testWidget->maxLength() == 10); + QCOMPARE(testWidget->maxLength(), 10); } @@ -4415,7 +4415,7 @@ void tst_QLineEdit::QTBUG1266_setInputMaskEmittingTextEdited() QSignalSpy spy(&lineEdit, SIGNAL(textEdited(QString))); lineEdit.setInputMask("AAAA"); lineEdit.setInputMask(QString()); - QVERIFY(spy.count() == 0); + QCOMPARE(spy.count(), 0); } QTEST_MAIN(tst_QLineEdit) diff --git a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp index 270e5168f71176b4b1cb13d2d3b1e123cba658d9..e8c533f301e65e50faea298dceccdddb5df7e547 100644 --- a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp +++ b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp @@ -211,15 +211,15 @@ tst_QMainWindow::tst_QMainWindow() void tst_QMainWindow::constructor() { QMainWindow mw; - QVERIFY(mw.parentWidget() == 0); + QVERIFY(!mw.parentWidget()); QVERIFY(mw.isWindow()); QMainWindow mw2(&mw); - QVERIFY(mw2.parentWidget() == &mw); + QCOMPARE(mw2.parentWidget(), &mw); QVERIFY(mw2.isWindow()); QMainWindow mw3(&mw, Qt::FramelessWindowHint); - QVERIFY(mw3.parentWidget() == &mw); + QCOMPARE(mw3.parentWidget(), &mw); QVERIFY(mw3.isWindow()); } @@ -607,7 +607,7 @@ void tst_QMainWindow::menuBar() QVERIFY(mw.menuBar() != 0); //we now call deleteLater on the previous menubar QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(mb1 == 0); + QVERIFY(mb1.isNull()); mw.setMenuBar(mb2); QVERIFY(mw.menuBar() != 0); @@ -618,7 +618,7 @@ void tst_QMainWindow::menuBar() QVERIFY(mw.menuBar() != 0); //we now call deleteLater on the previous menubar QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(mb2 == 0); + QVERIFY(mb2.isNull()); mb1 = new QMenuBar; mw.setMenuBar(mb1); @@ -631,7 +631,7 @@ void tst_QMainWindow::menuBar() QCOMPARE(mw.menuBar(), (QMenuBar *)mb2); //we now call deleteLater on the previous menubar QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(mb1 == 0); + QVERIFY(mb1.isNull()); mb1 = new QMenuBar; mw.setMenuBar(mb1); @@ -639,7 +639,7 @@ void tst_QMainWindow::menuBar() QCOMPARE(mw.menuBar(), (QMenuBar *)mb1); //we now call deleteLater on the previous menubar QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(mb2 == 0); + QVERIFY(mb2.isNull()); QPointer<QWidget> topLeftCornerWidget = new QWidget; mb1->setCornerWidget(topLeftCornerWidget, Qt::TopLeftCorner); @@ -652,7 +652,7 @@ void tst_QMainWindow::menuBar() QCOMPARE(mw.menuBar(), (QMenuBar *)mb2); //we now call deleteLater on the previous menubar QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(mb1 == 0); + QVERIFY(mb1.isNull()); QVERIFY(topLeftCornerWidget); QCOMPARE(mb2->cornerWidget(Qt::TopLeftCorner), static_cast<QWidget *>(topLeftCornerWidget)); @@ -663,8 +663,8 @@ void tst_QMainWindow::menuBar() QVERIFY(mw.menuBar() != 0); //we now call deleteLater on the previous menubar QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(mb2 == 0); + QVERIFY(mb2.isNull()); QVERIFY(!topLeftCornerWidget); QVERIFY(!topRightCornerWidget); } @@ -692,7 +692,7 @@ void tst_QMainWindow::statusBar() QVERIFY(mw.statusBar() != 0); //we now call deleteLater on the previous statusbar QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(sb1 == 0); + QVERIFY(sb1.isNull()); mw.setStatusBar(sb2); QVERIFY(mw.statusBar() != 0); @@ -703,7 +703,7 @@ void tst_QMainWindow::statusBar() QVERIFY(mw.statusBar() != 0); //we now call deleteLater on the previous statusbar QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(sb2 == 0); + QVERIFY(sb2.isNull()); sb1 = new QStatusBar; mw.setStatusBar(sb1); @@ -718,7 +718,7 @@ void tst_QMainWindow::statusBar() QCOMPARE(sb2->parentWidget(), (QWidget *)&mw); //we now call deleteLater on the previous statusbar QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(sb1 == 0); + QVERIFY(sb1.isNull()); sb1 = new QStatusBar; mw.setStatusBar(sb1); @@ -727,7 +727,7 @@ void tst_QMainWindow::statusBar() QCOMPARE(sb1->parentWidget(), (QWidget *)&mw); //we now call deleteLater on the previous statusbar QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(sb2 == 0); + QVERIFY(sb2.isNull()); sb2 = new QStatusBar; mw.setStatusBar(sb2); @@ -736,7 +736,7 @@ void tst_QMainWindow::statusBar() QCOMPARE(sb2->parentWidget(), (QWidget *)&mw); //we now call deleteLater on the previous statusbar QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(sb1 == 0); + QVERIFY(sb1.isNull()); } { @@ -749,7 +749,7 @@ void tst_QMainWindow::statusBar() QVERIFY(indexOfSb != -1); delete sb; indexOfSb = l->indexOf(sb); - QVERIFY(indexOfSb == -1); + QCOMPARE(indexOfSb, -1); } } @@ -791,7 +791,7 @@ void tst_QMainWindow::centralWidget() { { QMainWindow mw; - QVERIFY(mw.centralWidget() == 0); + QVERIFY(!mw.centralWidget()); } { @@ -799,7 +799,7 @@ void tst_QMainWindow::centralWidget() QPointer<QWidget> w1 = new QWidget; QPointer<QWidget> w2 = new QWidget; - QVERIFY(mw.centralWidget() == 0); + QVERIFY(!mw.centralWidget()); mw.setCentralWidget(w1); QVERIFY(mw.centralWidget() != 0); @@ -812,12 +812,12 @@ void tst_QMainWindow::centralWidget() QCOMPARE(w2->parentWidget(), (QWidget *)&mw); mw.setCentralWidget(0); - QVERIFY(mw.centralWidget() == 0); + QVERIFY(!mw.centralWidget()); //we now call deleteLater on the previous central widgets QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(w1 == 0); - QVERIFY(w2 == 0); + QVERIFY(w1.isNull()); + QVERIFY(w2.isNull()); } { @@ -831,7 +831,7 @@ void tst_QMainWindow::centralWidget() QPointer<QWidget> w1 = new QWidget; QPointer<QWidget> w2 = new QWidget; - QVERIFY(mw.centralWidget() == 0); + QVERIFY(!mw.centralWidget()); mw.setCentralWidget(w1); QVERIFY(mw.centralWidget() != 0); @@ -844,12 +844,12 @@ void tst_QMainWindow::centralWidget() QCOMPARE(w2->parentWidget(), (QWidget *)&mw); mw.setCentralWidget(0); - QVERIFY(mw.centralWidget() == 0); + QVERIFY(!mw.centralWidget()); //we now call deleteLater on the previous central widgets QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(w1 == 0); - QVERIFY(w2 == 0); + QVERIFY(w1.isNull()); + QVERIFY(w2.isNull()); } } @@ -860,25 +860,25 @@ void tst_QMainWindow::takeCentralWidget() { QPointer<QWidget> w1 = new QWidget; - QVERIFY(mw.centralWidget() == 0); + QVERIFY(!mw.centralWidget()); mw.setCentralWidget(w1); QWidget *oldCentralWidget = mw.takeCentralWidget(); - QVERIFY(oldCentralWidget == w1.data()); + QCOMPARE(oldCentralWidget, w1.data()); // ensure that takeCentralWidget doesn't end up calling deleteLater // on the central widget QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(mw.centralWidget() == 0); + QVERIFY(!mw.centralWidget()); QVERIFY(!w1.isNull()); - QVERIFY(w1->parent() == 0); + QVERIFY(!w1->parent()); mw.setCentralWidget(w1); // ensure that the deleteLater called by setCentralWidget // gets executed QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(mw.centralWidget() == w1.data()); + QCOMPARE(mw.centralWidget(), w1.data()); QPointer<QWidget> w2 = new QWidget; @@ -887,10 +887,10 @@ void tst_QMainWindow::takeCentralWidget() { QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); QVERIFY(w1.isNull()); - QVERIFY(mw.centralWidget() == w2.data()); + QCOMPARE(mw.centralWidget(), w2.data()); QWidget *hopefullyW2 = mw.takeCentralWidget(); - QVERIFY(mw.centralWidget() == 0); + QVERIFY(!mw.centralWidget()); // ensure that takeCentralWidget doesn't end up calling deleteLater // on the central widget QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); @@ -1928,9 +1928,9 @@ void tst_QMainWindow::toggleUnifiedTitleAndToolBarOnMac() mw.show(); QRect frameGeometry = mw.frameGeometry(); mw.setUnifiedTitleAndToolBarOnMac(false); - QVERIFY(frameGeometry.topLeft() == mw.frameGeometry().topLeft()); + QCOMPARE(frameGeometry.topLeft(), mw.frameGeometry().topLeft()); mw.setUnifiedTitleAndToolBarOnMac(true); - QVERIFY(frameGeometry.topLeft() == mw.frameGeometry().topLeft()); + QCOMPARE(frameGeometry.topLeft(), mw.frameGeometry().topLeft()); } #endif diff --git a/tests/auto/widgets/widgets/qmdiarea/BLACKLIST b/tests/auto/widgets/widgets/qmdiarea/BLACKLIST index b8640e9ac3909cc46e5f784f23e2f10b30ea784d..63da2e3ae38c36aa1aa3bd4a544981a5b034a26e 100644 --- a/tests/auto/widgets/widgets/qmdiarea/BLACKLIST +++ b/tests/auto/widgets/widgets/qmdiarea/BLACKLIST @@ -1,2 +1,5 @@ [updateScrollBars] osx +[tileSubWindows] +osx +xcb diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index 53defce4230417400383a1ee022cc6704d33e979..e7de027b2287bd6354e12530eee13c42c69b382c 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -377,13 +377,13 @@ void tst_QMdiArea::subWindowActivated() while (workspace->activeSubWindow() ) { workspace->activeSubWindow()->close(); qApp->processEvents(); - QVERIFY(activeWindow == workspace->activeSubWindow()); + QCOMPARE(activeWindow, workspace->activeSubWindow()); QCOMPARE(spy.count(), 1); spy.clear(); } - QVERIFY(activeWindow == 0); - QVERIFY(workspace->activeSubWindow() == 0); + QVERIFY(!activeWindow); + QVERIFY(!workspace->activeSubWindow()); QCOMPARE(workspace->subWindowList().count(), 0); { @@ -432,13 +432,13 @@ void tst_QMdiArea::subWindowActivated() QCOMPARE(spy.count(), 1); spy.clear(); QVERIFY( activeWindow == window ); - QVERIFY(workspace->activeSubWindow() == window); + QCOMPARE(workspace->activeSubWindow(), window); window->close(); qApp->processEvents(); QCOMPARE(spy.count(), 1); spy.clear(); - QVERIFY(workspace->activeSubWindow() == 0); - QVERIFY( activeWindow == 0 ); + QVERIFY(!workspace->activeSubWindow()); + QVERIFY(!activeWindow); } } @@ -564,8 +564,8 @@ void tst_QMdiArea::subWindowActivatedWithMinimize() window1->close(); qApp->processEvents(); - QVERIFY(workspace->activeSubWindow() == 0); - QVERIFY( activeWindow == 0 ); + QVERIFY(!workspace->activeSubWindow()); + QVERIFY(!activeWindow); QVERIFY( workspace->subWindowList().count() == 0 ); } @@ -1104,7 +1104,7 @@ void tst_QMdiArea::addAndRemoveWindows() QVERIFY(window); qApp->processEvents(); QCOMPARE(workspace.subWindowList().count(), 1); - QVERIFY(window->windowFlags() == DefaultWindowFlags); + QCOMPARE(window->windowFlags(), DefaultWindowFlags); QCOMPARE(window->size(), workspace.viewport()->size()); } @@ -1115,7 +1115,7 @@ void tst_QMdiArea::addAndRemoveWindows() QVERIFY(window); qApp->processEvents(); QCOMPARE(workspace.subWindowList().count(), 2); - QVERIFY(window->windowFlags() == DefaultWindowFlags); + QCOMPARE(window->windowFlags(), DefaultWindowFlags); QCOMPARE(window->size(), window->minimumSize()); } @@ -1127,7 +1127,7 @@ void tst_QMdiArea::addAndRemoveWindows() QVERIFY(window); qApp->processEvents(); QCOMPARE(workspace.subWindowList().count(), 3); - QVERIFY(window->windowFlags() == DefaultWindowFlags); + QCOMPARE(window->windowFlags(), DefaultWindowFlags); QCOMPARE(window->size(), QSize(1500, 1500)); } @@ -1142,7 +1142,7 @@ void tst_QMdiArea::addAndRemoveWindows() QMdiSubWindow *window = new QMdiSubWindow; workspace.addSubWindow(window); qApp->processEvents(); - QVERIFY(window->windowFlags() == DefaultWindowFlags); + QCOMPARE(window->windowFlags(), DefaultWindowFlags); window->setWidget(new QWidget); QCOMPARE(workspace.subWindowList().count(), 4); QTest::ignoreMessage(QtWarningMsg, "QMdiArea::addSubWindow: window is already added"); @@ -1206,7 +1206,7 @@ void tst_QMdiArea::addAndRemoveWindowsWithReparenting() { QMdiArea workspace; QMdiSubWindow window(&workspace); - QVERIFY(window.windowFlags() == DefaultWindowFlags); + QCOMPARE(window.windowFlags(), DefaultWindowFlags); // 0 because the window list contains widgets and not actual // windows. Silly, but that's the behavior. @@ -1219,7 +1219,7 @@ void tst_QMdiArea::addAndRemoveWindowsWithReparenting() QCOMPARE(workspace.subWindowList().count(), 0); window.setParent(&workspace); QCOMPARE(workspace.subWindowList().count(), 1); - QVERIFY(window.windowFlags() == DefaultWindowFlags); + QCOMPARE(window.windowFlags(), DefaultWindowFlags); QTest::ignoreMessage(QtWarningMsg, "QMdiArea::addSubWindow: window is already added"); workspace.addSubWindow(&window); diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index 46d3177a569941b8551acbd402c4d00aff5d49b8..843bb3437cccdc8da23743452115cf2524085560 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -78,6 +78,7 @@ public slots: private slots: void getSetCheck(); void addActionsAndClear(); + void addActionsConnect(); void keyboardNavigation_data(); void keyboardNavigation(); @@ -264,6 +265,34 @@ void tst_QMenu::addActionsAndClear() QCOMPARE(menus[0]->actions().count(), 0); } +static void testFunction() { } + +void tst_QMenu::addActionsConnect() +{ + QMenu menu; + const QString text = QLatin1String("bla"); + const QIcon icon; + menu.addAction(text, &menu, SLOT(deleteLater())); + menu.addAction(text, &menu, &QMenu::deleteLater); + menu.addAction(text, testFunction); + menu.addAction(text, &menu, testFunction); + menu.addAction(icon, text, &menu, SLOT(deleteLater())); + menu.addAction(icon, text, &menu, &QMenu::deleteLater); + menu.addAction(icon, text, testFunction); + menu.addAction(icon, text, &menu, testFunction); +#ifndef QT_NO_SHORTCUT + const QKeySequence keySequence(Qt::CTRL + Qt::Key_C); + menu.addAction(text, &menu, SLOT(deleteLater()), keySequence); + menu.addAction(text, &menu, &QMenu::deleteLater, keySequence); + menu.addAction(text, testFunction, keySequence); + menu.addAction(text, &menu, testFunction, keySequence); + menu.addAction(icon, text, &menu, SLOT(deleteLater()), keySequence); + menu.addAction(icon, text, &menu, &QMenu::deleteLater, keySequence); + menu.addAction(icon, text, testFunction, keySequence); + menu.addAction(icon, text, &menu, testFunction, keySequence); +#endif // !QT_NO_SHORTCUT +} + // We have a separate mouseActivation test for Windows mobile #ifndef Q_OS_WINCE void tst_QMenu::mouseActivation() @@ -334,8 +363,10 @@ void tst_QMenu::keyboardNavigation_data() QTest::newRow("data9") << Qt::Key(Qt::Key_Down) << Qt::KeyboardModifiers(Qt::NoModifier) << 3 << 0 << false << false<< true; QTest::newRow("data10") << Qt::Key(Qt::Key_Return) << Qt::KeyboardModifiers(Qt::NoModifier) << 3 << 0 << false << true << false; - // Test shortcuts. - QTest::newRow("shortcut0") << Qt::Key(Qt::Key_V) << Qt::KeyboardModifiers(Qt::AltModifier) << 5 << 0 << true << true << false; + if (qApp->platformName().toLower() != QStringLiteral("xcb")) { + // Test shortcuts. + QTest::newRow("shortcut0") << Qt::Key(Qt::Key_V) << Qt::KeyboardModifiers(Qt::AltModifier) << 5 << 0 << true << true << false; + } } void tst_QMenu::keyboardNavigation() @@ -513,7 +544,7 @@ void tst_QMenu::onStatusTipTimer() menu->close(); //goes out of the menu QCOMPARE(st, QString("sub action")); - QVERIFY(menu->isVisible() == false); + QVERIFY(!menu->isVisible()); m_onStatusTipTimerExecuted = true; } diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index f7cc69f83d4f3dd555f0d1b819bd72a022c1f225..9e24f373ebaba681f8455d044ba894e87261ae8f 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -146,7 +146,7 @@ private: QAction* m_lastSimpleAcceleratorId; int m_simpleActivatedCount; - int m_complexTriggerCount['k']; + int m_complexTriggerCount[int('k')]; }; // Testing get/set functions @@ -534,60 +534,60 @@ void tst_QMenuBar::check_accelKeys() QCOMPARE(m_complexTriggerCount[2], 0); QCOMPARE(m_complexTriggerCount[3], 0); QCOMPARE(m_complexTriggerCount[4], 0); - QCOMPARE(m_complexTriggerCount['a'], 0); - QCOMPARE(m_complexTriggerCount['b'], 0); - QCOMPARE(m_complexTriggerCount['c'], 0); - QCOMPARE(m_complexTriggerCount['d'], 0); + QCOMPARE(m_complexTriggerCount[int('a')], 0); + QCOMPARE(m_complexTriggerCount[int('b')], 0); + QCOMPARE(m_complexTriggerCount[int('c')], 0); + QCOMPARE(m_complexTriggerCount[int('d')], 0); QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_A, Qt::ControlModifier); QCOMPARE(m_complexTriggerCount[1], 0); QCOMPARE(m_complexTriggerCount[2], 0); QCOMPARE(m_complexTriggerCount[3], 0); QCOMPARE(m_complexTriggerCount[4], 0); - QCOMPARE(m_complexTriggerCount['a'], 1); - QCOMPARE(m_complexTriggerCount['b'], 0); - QCOMPARE(m_complexTriggerCount['c'], 0); - QCOMPARE(m_complexTriggerCount['d'], 0); + QCOMPARE(m_complexTriggerCount[int('a')], 1); + QCOMPARE(m_complexTriggerCount[int('b')], 0); + QCOMPARE(m_complexTriggerCount[int('c')], 0); + QCOMPARE(m_complexTriggerCount[int('d')], 0); QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_C, Qt::ControlModifier); QCOMPARE(m_complexTriggerCount[1], 0); QCOMPARE(m_complexTriggerCount[2], 0); QCOMPARE(m_complexTriggerCount[3], 0); QCOMPARE(m_complexTriggerCount[4], 0); - QCOMPARE(m_complexTriggerCount['a'], 1); - QCOMPARE(m_complexTriggerCount['b'], 0); - QCOMPARE(m_complexTriggerCount['c'], 1); - QCOMPARE(m_complexTriggerCount['d'], 0); + QCOMPARE(m_complexTriggerCount[int('a')], 1); + QCOMPARE(m_complexTriggerCount[int('b')], 0); + QCOMPARE(m_complexTriggerCount[int('c')], 1); + QCOMPARE(m_complexTriggerCount[int('d')], 0); QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_B, Qt::ControlModifier); QCOMPARE(m_complexTriggerCount[1], 0); QCOMPARE(m_complexTriggerCount[2], 0); QCOMPARE(m_complexTriggerCount[3], 0); QCOMPARE(m_complexTriggerCount[4], 0); - QCOMPARE(m_complexTriggerCount['a'], 1); - QCOMPARE(m_complexTriggerCount['b'], 1); - QCOMPARE(m_complexTriggerCount['c'], 1); - QCOMPARE(m_complexTriggerCount['d'], 0); + QCOMPARE(m_complexTriggerCount[int('a')], 1); + QCOMPARE(m_complexTriggerCount[int('b')], 1); + QCOMPARE(m_complexTriggerCount[int('c')], 1); + QCOMPARE(m_complexTriggerCount[int('d')], 0); QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_D, Qt::ControlModifier); QCOMPARE(m_complexTriggerCount[1], 0); QCOMPARE(m_complexTriggerCount[2], 0); QCOMPARE(m_complexTriggerCount[3], 0); QCOMPARE(m_complexTriggerCount[4], 0); - QCOMPARE(m_complexTriggerCount['a'], 1); - QCOMPARE(m_complexTriggerCount['b'], 1); - QCOMPARE(m_complexTriggerCount['c'], 1); - QCOMPARE(m_complexTriggerCount['d'], 1); + QCOMPARE(m_complexTriggerCount[int('a')], 1); + QCOMPARE(m_complexTriggerCount[int('b')], 1); + QCOMPARE(m_complexTriggerCount[int('c')], 1); + QCOMPARE(m_complexTriggerCount[int('d')], 1); QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_J, Qt::AltModifier); QCOMPARE(m_complexTriggerCount[1], 0); QCOMPARE(m_complexTriggerCount[2], 0); QCOMPARE(m_complexTriggerCount[3], 1); QCOMPARE(m_complexTriggerCount[4], 0); - QCOMPARE(m_complexTriggerCount['a'], 1); - QCOMPARE(m_complexTriggerCount['b'], 1); - QCOMPARE(m_complexTriggerCount['c'], 1); - QCOMPARE(m_complexTriggerCount['d'], 1); + QCOMPARE(m_complexTriggerCount[int('a')], 1); + QCOMPARE(m_complexTriggerCount[int('b')], 1); + QCOMPARE(m_complexTriggerCount[int('c')], 1); + QCOMPARE(m_complexTriggerCount[int('d')], 1); } #endif @@ -606,10 +606,10 @@ void tst_QMenuBar::check_cursorKeys1() // the Popupmenu should be visible now QCOMPARE(m_complexTriggerCount[3], 0); QCOMPARE(m_complexTriggerCount[4], 0); - QCOMPARE(m_complexTriggerCount['a'], 0); - QCOMPARE(m_complexTriggerCount['b'], 0); - QCOMPARE(m_complexTriggerCount['c'], 0); - QCOMPARE(m_complexTriggerCount['d'], 0); + QCOMPARE(m_complexTriggerCount[int('a')], 0); + QCOMPARE(m_complexTriggerCount[int('b')], 0); + QCOMPARE(m_complexTriggerCount[int('c')], 0); + QCOMPARE(m_complexTriggerCount[int('d')], 0); // Simulate a cursor key down click QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Down ); @@ -618,10 +618,10 @@ void tst_QMenuBar::check_cursorKeys1() // Let's see if the correct slot is called... QCOMPARE(m_complexTriggerCount[3], 0); QCOMPARE(m_complexTriggerCount[4], 0); - QCOMPARE(m_complexTriggerCount['a'], 0); // this shouldn't have been called - QCOMPARE(m_complexTriggerCount['b'], 1); // and this should have been called by a signal now - QCOMPARE(m_complexTriggerCount['c'], 0); - QCOMPARE(m_complexTriggerCount['d'], 0); + QCOMPARE(m_complexTriggerCount[int('a')], 0); // this shouldn't have been called + QCOMPARE(m_complexTriggerCount[int('b')], 1); // and this should have been called by a signal now + QCOMPARE(m_complexTriggerCount[int('c')], 0); + QCOMPARE(m_complexTriggerCount[int('d')], 0); } #endif @@ -648,10 +648,10 @@ void tst_QMenuBar::check_cursorKeys2() // Let's see if the correct slot is called... QCOMPARE(m_complexTriggerCount[3], 0); QCOMPARE(m_complexTriggerCount[4], 0); - QCOMPARE(m_complexTriggerCount['a'], 0); // this shouldn't have been caled - QCOMPARE(m_complexTriggerCount['b'], 0); // and this should have been called by a signal ow - QCOMPARE(m_complexTriggerCount['c'], 0); - QCOMPARE(m_complexTriggerCount['d'], 1); + QCOMPARE(m_complexTriggerCount[int('a')], 0); // this shouldn't have been caled + QCOMPARE(m_complexTriggerCount[int('b')], 0); // and this should have been called by a signal ow + QCOMPARE(m_complexTriggerCount[int('c')], 0); + QCOMPARE(m_complexTriggerCount[int('d')], 1); } #endif @@ -679,10 +679,10 @@ void tst_QMenuBar::check_cursorKeys3() // Let's see if the correct slot is called... QCOMPARE(m_complexTriggerCount[3], 0); QCOMPARE(m_complexTriggerCount[4], 0); - QCOMPARE(m_complexTriggerCount['a'], 0); // this shouldn't have been called - QCOMPARE(m_complexTriggerCount['b'], 1); // and this should have been called by a signal now - QCOMPARE(m_complexTriggerCount['c'], 0); - QCOMPARE(m_complexTriggerCount['d'], 0); + QCOMPARE(m_complexTriggerCount[int('a')], 0); // this shouldn't have been called + QCOMPARE(m_complexTriggerCount[int('b')], 1); // and this should have been called by a signal now + QCOMPARE(m_complexTriggerCount[int('c')], 0); + QCOMPARE(m_complexTriggerCount[int('d')], 0); } #endif @@ -715,17 +715,17 @@ void tst_QMenuBar::check_homeKey() // and press ENTER QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Enter ); // Let's see if the correct slot is called... -// QVERIFY2( m_complexActionTriggerCount['c'] == 1, "Popupmenu should respond to a Home key" ); - QCOMPARE(m_complexTriggerCount['c'], 1); +// QVERIFY2( m_complexActionTriggerCount[int('c')] == 1, "Popupmenu should respond to a Home key" ); + QCOMPARE(m_complexTriggerCount[int('c')], 1); QCOMPARE(m_complexTriggerCount[3], 0); QCOMPARE(m_complexTriggerCount[4], 0); - QCOMPARE(m_complexTriggerCount['a'], 0); - QCOMPARE(m_complexTriggerCount['b'], 0); - QCOMPARE(m_complexTriggerCount['d'], 0); - QCOMPARE(m_complexTriggerCount['e'], 0); - QCOMPARE(m_complexTriggerCount['f'], 0); - QCOMPARE(m_complexTriggerCount['g'], 0); - QCOMPARE(m_complexTriggerCount['h'], 0); + QCOMPARE(m_complexTriggerCount[int('a')], 0); + QCOMPARE(m_complexTriggerCount[int('b')], 0); + QCOMPARE(m_complexTriggerCount[int('d')], 0); + QCOMPARE(m_complexTriggerCount[int('e')], 0); + QCOMPARE(m_complexTriggerCount[int('f')], 0); + QCOMPARE(m_complexTriggerCount[int('g')], 0); + QCOMPARE(m_complexTriggerCount[int('h')], 0); } /*! @@ -754,17 +754,17 @@ void tst_QMenuBar::check_endKey() // and press ENTER QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Enter ); // Let's see if the correct slot is called... -// QVERIFY2( m_complexActionTriggerCount['h'] == 1, "Popupmenu should respond to an End key" ); - QCOMPARE(m_complexTriggerCount['h'], 1);//, "Popupmenu should respond to an End key"); +// QVERIFY2( m_complexActionTriggerCount[int('h')] == 1, "Popupmenu should respond to an End key" ); + QCOMPARE(m_complexTriggerCount[int('h')], 1);//, "Popupmenu should respond to an End key"); QCOMPARE(m_complexTriggerCount[3], 0); QCOMPARE(m_complexTriggerCount[4], 0); - QCOMPARE(m_complexTriggerCount['a'], 0); - QCOMPARE(m_complexTriggerCount['b'], 0); - QCOMPARE(m_complexTriggerCount['c'], 0); - QCOMPARE(m_complexTriggerCount['d'], 0); - QCOMPARE(m_complexTriggerCount['e'], 0); - QCOMPARE(m_complexTriggerCount['f'], 0); - QCOMPARE(m_complexTriggerCount['g'], 0); + QCOMPARE(m_complexTriggerCount[int('a')], 0); + QCOMPARE(m_complexTriggerCount[int('b')], 0); + QCOMPARE(m_complexTriggerCount[int('c')], 0); + QCOMPARE(m_complexTriggerCount[int('d')], 0); + QCOMPARE(m_complexTriggerCount[int('e')], 0); + QCOMPARE(m_complexTriggerCount[int('f')], 0); + QCOMPARE(m_complexTriggerCount[int('g')], 0); } /*! @@ -808,7 +808,7 @@ void tst_QMenuBar::check_escKey() // and press ENTER QTest::keyClick( menu.menus.at(1), Qt::Key_Enter ); // Let's see if the correct slot is called... - QVERIFY2( m_complexTriggerCount['c'] == 1, "Expected item 2C to be selected" ); + QVERIFY2(m_complexTriggerCount[int('c')] == 1, "Expected item 2C to be selected"); } #endif diff --git a/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST b/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..725b8e93b425c81a16b0fa4856a3df9ceb50cd01 --- /dev/null +++ b/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST @@ -0,0 +1,2 @@ +[clearAndGrab] +opensuse-13.1 diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp index e9f9c6785636679accc8f233242be5996cc530b6..638fad62062a3a46ffd35533c3992da7e95021b9 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp +++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp @@ -70,7 +70,7 @@ void tst_QOpenGLWidget::create() QVERIFY(w->isValid()); QVERIFY(w->context()); - QVERIFY(w->context()->format() == w->format()); + QCOMPARE(w->context()->format(), w->format()); QVERIFY(w->defaultFramebufferObject() != 0); } @@ -304,7 +304,7 @@ void tst_QOpenGLWidget::asViewport() // the widget stack. btn->update(); qApp->processEvents(); - QVERIFY(view->paintCount() == 0); + QCOMPARE(view->paintCount(), 0); } class PaintCountWidget : public QOpenGLWidget diff --git a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp index e7de6b0b754a8d6df1a904a5f679fc98a8ffac26..2145260013071214303cd7a2ed6f0b3e30273833 100644 --- a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp +++ b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp @@ -333,7 +333,7 @@ void tst_QPlainTextEdit::selectAllSetsNotSelection() QSKIP("Test only relevant for systems with selection"); QApplication::clipboard()->setText(QString("foobar"), QClipboard::Selection); - QVERIFY(QApplication::clipboard()->text(QClipboard::Selection) == QString("foobar")); + QCOMPARE(QApplication::clipboard()->text(QClipboard::Selection), QString("foobar")); ed->insertPlainText("Hello World"); ed->selectAll(); @@ -905,13 +905,13 @@ void tst_QPlainTextEdit::mouseCursorShape() { // always show an IBeamCursor, see change 170146 QVERIFY(!ed->isReadOnly()); - QVERIFY(ed->viewport()->cursor().shape() == Qt::IBeamCursor); + QCOMPARE(ed->viewport()->cursor().shape(), Qt::IBeamCursor); ed->setReadOnly(true); - QVERIFY(ed->viewport()->cursor().shape() == Qt::IBeamCursor); + QCOMPARE(ed->viewport()->cursor().shape(), Qt::IBeamCursor); ed->setPlainText("Foo"); - QVERIFY(ed->viewport()->cursor().shape() == Qt::IBeamCursor); + QCOMPARE(ed->viewport()->cursor().shape(), Qt::IBeamCursor); } #endif @@ -1324,7 +1324,7 @@ void tst_QPlainTextEdit::preserveCharFormatAfterSetPlainText() QTextBlock block = ed->document()->begin(); block = block.next(); QCOMPARE(block.text(), QString("This should still be blue")); - QVERIFY(block.begin().fragment().charFormat().foreground().color() == QColor(Qt::blue)); + QCOMPARE(block.begin().fragment().charFormat().foreground().color(), QColor(Qt::blue)); } void tst_QPlainTextEdit::extraSelections() @@ -1444,7 +1444,7 @@ void tst_QPlainTextEdit::wordWrapProperty() doc->setDocumentLayout(new QPlainTextDocumentLayout(doc)); edit.setDocument(doc); edit.setWordWrapMode(QTextOption::NoWrap); - QVERIFY(doc->defaultTextOption().wrapMode() == QTextOption::NoWrap); + QCOMPARE(doc->defaultTextOption().wrapMode(), QTextOption::NoWrap); } { QPlainTextEdit edit; @@ -1452,18 +1452,18 @@ void tst_QPlainTextEdit::wordWrapProperty() doc->setDocumentLayout(new QPlainTextDocumentLayout(doc)); edit.setWordWrapMode(QTextOption::NoWrap); edit.setDocument(doc); - QVERIFY(doc->defaultTextOption().wrapMode() == QTextOption::NoWrap); + QCOMPARE(doc->defaultTextOption().wrapMode(), QTextOption::NoWrap); } } void tst_QPlainTextEdit::lineWrapProperty() { - QVERIFY(ed->wordWrapMode() == QTextOption::WrapAtWordBoundaryOrAnywhere); - QVERIFY(ed->lineWrapMode() == QPlainTextEdit::WidgetWidth); + QCOMPARE(ed->wordWrapMode(), QTextOption::WrapAtWordBoundaryOrAnywhere); + QCOMPARE(ed->lineWrapMode(), QPlainTextEdit::WidgetWidth); ed->setLineWrapMode(QPlainTextEdit::NoWrap); - QVERIFY(ed->lineWrapMode() == QPlainTextEdit::NoWrap); - QVERIFY(ed->wordWrapMode() == QTextOption::WrapAtWordBoundaryOrAnywhere); - QVERIFY(ed->document()->defaultTextOption().wrapMode() == QTextOption::NoWrap); + QCOMPARE(ed->lineWrapMode(), QPlainTextEdit::NoWrap); + QCOMPARE(ed->wordWrapMode(), QTextOption::WrapAtWordBoundaryOrAnywhere); + QCOMPARE(ed->document()->defaultTextOption().wrapMode(), QTextOption::NoWrap); } void tst_QPlainTextEdit::selectionChanged() @@ -1560,7 +1560,7 @@ void tst_QPlainTextEdit::findWithRegExp() bool found = ed->find(rx); - QVERIFY(found == true); + QVERIFY(found); QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("text")); } @@ -1574,7 +1574,7 @@ void tst_QPlainTextEdit::findBackwardWithRegExp() bool found = ed->find(rx, QTextDocument::FindBackward); - QVERIFY(found == true); + QVERIFY(found); QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("arbit")); } @@ -1586,7 +1586,7 @@ void tst_QPlainTextEdit::findWithRegExpReturnsFalseIfNoMoreResults() bool found = ed->find(rx); - QVERIFY(found == false); + QVERIFY(!found); QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("text")); } #endif diff --git a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp index 4fd8b99acf282969e1994d0e26efae7d2e991420..44a554ad8245d66a234461fec93ffdad74409665 100644 --- a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp +++ b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp @@ -227,8 +227,8 @@ void tst_QPushButton::autoRepeat() QVERIFY( testWidget->isDown() ); QVERIFY( toggle_count == 0 ); QTest::keyRelease( testWidget, Qt::Key_Space ); - QVERIFY(press_count == release_count); - QVERIFY(release_count == click_count); + QCOMPARE(press_count, release_count); + QCOMPARE(release_count, click_count); QVERIFY(press_count > 1); // #### shouldn't I check here to see if multiple signals have been fired??? diff --git a/tests/auto/widgets/widgets/qscrollarea/tst_qscrollarea.cpp b/tests/auto/widgets/widgets/qscrollarea/tst_qscrollarea.cpp index 40e13c8e8d2888562ad01ad163be611c3a2d00dc..ce6afc0a576ce90e55c25675d8565e2658b5e6be 100644 --- a/tests/auto/widgets/widgets/qscrollarea/tst_qscrollarea.cpp +++ b/tests/auto/widgets/widgets/qscrollarea/tst_qscrollarea.cpp @@ -166,8 +166,8 @@ void tst_QScrollArea::checkHFW_Task_197736() scrollArea.setWidgetResizable(false); scrollArea.resize(QSize(100,100)); w->resize(QSize(200,200)); - QVERIFY(w->width() == 200); - QVERIFY(w->height() == 200); + QCOMPARE(w->width(), 200); + QCOMPARE(w->height(), 200); } QTEST_MAIN(tst_QScrollArea) diff --git a/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp b/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp index 1037d9473474dc046daa1a6cd1368e7aed9f1dd4..0b7189179dd5817dff029de15724874028a52a15 100644 --- a/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp +++ b/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp @@ -100,7 +100,7 @@ void tst_QScrollBar::scrollSingleStep() QTest::qWait(510); // initial delay is 500 for setRepeatAction disconnect(&testWidget, &QAbstractSlider::actionTriggered, &testWidget, &SingleStepTestScrollBar::hideAndShow); #ifdef Q_OS_MAC - QEXPECT_FAIL("", "This test fails on Mac OS X, see QTBUG-25272", Abort); + QEXPECT_FAIL("", "This test fails on OS X, see QTBUG-25272", Abort); #endif QCOMPARE(testWidget.value(), testWidget.singleStep()); } diff --git a/tests/auto/widgets/widgets/qsizegrip/BLACKLIST b/tests/auto/widgets/widgets/qsizegrip/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..2c874bcb578b20dc6b649805a152383af1e648d7 --- /dev/null +++ b/tests/auto/widgets/widgets/qsizegrip/BLACKLIST @@ -0,0 +1,2 @@ +[hideAndShowOnWindowStateChange:Qt::Window] +xcb diff --git a/tests/auto/widgets/widgets/qspinbox/BLACKLIST b/tests/auto/widgets/widgets/qspinbox/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..5bf6c3beed34b3106eba857ecc0cffd46e73a85f --- /dev/null +++ b/tests/auto/widgets/widgets/qspinbox/BLACKLIST @@ -0,0 +1,3 @@ +[editingFinished] +osx-10.8 +osx-10.9 diff --git a/tests/auto/widgets/widgets/qtabbar/BLACKLIST b/tests/auto/widgets/widgets/qtabbar/BLACKLIST new file mode 100644 index 0000000000000000000000000000000000000000..b000b084442260b086a732a2f810c5db05c738da --- /dev/null +++ b/tests/auto/widgets/widgets/qtabbar/BLACKLIST @@ -0,0 +1,2 @@ +[sizeHints] +ubuntu-14.04 diff --git a/tests/auto/widgets/widgets/qtabwidget/qtabwidget.pro b/tests/auto/widgets/widgets/qtabwidget/qtabwidget.pro index c367959cbc967a18bd43831cce031fd2d94daff2..92c2f6cb7eae3c9b549ece18763dc645cdc826d9 100644 --- a/tests/auto/widgets/widgets/qtabwidget/qtabwidget.pro +++ b/tests/auto/widgets/widgets/qtabwidget/qtabwidget.pro @@ -8,4 +8,4 @@ INCLUDEPATH += ../ HEADERS += SOURCES += tst_qtabwidget.cpp -win32:!wince*:!winrt:LIBS += -luser32 +win32:!wince:!winrt: LIBS += -luser32 diff --git a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp index fffbbc2ec787f81dc773ba67aa11db522220fb27..a991f18110bbd0def7f682157e1fb985503907b2 100644 --- a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp +++ b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp @@ -165,7 +165,7 @@ void tst_QTabWidget::init() tw = new QTabWidget(0); QCOMPARE(tw->count(), 0); QCOMPARE(tw->currentIndex(), -1); - QVERIFY(tw->currentWidget() == NULL); + QVERIFY(!tw->currentWidget()); } void tst_QTabWidget::cleanup() @@ -208,7 +208,7 @@ void tst_QTabWidget::addRemoveTab() QCOMPARE(tw->count(), 0); tw->removeTab(-1); QCOMPARE(tw->count(), 0); - QVERIFY(tw->widget(-1) == 0); + QVERIFY(!tw->widget(-1)); QWidget *w = new QWidget(); int index = tw->addTab(w, LABEL); @@ -216,7 +216,7 @@ void tst_QTabWidget::addRemoveTab() QCOMPARE(tw->indexOf(w), index); QCOMPARE(tw->count(), 1); - QVERIFY(tw->widget(index) == w); + QCOMPARE(tw->widget(index), w); QCOMPARE(tw->tabText(index), QString(LABEL)); removePage(index); @@ -238,7 +238,7 @@ void tst_QTabWidget::tabPosition() void tst_QTabWidget::tabEnabled() { // Test bad arguments - QVERIFY(tw->isTabEnabled(-1) == false); + QVERIFY(!tw->isTabEnabled(-1)); tw->setTabEnabled(-1, false); int index = addPage(); @@ -333,21 +333,21 @@ void tst_QTabWidget::currentWidget() { // Test bad arguments tw->setCurrentWidget(NULL); - QVERIFY(tw->currentWidget() == NULL); + QVERIFY(!tw->currentWidget()); int index = addPage(); QWidget *w = tw->widget(index); - QVERIFY(tw->currentWidget() == w); + QCOMPARE(tw->currentWidget(), w); QCOMPARE(tw->currentIndex(), index); tw->setCurrentWidget(NULL); - QVERIFY(tw->currentWidget() == w); + QCOMPARE(tw->currentWidget(), w); QCOMPARE(tw->currentIndex(), index); int index2 = addPage(); QWidget *w2 = tw->widget(index2); Q_UNUSED(w2); - QVERIFY(tw->currentWidget() == w); + QCOMPARE(tw->currentWidget(), w); QCOMPARE(tw->currentIndex(), index); removePage(index2); @@ -372,7 +372,7 @@ void tst_QTabWidget::currentIndex() QCOMPARE(tw->currentIndex(), firstIndex); QCOMPARE(spy.count(), 1); QList<QVariant> arguments = spy.takeFirst(); - QVERIFY(arguments.at(0).toInt() == firstIndex); + QCOMPARE(arguments.at(0).toInt(), firstIndex); int index = addPage(); QCOMPARE(tw->currentIndex(), firstIndex); @@ -380,19 +380,19 @@ void tst_QTabWidget::currentIndex() QCOMPARE(tw->currentIndex(), index); QCOMPARE(spy.count(), 1); arguments = spy.takeFirst(); - QVERIFY(arguments.at(0).toInt() == index); + QCOMPARE(arguments.at(0).toInt(), index); removePage(index); QCOMPARE(tw->currentIndex(), firstIndex); QCOMPARE(spy.count(), 1); arguments = spy.takeFirst(); - QVERIFY(arguments.at(0).toInt() == firstIndex); + QCOMPARE(arguments.at(0).toInt(), firstIndex); removePage(firstIndex); QCOMPARE(tw->currentIndex(), -1); QCOMPARE(spy.count(), 1); arguments = spy.takeFirst(); - QVERIFY(arguments.at(0).toInt() == -1); + QCOMPARE(arguments.at(0).toInt(), -1); } void tst_QTabWidget::cornerWidget() @@ -400,24 +400,24 @@ void tst_QTabWidget::cornerWidget() // Test bad arguments tw->setCornerWidget(NULL, Qt::TopRightCorner); - QVERIFY(tw->cornerWidget(Qt::TopLeftCorner) == 0); - QVERIFY(tw->cornerWidget(Qt::TopRightCorner) == 0); - QVERIFY(tw->cornerWidget(Qt::BottomLeftCorner) == 0); - QVERIFY(tw->cornerWidget(Qt::BottomRightCorner) == 0); + QVERIFY(!tw->cornerWidget(Qt::TopLeftCorner)); + QVERIFY(!tw->cornerWidget(Qt::TopRightCorner)); + QVERIFY(!tw->cornerWidget(Qt::BottomLeftCorner)); + QVERIFY(!tw->cornerWidget(Qt::BottomRightCorner)); QWidget *w = new QWidget(0); tw->setCornerWidget(w, Qt::TopLeftCorner); QCOMPARE(w->parent(), (QObject *)tw); - QVERIFY(tw->cornerWidget(Qt::TopLeftCorner) == w); + QCOMPARE(tw->cornerWidget(Qt::TopLeftCorner), w); tw->setCornerWidget(w, Qt::TopRightCorner); - QVERIFY(tw->cornerWidget(Qt::TopRightCorner) == w); + QCOMPARE(tw->cornerWidget(Qt::TopRightCorner), w); tw->setCornerWidget(w, Qt::BottomLeftCorner); - QVERIFY(tw->cornerWidget(Qt::BottomLeftCorner) == w); + QCOMPARE(tw->cornerWidget(Qt::BottomLeftCorner), w); tw->setCornerWidget(w, Qt::BottomRightCorner); - QVERIFY(tw->cornerWidget(Qt::BottomRightCorner) == w); + QCOMPARE(tw->cornerWidget(Qt::BottomRightCorner), w); tw->setCornerWidget(0, Qt::TopRightCorner); - QVERIFY(tw->cornerWidget(Qt::TopRightCorner) == 0); + QVERIFY(!tw->cornerWidget(Qt::TopRightCorner)); QCOMPARE(w->isHidden(), true); } diff --git a/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp b/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp index aaa7348bdf4257a9c30a8db6034f3d2c1c18e668..adc768f828c314f9d13f0334a471429fd2a4e57e 100644 --- a/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp +++ b/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp @@ -141,14 +141,14 @@ void tst_QTextBrowser::noReloadOnAnchorJump() browser->setSource(url); QCOMPARE(browser->htmlLoadAttempts, 1); QVERIFY(!browser->toPlainText().isEmpty()); - QVERIFY(browser->source() == url); + QCOMPARE(browser->source(), url); } void tst_QTextBrowser::bgColorOnSourceChange() { browser->setSource(QUrl::fromLocalFile("pagewithbg.html")); QVERIFY(browser->document()->rootFrame()->frameFormat().hasProperty(QTextFormat::BackgroundBrush)); - QVERIFY(browser->document()->rootFrame()->frameFormat().background().color() == Qt::blue); + QCOMPARE(browser->document()->rootFrame()->frameFormat().background().color(), QColor(Qt::blue)); browser->setSource(QUrl::fromLocalFile("pagewithoutbg.html")); QVERIFY(!browser->document()->rootFrame()->frameFormat().hasProperty(QTextFormat::BackgroundBrush)); @@ -167,13 +167,13 @@ void tst_QTextBrowser::forwardButton() QVERIFY(!forwardEmissions.isEmpty()); QVariant val = forwardEmissions.takeLast()[0]; - QVERIFY(val.type() == QVariant::Bool); - QVERIFY(val.toBool() == false); + QCOMPARE(val.type(), QVariant::Bool); + QVERIFY(!val.toBool()); QVERIFY(!backwardEmissions.isEmpty()); val = backwardEmissions.takeLast()[0]; - QVERIFY(val.type() == QVariant::Bool); - QVERIFY(val.toBool() == false); + QCOMPARE(val.type(), QVariant::Bool); + QVERIFY(!val.toBool()); QVERIFY(browser->historyTitle(-1).isEmpty()); QCOMPARE(browser->historyUrl(0), QUrl::fromLocalFile("pagewithbg.html")); @@ -185,13 +185,13 @@ void tst_QTextBrowser::forwardButton() QVERIFY(!forwardEmissions.isEmpty()); val = forwardEmissions.takeLast()[0]; - QVERIFY(val.type() == QVariant::Bool); - QVERIFY(val.toBool() == false); + QCOMPARE(val.type(), QVariant::Bool); + QVERIFY(!val.toBool()); QVERIFY(!backwardEmissions.isEmpty()); val = backwardEmissions.takeLast()[0]; - QVERIFY(val.type() == QVariant::Bool); - QVERIFY(val.toBool() == true); + QCOMPARE(val.type(), QVariant::Bool); + QVERIFY(val.toBool()); QCOMPARE(browser->historyTitle(-1), QString("Page With BG")); QCOMPARE(browser->historyTitle(0), QString("Sample Anchor")); @@ -201,13 +201,13 @@ void tst_QTextBrowser::forwardButton() QVERIFY(!forwardEmissions.isEmpty()); val = forwardEmissions.takeLast()[0]; - QVERIFY(val.type() == QVariant::Bool); - QVERIFY(val.toBool() == true); + QCOMPARE(val.type(), QVariant::Bool); + QVERIFY(val.toBool()); QVERIFY(!backwardEmissions.isEmpty()); val = backwardEmissions.takeLast()[0]; - QVERIFY(val.type() == QVariant::Bool); - QVERIFY(val.toBool() == false); + QCOMPARE(val.type(), QVariant::Bool); + QVERIFY(!val.toBool()); QVERIFY(browser->historyTitle(-1).isEmpty()); QCOMPARE(browser->historyTitle(0), QString("Page With BG")); @@ -217,13 +217,13 @@ void tst_QTextBrowser::forwardButton() QVERIFY(!forwardEmissions.isEmpty()); val = forwardEmissions.takeLast()[0]; - QVERIFY(val.type() == QVariant::Bool); - QVERIFY(val.toBool() == false); + QCOMPARE(val.type(), QVariant::Bool); + QVERIFY(!val.toBool()); QVERIFY(!backwardEmissions.isEmpty()); val = backwardEmissions.takeLast()[0]; - QVERIFY(val.type() == QVariant::Bool); - QVERIFY(val.toBool() == true); + QCOMPARE(val.type(), QVariant::Bool); + QVERIFY(val.toBool()); } void tst_QTextBrowser::viewportPositionInHistory() @@ -244,29 +244,29 @@ void tst_QTextBrowser::relativeLinks() QSignalSpy sourceChangedSpy(browser, SIGNAL(sourceChanged(QUrl))); browser->setSource(QUrl("subdir/../qtextbrowser.html")); QVERIFY(!browser->document()->isEmpty()); - QVERIFY(sourceChangedSpy.count() == 1); + QCOMPARE(sourceChangedSpy.count(), 1); QCOMPARE(sourceChangedSpy.takeFirst()[0].toUrl(), QUrl("subdir/../qtextbrowser.html")); browser->setSource(QUrl("subdir/index.html")); QVERIFY(!browser->document()->isEmpty()); - QVERIFY(sourceChangedSpy.count() == 1); + QCOMPARE(sourceChangedSpy.count(), 1); QCOMPARE(sourceChangedSpy.takeFirst()[0].toUrl(), QUrl("subdir/index.html")); browser->setSource(QUrl("anchor.html")); QVERIFY(!browser->document()->isEmpty()); - QVERIFY(sourceChangedSpy.count() == 1); + QCOMPARE(sourceChangedSpy.count(), 1); QCOMPARE(sourceChangedSpy.takeFirst()[0].toUrl(), QUrl("anchor.html")); browser->setSource(QUrl("subdir/index.html")); QVERIFY(!browser->document()->isEmpty()); - QVERIFY(sourceChangedSpy.count() == 1); + QCOMPARE(sourceChangedSpy.count(), 1); QCOMPARE(sourceChangedSpy.takeFirst()[0].toUrl(), QUrl("subdir/index.html")); // using QUrl::fromLocalFile() browser->setSource(QUrl::fromLocalFile("anchor.html")); QVERIFY(!browser->document()->isEmpty()); - QVERIFY(sourceChangedSpy.count() == 1); + QCOMPARE(sourceChangedSpy.count(), 1); QCOMPARE(sourceChangedSpy.takeFirst()[0].toUrl(), QUrl("file:anchor.html")); browser->setSource(QUrl("subdir/../qtextbrowser.html")); QVERIFY(!browser->document()->isEmpty()); - QVERIFY(sourceChangedSpy.count() == 1); + QCOMPARE(sourceChangedSpy.count(), 1); QCOMPARE(sourceChangedSpy.takeFirst()[0].toUrl(), QUrl("subdir/../qtextbrowser.html")); } @@ -446,13 +446,13 @@ void tst_QTextBrowser::sourceInsideLoadResource() void tst_QTextBrowser::textInteractionFlags_vs_readOnly() { QVERIFY(browser->isReadOnly()); - QVERIFY(browser->textInteractionFlags() == Qt::TextBrowserInteraction); + QCOMPARE(browser->textInteractionFlags(), Qt::TextBrowserInteraction); browser->setReadOnly(true); - QVERIFY(browser->textInteractionFlags() == Qt::TextBrowserInteraction); + QCOMPARE(browser->textInteractionFlags(), Qt::TextBrowserInteraction); browser->setReadOnly(false); - QVERIFY(browser->textInteractionFlags() == Qt::TextEditorInteraction); + QCOMPARE(browser->textInteractionFlags(), Qt::TextEditorInteraction); browser->setReadOnly(true); - QVERIFY(browser->textInteractionFlags() == Qt::TextBrowserInteraction); + QCOMPARE(browser->textInteractionFlags(), Qt::TextBrowserInteraction); } void tst_QTextBrowser::anchorsWithSelfBuiltHtml() @@ -525,7 +525,7 @@ void tst_QTextBrowser::loadResourceOnRelativeLocalFiles() QVERIFY(!browser->toPlainText().isEmpty()); QVariant v = browser->loadResource(QTextDocument::HtmlResource, QUrl("../anchor.html")); QVERIFY(v.isValid()); - QVERIFY(v.type() == QVariant::ByteArray); + QCOMPARE(v.type(), QVariant::ByteArray); QVERIFY(!v.toByteArray().isEmpty()); } @@ -658,7 +658,7 @@ void tst_QTextBrowser::urlEncoding() QCOMPARE(spy.count(), 1); QUrl url = spy.at(0).at(0).toUrl(); - QVERIFY(url.toEncoded() == QByteArray("http://www.google.com/q=%22")); + QCOMPARE(url.toEncoded(), QByteArray("http://www.google.com/q=%22")); delete browser; } diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp index 399f82fdca57a1d6c3ee6b24257b3eaab34148db..fb7c3e8a68c5851118689f0a82ba79374beadced 100644 --- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp @@ -398,12 +398,13 @@ void tst_QTextEdit::cleanup() void tst_QTextEdit::inlineAttributesOnInsert() { - QVERIFY(ed->textCursor().charFormat().foreground().color() != Qt::blue); + const QColor blue(Qt::blue); + QVERIFY(ed->textCursor().charFormat().foreground().color() != blue); - ed->setTextColor(Qt::blue); + ed->setTextColor(blue); QTest::keyClick(ed, Qt::Key_A); - QVERIFY(ed->textCursor().charFormat().foreground().color() == Qt::blue); + QCOMPARE(ed->textCursor().charFormat().foreground().color(), blue); } void tst_QTextEdit::inlineAttributesOnSelection() @@ -457,7 +458,7 @@ void tst_QTextEdit::autoBulletList1() QTest::keyClicks(ed, "*This should become a list"); QVERIFY(ed->textCursor().currentList()); - QVERIFY(ed->textCursor().currentList()->format().style() == QTextListFormat::ListDisc); + QCOMPARE(ed->textCursor().currentList()->format().style(), QTextListFormat::ListDisc); } void tst_QTextEdit::autoBulletList2() @@ -582,7 +583,7 @@ void tst_QTextEdit::selectAllSetsNotSelection() } QApplication::clipboard()->setText(QString("foobar"), QClipboard::Selection); - QVERIFY(QApplication::clipboard()->text(QClipboard::Selection) == QString("foobar")); + QCOMPARE(QApplication::clipboard()->text(QClipboard::Selection), QString("foobar")); ed->insertPlainText("Hello World"); ed->selectAll(); @@ -867,11 +868,12 @@ void tst_QTextEdit::appendShouldUseCurrentFormat() fmt.setFontItalic(true); ed->setCurrentCharFormat(fmt); ed->append("Hello"); + const QColor blue(Qt::blue); QTextCursor cursor(ed->document()); QVERIFY(cursor.movePosition(QTextCursor::NextCharacter)); - QVERIFY(cursor.charFormat().foreground().color() != Qt::blue); + QVERIFY(cursor.charFormat().foreground().color() != blue); QVERIFY(!cursor.charFormat().fontItalic()); QVERIFY(cursor.movePosition(QTextCursor::NextBlock)); @@ -883,7 +885,7 @@ void tst_QTextEdit::appendShouldUseCurrentFormat() } QVERIFY(cursor.movePosition(QTextCursor::NextCharacter)); - QVERIFY(cursor.charFormat().foreground().color() == Qt::blue); + QCOMPARE(cursor.charFormat().foreground().color(), blue); QVERIFY(cursor.charFormat().fontItalic()); } @@ -1211,7 +1213,7 @@ void tst_QTextEdit::lineWrapModes() { ed->setLineWrapMode(QTextEdit::NoWrap); // NoWrap at the same time as having all lines that are all left aligned means we optimize to only layout once. The effect is that the width is always 0 - QVERIFY(ed->document()->pageSize().width() == qreal(0)); + QCOMPARE(ed->document()->pageSize().width(), qreal(0)); QTextCursor cursor = QTextCursor(ed->document()); cursor.insertText(QString("A simple line")); @@ -1237,13 +1239,13 @@ void tst_QTextEdit::mouseCursorShape() { // always show an IBeamCursor, see change 170146 QVERIFY(!ed->isReadOnly()); - QVERIFY(ed->viewport()->cursor().shape() == Qt::IBeamCursor); + QCOMPARE(ed->viewport()->cursor().shape(), Qt::IBeamCursor); ed->setReadOnly(true); - QVERIFY(ed->viewport()->cursor().shape() == Qt::IBeamCursor); + QCOMPARE(ed->viewport()->cursor().shape(), Qt::IBeamCursor); ed->setPlainText("Foo"); - QVERIFY(ed->viewport()->cursor().shape() == Qt::IBeamCursor); + QCOMPARE(ed->viewport()->cursor().shape(), Qt::IBeamCursor); } #endif @@ -1661,7 +1663,7 @@ void tst_QTextEdit::preserveCharFormatAfterSetPlainText() QTextBlock block = ed->document()->begin(); block = block.next(); QCOMPARE(block.text(), QString("This should still be blue")); - QVERIFY(block.begin().fragment().charFormat().foreground().color() == QColor(Qt::blue)); + QCOMPARE(block.begin().fragment().charFormat().foreground().color(), QColor(Qt::blue)); } void tst_QTextEdit::extraSelections() @@ -1796,25 +1798,25 @@ void tst_QTextEdit::wordWrapProperty() QTextDocument *doc = new QTextDocument(&edit); edit.setDocument(doc); edit.setWordWrapMode(QTextOption::NoWrap); - QVERIFY(doc->defaultTextOption().wrapMode() == QTextOption::NoWrap); + QCOMPARE(doc->defaultTextOption().wrapMode(), QTextOption::NoWrap); } { QTextEdit edit; QTextDocument *doc = new QTextDocument(&edit); edit.setWordWrapMode(QTextOption::NoWrap); edit.setDocument(doc); - QVERIFY(doc->defaultTextOption().wrapMode() == QTextOption::NoWrap); + QCOMPARE(doc->defaultTextOption().wrapMode(), QTextOption::NoWrap); } } void tst_QTextEdit::lineWrapProperty() { - QVERIFY(ed->wordWrapMode() == QTextOption::WrapAtWordBoundaryOrAnywhere); - QVERIFY(ed->lineWrapMode() == QTextEdit::WidgetWidth); + QCOMPARE(ed->wordWrapMode(), QTextOption::WrapAtWordBoundaryOrAnywhere); + QCOMPARE(ed->lineWrapMode(), QTextEdit::WidgetWidth); ed->setLineWrapMode(QTextEdit::NoWrap); - QVERIFY(ed->lineWrapMode() == QTextEdit::NoWrap); - QVERIFY(ed->wordWrapMode() == QTextOption::WrapAtWordBoundaryOrAnywhere); - QVERIFY(ed->document()->defaultTextOption().wrapMode() == QTextOption::NoWrap); + QCOMPARE(ed->lineWrapMode(), QTextEdit::NoWrap); + QCOMPARE(ed->wordWrapMode(), QTextOption::WrapAtWordBoundaryOrAnywhere); + QCOMPARE(ed->document()->defaultTextOption().wrapMode(), QTextOption::NoWrap); } void tst_QTextEdit::selectionChanged() @@ -2119,7 +2121,7 @@ void tst_QTextEdit::setDocumentPreservesPalette() QTextDocument *newDoc = new QTextDocument(ed); ed->setDocument(newDoc); - QVERIFY(control->document() == newDoc); + QCOMPARE(control->document(), newDoc); QVERIFY(whitePal.color(QPalette::Active, QPalette::Text) == control->palette().color(QPalette::Active, QPalette::Text)); } @@ -2522,7 +2524,7 @@ void tst_QTextEdit::findWithRegExp() bool found = ed->find(rx); - QVERIFY(found == true); + QVERIFY(found); QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("text")); } @@ -2536,7 +2538,7 @@ void tst_QTextEdit::findBackwardWithRegExp() bool found = ed->find(rx, QTextDocument::FindBackward); - QVERIFY(found == true); + QVERIFY(found); QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("arbit")); } @@ -2548,7 +2550,7 @@ void tst_QTextEdit::findWithRegExpReturnsFalseIfNoMoreResults() bool found = ed->find(rx); - QVERIFY(found == false); + QVERIFY(!found); QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("text")); } #endif diff --git a/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp b/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp index 24de35ce89ec853014a7939471b57f26e13601cf..e653a85d963a0440c4b469f346bbba566b96f9c3 100644 --- a/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp +++ b/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp @@ -67,6 +67,7 @@ private slots: void allowedAreas(); void orientation(); void addAction(); + void addActionConnect(); void insertAction(); void addSeparator(); void insertSeparator(); @@ -361,6 +362,23 @@ void tst_QToolBar::addAction() } } +static void testFunction() { } + +void tst_QToolBar::addActionConnect() +{ + QToolBar tb; + const QString text = QLatin1String("bla"); + const QIcon icon; + tb.addAction(text, &tb, SLOT(deleteLater())); + tb.addAction(text, &tb, &QMenu::deleteLater); + tb.addAction(text, testFunction); + tb.addAction(text, &tb, testFunction); + tb.addAction(icon, text, &tb, SLOT(deleteLater())); + tb.addAction(icon, text, &tb, &QMenu::deleteLater); + tb.addAction(icon, text, testFunction); + tb.addAction(icon, text, &tb, testFunction); +} + void tst_QToolBar::insertAction() { QToolBar tb; @@ -495,13 +513,13 @@ void tst_QToolBar::insertWidget() QToolBar tb; QPointer<QWidget> widget = new QWidget; QAction *action = tb.addWidget(widget); - QVERIFY(action->parent() == &tb); + QCOMPARE(action->parent(), &tb); QToolBar tb2; tb.removeAction(action); tb2.addAction(action); QVERIFY(widget && widget->parent() == &tb2); - QVERIFY(action->parent() == &tb2); + QCOMPARE(action->parent(), &tb2); } } @@ -960,10 +978,10 @@ void tst_QToolBar::actionOwnership() QToolBar *tb2 = new QToolBar; QPointer<QAction> action = tb1->addAction("test"); - QVERIFY(action->parent() == tb1); + QCOMPARE(action->parent(), tb1); tb2->addAction(action); - QVERIFY(action->parent() == tb1); + QCOMPARE(action->parent(), tb1); delete tb1; QVERIFY(!action); @@ -974,13 +992,13 @@ void tst_QToolBar::actionOwnership() QToolBar *tb2 = new QToolBar; QPointer<QAction> action = tb1->addAction("test"); - QVERIFY(action->parent() == tb1); + QCOMPARE(action->parent(), tb1); tb1->removeAction(action); - QVERIFY(action->parent() == tb1); + QCOMPARE(action->parent(), tb1); tb2->addAction(action); - QVERIFY(action->parent() == tb1); + QCOMPARE(action->parent(), tb1); delete tb1; QVERIFY(!action); diff --git a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp index 03fbae2e578a62ba2a9a2232a189bd319252a6b9..0d1abe50324ae7682fd1e4305fe63517e1e73b22 100644 --- a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp +++ b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp @@ -170,10 +170,10 @@ void tst_QToolButton::collapseTextOnPriority() QStyleOptionToolButton option; button.initStyleOption(&option); - QVERIFY(option.toolButtonStyle == Qt::ToolButtonTextBesideIcon); + QCOMPARE(option.toolButtonStyle, Qt::ToolButtonTextBesideIcon); action.setPriority(QAction::LowPriority); button.initStyleOption(&option); - QVERIFY(option.toolButtonStyle == Qt::ToolButtonIconOnly); + QCOMPARE(option.toolButtonStyle, Qt::ToolButtonIconOnly); } diff --git a/tests/auto/xml/dom/qdom/tst_qdom.cpp b/tests/auto/xml/dom/qdom/tst_qdom.cpp index 2ce32c7cf297d7fcdc0ede4ac70d364c7b5cddbe..a4a3f1f6b34bd0df81153571547a207f149a974a 100644 --- a/tests/auto/xml/dom/qdom/tst_qdom.cpp +++ b/tests/auto/xml/dom/qdom/tst_qdom.cpp @@ -1043,15 +1043,15 @@ void tst_QDom::browseElements() QVERIFY(!bar.isNull()); QVERIFY(bar.previousSiblingElement("bar").isNull()); QVERIFY(bar.previousSiblingElement().isNull()); - QVERIFY(bar.nextSiblingElement("bar").tagName() == "bar"); + QCOMPARE(bar.nextSiblingElement("bar").tagName(), QLatin1String("bar")); QVERIFY(bar.nextSiblingElement("bar").nextSiblingElement("bar").isNull()); QDomElement bop = foo.firstChildElement("bop"); QVERIFY(!bop.isNull()); - QVERIFY(bar.nextSiblingElement() == bop); - QVERIFY(bop.nextSiblingElement("bop") == foo.lastChildElement("bop")); - QVERIFY(bop.previousSiblingElement("bar") == foo.firstChildElement("bar")); - QVERIFY(bop.previousSiblingElement("bar") == foo.firstChildElement()); + QCOMPARE(bar.nextSiblingElement(), bop); + QCOMPARE(bop.nextSiblingElement("bop"), foo.lastChildElement("bop")); + QCOMPARE(bop.previousSiblingElement("bar"), foo.firstChildElement("bar")); + QCOMPARE(bop.previousSiblingElement("bar"), foo.firstChildElement()); } void tst_QDom::domNodeMapAndList() diff --git a/tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp b/tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp index 04f19f6a2be20ab3f5579191ba85f00d09c254f6..a5ac58878e5a96573aaa83c57cbdd485873c7b45 100644 --- a/tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp +++ b/tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp @@ -147,7 +147,7 @@ public slots: void requestFinished(QNetworkReply *reply) { - QVERIFY(reply->error() == QNetworkReply::NoError); + QCOMPARE(reply->error(), QNetworkReply::NoError); reply->deleteLater(); } diff --git a/tests/benchmarks/corelib/io/qdiriterator/main.cpp b/tests/benchmarks/corelib/io/qdiriterator/main.cpp index 272bafc7dd5769811c70f4dcd98d615bfcdbc28f..42d36a22f891d54ee3fa9a1d7af808125ad7d07b 100644 --- a/tests/benchmarks/corelib/io/qdiriterator/main.cpp +++ b/tests/benchmarks/corelib/io/qdiriterator/main.cpp @@ -223,12 +223,12 @@ void tst_qdiriterator::fsiterator() int c = 0; dump && printf("\n\n\n\n"); - QFileSystemIterator dir(dirpath, + QDirIteratorTest::QFileSystemIterator dir(dirpath, //QDir::AllEntries | QDir::Hidden | QDir::NoDotAndDotDot, //QDir::AllEntries | QDir::Hidden, //QDir::Files | QDir::NoDotAndDotDot, QDir::Files, - QFileSystemIterator::Subdirectories); + QDirIteratorTest::QFileSystemIterator::Subdirectories); for (; !dir.atEnd(); dir.next()) { dump && printf("%d %s\n", diff --git a/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp index 1b28f462aa81c9d3bea199e7c4bd51c56bf7e34b..a4db21742d482b2ed7b7816a3770f01d4295433b 100644 --- a/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp +++ b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp @@ -99,6 +99,8 @@ QT_BEGIN_NAMESPACE +namespace QDirIteratorTest { + class QFileSystemIteratorPrivate { public: @@ -671,4 +673,6 @@ QString QFileSystemIterator::path() const return QString::fromLocal8Bit(d->m_dirPaths.top()); } +} // QDirIteratorTest:: + QT_END_NAMESPACE diff --git a/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.h b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.h index b940c0061b8b79211134b1b1cc18e54426d74b95..96fa5177a0a3a160dca812e242ed23492efd18a1 100644 --- a/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.h +++ b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.h @@ -38,6 +38,7 @@ QT_BEGIN_NAMESPACE +namespace QDirIteratorTest { class QFileSystemIteratorPrivate; class //Q_CORE_EXPORT @@ -81,6 +82,8 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(QFileSystemIterator::IteratorFlags) +} // namespace QDirIteratorTest + QT_END_NAMESPACE #endif diff --git a/tests/benchmarks/gui/image/qimagereader/qimagereader.pro b/tests/benchmarks/gui/image/qimagereader/qimagereader.pro index 4f821235961510185266366851cc3955927b5348..5f1c72153d98cc5f43bedd92d9c36412db165502 100644 --- a/tests/benchmarks/gui/image/qimagereader/qimagereader.pro +++ b/tests/benchmarks/gui/image/qimagereader/qimagereader.pro @@ -9,7 +9,7 @@ SOURCES += tst_qimagereader.cpp !contains(QT_CONFIG, no-jpeg):DEFINES += QTEST_HAVE_JPEG QT += network -wince*: { +wince { addFiles.files = images addFiles.path = . diff --git a/tests/manual/diaglib/qwidgetdump.cpp b/tests/manual/diaglib/qwidgetdump.cpp index 432e65167807b507d9d450d987eced353c047200..f057a58ff0229432f898949ca0463a9d0cdec6c5 100644 --- a/tests/manual/diaglib/qwidgetdump.cpp +++ b/tests/manual/diaglib/qwidgetdump.cpp @@ -58,6 +58,8 @@ static void dumpWidgetRecursion(QTextStream &str, const QWidget *w, str << (w->testAttribute(Qt::WA_Mapped) ? "[mapped] " : "[not mapped] "); if (w->testAttribute(Qt::WA_DontCreateNativeAncestors)) str << "[NoNativeAncestors] "; + if (const int states = w->windowState()) + str << "windowState=" << hex << showbase << states << dec << noshowbase << ' '; formatRect(str, w->geometry()); if (!(options & DontPrintWindowFlags)) { str << ' '; diff --git a/tests/manual/diaglib/qwindowdump.cpp b/tests/manual/diaglib/qwindowdump.cpp index ca76d7b80d00ccb32ac606128d798591275c4b36..a77bae22e986a70469471dfaf552b92a650bfe07 100644 --- a/tests/manual/diaglib/qwindowdump.cpp +++ b/tests/manual/diaglib/qwindowdump.cpp @@ -131,6 +131,8 @@ void formatWindow(QTextStream &str, const QWindow *w, FormatWindowOptions option str << "[top] "; if (w->isExposed()) str << "[exposed] "; + if (const Qt::WindowState state = w->windowState()) + str << "windowState=" << state << ' '; formatRect(str, w->geometry()); if (!(options & DontPrintWindowFlags)) { str << ' '; diff --git a/tests/manual/highdpi/dragwidget.cpp b/tests/manual/highdpi/dragwidget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b2035666965779cb2cb380259473a24ae29a5641 --- /dev/null +++ b/tests/manual/highdpi/dragwidget.cpp @@ -0,0 +1,223 @@ +/**************************************************************************** + ** + ** Copyright (C) 2015 The Qt Company Ltd. + ** Contact: http://www.qt.io/licensing/ + ** + ** This file is part of the test suite of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:LGPL21$ + ** 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 http://www.qt.io/terms-conditions. For further + ** information use the contact form at http://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 2.1 or version 3 as published by the Free + ** Software Foundation and appearing in the file LICENSE.LGPLv21 and + ** LICENSE.LGPLv3 included in the packaging of this file. Please review the + ** following information to ensure the GNU Lesser General Public License + ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and + ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. + ** + ** As a special exception, The Qt Company gives you certain additional + ** rights. These rights are described in The Qt Company LGPL Exception + ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. + ** + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#include <QtWidgets> +#include "dragwidget.h" + +class FramedLabel : public QLabel +{ +public: + FramedLabel(const QString &text, QWidget *parent) + : QLabel(text, parent) + { + setAutoFillBackground(true); + setFrameShape(QFrame::Panel); + setFrameShadow(QFrame::Raised); + } +}; + +DragWidget::DragWidget(QString text, QWidget *parent) + : QWidget(parent), otherWindow(0) +{ + int x = 5; + int y = 5; + + bool createChildWindow = text.isEmpty(); // OK, yes this is a hack... + if (text.isEmpty()) + text = "You can drag from this window and drop text here"; + + QStringList words = text.split(' '); + foreach (QString word, words) { + if (!word.isEmpty()) { + FramedLabel *wordLabel = new FramedLabel(word, this); + wordLabel->move(x, y); + wordLabel->show(); + x += wordLabel->width() + 2; + if (x >= 245) { + x = 5; + y += wordLabel->height() + 2; + } + } + } + + /* + QPalette newPalette = palette(); + newPalette.setColor(QPalette::Window, Qt::white); + setPalette(newPalette); + */ + + setAcceptDrops(true); + setMinimumSize(400, qMax(200, y)); + setWindowTitle(tr("Draggable Text Window %1").arg(createChildWindow ? 1 : 2)); + if (createChildWindow) + otherWindow = new DragWidget("Here is a second window that accepts drops"); +} + +void DragWidget::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasText()) { + if (event->source() == this) { + event->setDropAction(Qt::MoveAction); + event->accept(); + } else { + event->acceptProposedAction(); + } + } else { + event->ignore(); + } +} + +void DragWidget::dragMoveEvent(QDragMoveEvent * event) +{ + dragPos = event->pos(); + dragTimer.start(500, this); + update(); +} + +void DragWidget::dragLeaveEvent(QDragLeaveEvent *) +{ + dragTimer.stop(); + update(); +} + + +void DragWidget::dropEvent(QDropEvent *event) +{ + if (event->mimeData()->hasText()) { + const QMimeData *mime = event->mimeData(); + QStringList pieces = mime->text().split(QRegExp("\\s+"), + QString::SkipEmptyParts); + QPoint position = event->pos(); + QPoint hotSpot; + + QList<QByteArray> hotSpotPos = mime->data("application/x-hotspot").split(' '); + if (hotSpotPos.size() == 2) { + hotSpot.setX(hotSpotPos.first().toInt()); + hotSpot.setY(hotSpotPos.last().toInt()); + } + dropPos = position - hotSpot; + dropTimer.start(500, this); + update(); + + foreach (QString piece, pieces) { + FramedLabel *newLabel = new FramedLabel(piece, this); + newLabel->move(position - hotSpot); + newLabel->show(); + + position += QPoint(newLabel->width(), 0); + } + + if (event->source() == this) { + event->setDropAction(Qt::MoveAction); + event->accept(); + } else { + event->acceptProposedAction(); + } + } else { + event->ignore(); + } + foreach (QObject *child, children()) { + if (child->inherits("QWidget")) { + QWidget *widget = static_cast<QWidget *>(child); + if (!widget->isVisible()) + widget->deleteLater(); + } + } +} + +void DragWidget::mousePressEvent(QMouseEvent *event) +{ + QLabel *child = static_cast<QLabel*>(childAt(event->pos())); + if (!child) + return; + + QPoint hotSpot = event->pos() - child->pos(); + + QMimeData *mimeData = new QMimeData; + mimeData->setText(child->text()); + mimeData->setData("application/x-hotspot", + QByteArray::number(hotSpot.x()) + " " + QByteArray::number(hotSpot.y())); + + QPixmap pixmap(child->size()); + child->render(&pixmap); + + QDrag *drag = new QDrag(this); + drag->setMimeData(mimeData); + drag->setPixmap(pixmap); + drag->setHotSpot(hotSpot); + + Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction); + + if (dropAction == Qt::MoveAction) + child->close(); +} + +void DragWidget::timerEvent(QTimerEvent *e) +{ + if (e->timerId() == dragTimer.timerId()) + dragTimer.stop(); + if (e->timerId() == dropTimer.timerId()) + dropTimer.stop(); + update(); +} + +void DragWidget::paintEvent(QPaintEvent *) +{ + QPainter p(this); + p.fillRect(rect(), Qt::white); + + if (dropTimer.isActive()) { + p.setBrush(Qt::red); + p.drawEllipse(dropPos, 50, 50); + } + + if (dragTimer.isActive()) { + p.setPen(QPen(Qt::blue, 5)); + QPoint p1 = (rect().topLeft()*3 + rect().bottomRight())/4; + QPoint p2 = (rect().topLeft() + rect().bottomRight()*3)/4; + p.drawLine(p1, dragPos); + p.drawLine(p2, dragPos); + } +} + +void DragWidget::showEvent(QShowEvent *) +{ + if (otherWindow) + otherWindow->show(); +} + +void DragWidget::hideEvent(QHideEvent *) +{ + if (otherWindow) + otherWindow->hide(); +} diff --git a/tests/manual/highdpi/dragwidget.h b/tests/manual/highdpi/dragwidget.h new file mode 100644 index 0000000000000000000000000000000000000000..0d9631e2f8f71294c056d894ed311c7faddeafde --- /dev/null +++ b/tests/manual/highdpi/dragwidget.h @@ -0,0 +1,68 @@ +/**************************************************************************** + ** + ** Copyright (C) 2015 The Qt Company Ltd. + ** Contact: http://www.qt.io/licensing/ + ** + ** This file is part of the test suite of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:LGPL21$ + ** 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 http://www.qt.io/terms-conditions. For further + ** information use the contact form at http://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 2.1 or version 3 as published by the Free + ** Software Foundation and appearing in the file LICENSE.LGPLv21 and + ** LICENSE.LGPLv3 included in the packaging of this file. Please review the + ** following information to ensure the GNU Lesser General Public License + ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and + ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. + ** + ** As a special exception, The Qt Company gives you certain additional + ** rights. These rights are described in The Qt Company LGPL Exception + ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. + ** + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#ifndef DRAGWIDGET_H +#define DRAGWIDGET_H + +#include <QWidget> +#include <QBasicTimer> + +QT_BEGIN_NAMESPACE +class QDragEnterEvent; +class QDropEvent; +QT_END_NAMESPACE + +class DragWidget : public QWidget +{ +public: + DragWidget(QString text = QString(), QWidget *parent = 0); + +protected: + void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE; + void dragLeaveEvent(QDragLeaveEvent *event) Q_DECL_OVERRIDE; + void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void dragMoveEvent(QDragMoveEvent * event) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; + void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE; + void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; + void hideEvent(QHideEvent *event) Q_DECL_OVERRIDE; +private: + QPoint dragPos; + QPoint dropPos; + QBasicTimer dragTimer; + QBasicTimer dropTimer; + QWidget *otherWindow; +}; + +#endif // DRAGWIDGET_H diff --git a/tests/manual/highdpi/highdpi.pro b/tests/manual/highdpi/highdpi.pro index 7a2979c74c1bf2b16850baf22660ce55fbc075dc..7d6b42535e27bdcdb710972e0735d04b071d3912 100644 --- a/tests/manual/highdpi/highdpi.pro +++ b/tests/manual/highdpi/highdpi.pro @@ -1,10 +1,17 @@ TEMPLATE = app TARGET = highdpi INCLUDEPATH += . -QT += widgets -CONFIG+=console +QT += widgets gui-private +CONFIG +=console +CONFIG -= app_bundle +CONFIG += c++11 # Input -SOURCES += main.cpp +SOURCES += \ + dragwidget.cpp \ + main.cpp + +HEADERS += \ + dragwidget.h RESOURCES += \ highdpi.qrc diff --git a/tests/manual/highdpi/main.cpp b/tests/manual/highdpi/main.cpp index fd14523a97a1d64bb1726d5c64895b32e1478935..692a60d5112c22303fa755ede24f3295b53dbd66 100644 --- a/tests/manual/highdpi/main.cpp +++ b/tests/manual/highdpi/main.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include <QMainWindow> +#include <QMenuBar> #include <QLabel> #include <QHBoxLayout> #include <QApplication> @@ -39,6 +40,7 @@ #include <QStyle> #include <QToolBar> #include <QPushButton> +#include <QButtonGroup> #include <QLineEdit> #include <QScrollBar> #include <QSlider> @@ -49,10 +51,219 @@ #include <QWindow> #include <QScreen> #include <QFile> +#include <QMouseEvent> #include <QTemporaryDir> +#include <QTimer> #include <QCommandLineParser> #include <QCommandLineOption> +#include <QDebug> +#include <private/qhighdpiscaling_p.h> +#include "dragwidget.h" + +class DemoContainerBase +{ +public: + DemoContainerBase() : m_widget(0) {} + virtual ~DemoContainerBase() {} + QString name() { return option().names().first(); } + virtual QCommandLineOption &option() = 0; + virtual void makeVisible(bool visible, QWidget *parent) = 0; + QWidget *widget() { return m_widget; } +protected: + QWidget *m_widget; +}; + +typedef QList<DemoContainerBase*> DemoContainerList ; + + +template <class T> +class DemoContainer : public DemoContainerBase +{ +public: + DemoContainer(const QString &optionName, const QString &description) + : m_option(optionName, description) + { + } + ~DemoContainer() { delete m_widget; } + + QCommandLineOption &option() { return m_option; } + + void makeVisible(bool visible, QWidget *parent) { + if (visible && !m_widget) { + m_widget = new T; + m_widget->installEventFilter(parent); + } + if (m_widget) + m_widget->setVisible(visible); + } +private: + QCommandLineOption m_option; +}; + +class LabelSlider : public QObject +{ +Q_OBJECT +public: + LabelSlider(QObject *parent, const QString &text, QGridLayout *layout, int row) + : QObject(parent) + { + QLabel *textLabel = new QLabel(text); + m_slider = new QSlider(); + m_slider->setOrientation(Qt::Horizontal); + m_slider->setMinimum(1); + m_slider->setMaximum(40); + m_slider->setValue(10); + m_slider->setTracking(false); + m_slider->setTickInterval(5); + m_slider->setTickPosition(QSlider::TicksBelow); + m_label = new QLabel("1.0"); + + // set up layouts + layout->addWidget(textLabel, row, 0); + layout->addWidget(m_slider, row, 1); + layout->addWidget(m_label, row, 2); + + // handle slider position change + connect(m_slider, &QSlider::sliderMoved, this, &LabelSlider::updateLabel); + connect(m_slider, &QSlider::valueChanged, this, &LabelSlider::valueChanged); + } + void setValue(int scaleFactor) { + m_slider->setValue(scaleFactor); + updateLabel(scaleFactor); + } +private slots: + void updateLabel(int scaleFactor) { + // slider value is scale factor times ten; + qreal scalefactorF = qreal(scaleFactor) / 10.0; + + // update label, add ".0" if needed. + QString number = QString::number(scalefactorF); + if (!number.contains(".")) + number.append(".0"); + m_label->setText(number); + } +signals: + void valueChanged(int scaleFactor); +private: + QSlider *m_slider; + QLabel *m_label; +}; + +static qreal getScreenFactorWithoutPixelDensity(const QScreen *screen) +{ + // this is a hack that relies on knowing the internals of QHighDpiScaling + static const char *scaleFactorProperty = "_q_scaleFactor"; + QVariant screenFactor = screen->property(scaleFactorProperty); + return screenFactor.isValid() ? screenFactor.toReal() : 1.0; +} + +static inline qreal getGlobalScaleFactor() +{ + QScreen *noScreen = 0; + return QHighDpiScaling::factor(noScreen); +} + +class DemoController : public QWidget +{ +Q_OBJECT +public: + DemoController(DemoContainerList *demos, QCommandLineParser *parser); + ~DemoController(); +protected: + bool eventFilter(QObject *object, QEvent *event); + void closeEvent(QCloseEvent *) { qApp->quit(); } +private slots: + void handleButton(int id, bool toggled); +private: + DemoContainerList *m_demos; + QButtonGroup *m_group; +}; + +DemoController::DemoController(DemoContainerList *demos, QCommandLineParser *parser) + : m_demos(demos) +{ + setWindowTitle("screen scale factors"); + setObjectName("controller"); // make WindowScaleFactorSetter skip this window + + QGridLayout *layout = new QGridLayout; + setLayout(layout); + + int layoutRow = 0; + LabelSlider *globalScaleSlider = new LabelSlider(this, "Global scale factor", layout, layoutRow++); + globalScaleSlider->setValue(int(getGlobalScaleFactor() * 10)); + connect(globalScaleSlider, &LabelSlider::valueChanged, [](int scaleFactor){ + // slider value is scale factor times ten; + qreal scalefactorF = qreal(scaleFactor) / 10.0; + QHighDpiScaling::setGlobalFactor(scalefactorF); + }); + + // set up one scale control line per screen + QList<QScreen *> screens = QGuiApplication::screens(); + foreach (QScreen *screen, screens) { + // create scale control line + QSize screenSize = screen->geometry().size(); + QString screenId = screen->name() + " " + QString::number(screenSize.width()) + + " " + QString::number(screenSize.height()); + LabelSlider *slider = new LabelSlider(this, screenId, layout, layoutRow++); + slider->setValue(getScreenFactorWithoutPixelDensity(screen) * 10); + + // handle slider value change + connect(slider, &LabelSlider::valueChanged, [screen](int scaleFactor){ + // slider value is scale factor times ten; + qreal scalefactorF = qreal(scaleFactor) / 10.0; + + // set scale factor for screen + qreal oldFactor = QHighDpiScaling::factor(screen); + QHighDpiScaling::setScreenFactor(screen, scalefactorF); + qreal newFactor = QHighDpiScaling::factor(screen); + + qDebug() << "factor was / is" << oldFactor << newFactor; + }); + } + + 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()); + button->setCheckable(true); + layout->addWidget(button, layoutRow++, 0, 1, -1); + m_group->addButton(button, i); + + if (parser->isSet(demo->option())) { + demo->makeVisible(true, this); + button->setChecked(true); + } + } + connect(m_group, SIGNAL(buttonToggled(int, bool)), this, SLOT(handleButton(int, bool))); +} + +DemoController::~DemoController() +{ + 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); + if (demo->widget() == object) { + m_group->button(i)->setChecked(false); + break; + } + } + } + return false; +} + +void DemoController::handleButton(int id, bool toggled) +{ + m_demos->at(id)->makeVisible(toggled, this); +} class PixmapPainter : public QWidget { @@ -69,7 +280,6 @@ public: QIcon qtIcon; }; - PixmapPainter::PixmapPainter() { pixmap1X = QPixmap(":/qticon32.png"); @@ -172,15 +382,18 @@ class MainWindow : public QMainWindow { public: MainWindow(); + QMenu *addNewMenu(const QString &title, int itemCount = 5); QIcon qtIcon; QIcon qtIcon1x; QIcon qtIcon2x; QToolBar *fileToolBar; + int menuCount; }; MainWindow::MainWindow() + :menuCount(0) { // beware that QIcon auto-loads the @2x versions. qtIcon1x.addFile(":/qticon16.png"); @@ -192,8 +405,33 @@ MainWindow::MainWindow() // fileToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); fileToolBar->addAction(new QAction(qtIcon1x, QString("1x"), this)); fileToolBar->addAction(new QAction(qtIcon2x, QString("2x"), this)); + addNewMenu("&Edit"); + addNewMenu("&Build"); + addNewMenu("&Debug", 4); + addNewMenu("&Transmogrify", 7); + addNewMenu("T&ools"); + addNewMenu("&Help", 2); } + +QMenu *MainWindow::addNewMenu(const QString &title, int itemCount) +{ + QMenu *menu = menuBar()->addMenu(title); + for (int i = 0; i < itemCount; i++) { + menuCount++; + QString s = "Menu item " + QString::number(menuCount); + if (i == 3) { + QMenu *subMenu = menu->addMenu(s); + for (int j = 1; j < 4; j++) + subMenu->addAction(QString::fromLatin1("SubMenu item %1.%2").arg(menuCount).arg(j)); + } else { + menu->addAction(s); + } + } + return menu; +} + + class StandardIcons : public QWidget { public: @@ -205,7 +443,7 @@ public: int dy = 50; int maxX = 500; - for (int iconIndex = QStyle::SP_TitleBarMenuButton; iconIndex < QStyle::SP_MediaVolumeMuted; ++iconIndex) { + for (uint iconIndex = QStyle::SP_TitleBarMenuButton; iconIndex < QStyle::SP_MediaVolumeMuted; ++iconIndex) { QIcon icon = qApp->style()->standardIcon(QStyle::StandardPixmap(iconIndex)); QPainter p(this); p.drawPixmap(x, y, icon.pixmap(dx - 5, dy - 5)); @@ -295,14 +533,27 @@ public: void paintEvent(QPaintEvent *) { QPainter painter(this); - int y = 40; - for (int fontSize = 2; fontSize < 18; fontSize += 2) { + + // Points + int y = 10; + for (int fontSize = 6; fontSize < 18; fontSize += 2) { QFont font; font.setPointSize(fontSize); - QString string = QString(QStringLiteral("%1 The quick brown fox jumped over the lazy Doug.")).arg(fontSize); + QString string = QString(QStringLiteral("This text is in point size %1")).arg(fontSize); + painter.setFont(font); + y += (painter.fontMetrics().lineSpacing()); + painter.drawText(10, y, string); + } + + // Pixels + y += painter.fontMetrics().lineSpacing(); + for (int fontSize = 6; fontSize < 18; fontSize += 2) { + QFont font; + font.setPixelSize(fontSize); + QString string = QString(QStringLiteral("This text is in pixel size %1")).arg(fontSize); painter.setFont(font); + y += (painter.fontMetrics().lineSpacing()); painter.drawText(10, y, string); - y += (fontSize * 2.5); } } }; @@ -461,97 +712,427 @@ public: } }; +class LinePainter : public QWidget +{ +public: + void paintEvent(QPaintEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + + QPoint lastMousePoint; + QVector<QPoint> linePoints; +}; -int main(int argc, char **argv) +void LinePainter::paintEvent(QPaintEvent *) { - QApplication app(argc, argv); - QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); - QCoreApplication::setApplicationVersion(QT_VERSION_STR); + QPainter p(this); + p.fillRect(QRect(QPoint(0, 0), size()), QBrush(Qt::gray)); - QCommandLineParser parser; - parser.setApplicationDescription("High DPI tester"); - parser.addHelpOption(); - parser.addVersionOption(); - QCommandLineOption pixmapPainterOption("pixmap", "Test pixmap painter"); - parser.addOption(pixmapPainterOption); - QCommandLineOption labelOption("label", "Test Labels"); - parser.addOption(labelOption); - QCommandLineOption mainWindowOption("mainwindow", "Test QMainWindow"); - parser.addOption(mainWindowOption); - QCommandLineOption standardIconsOption("standard-icons", "Test standard icons"); - parser.addOption(standardIconsOption); - QCommandLineOption cachingOption("caching", "Test caching"); - parser.addOption(cachingOption); - QCommandLineOption styleOption("styles", "Test style"); - parser.addOption(styleOption); - QCommandLineOption fontsOption("fonts", "Test fonts"); - parser.addOption(fontsOption); - QCommandLineOption iconDrawingOption("icondrawing", "Test icon drawing"); - parser.addOption(iconDrawingOption); - QCommandLineOption buttonsOption("buttons", "Test buttons"); - parser.addOption(buttonsOption); + // Default antialiased line + p.setRenderHint(QPainter::Antialiasing); + p.drawLines(linePoints); + + // Cosmetic 1 antialiased line + QPen pen; + pen.setCosmetic(true); + pen.setWidth(1); + p.setPen(pen); + p.translate(3, 3); + p.drawLines(linePoints); + + // Aliased cosmetic 1 line + p.setRenderHint(QPainter::Antialiasing, false); + p.translate(3, 3); + p.drawLines(linePoints); +} - parser.process(app); +void LinePainter::mousePressEvent(QMouseEvent *event) +{ + lastMousePoint = event->pos(); +} - QScopedPointer<PixmapPainter> pixmapPainter; - if (parser.isSet(pixmapPainterOption)) { - pixmapPainter.reset(new PixmapPainter); - pixmapPainter->show(); +void LinePainter::mouseReleaseEvent(QMouseEvent *) +{ + lastMousePoint = QPoint(); +} + +void LinePainter::mouseMoveEvent(QMouseEvent *event) +{ + if (lastMousePoint.isNull()) + return; + + QPoint newMousePoint = event->pos(); + if (lastMousePoint == newMousePoint) + return; + linePoints.append(lastMousePoint); + linePoints.append(newMousePoint); + lastMousePoint = newMousePoint; + update(); +} + +class CursorTester : public QWidget +{ +public: + CursorTester() + :moveLabel(0), moving(false) + { } - QScopedPointer<Labels> label; - if (parser.isSet(labelOption)) { - label.reset(new Labels); - label->resize(200, 200); - label->show(); + inline QRect getRect(int idx) const + { + int h = height() / 2; + return QRect(10, 10 + h * (idx - 1), width() - 20, h - 20); + } + void paintEvent(QPaintEvent *) + { + QPainter p(this); + QRect r1 = getRect(1); + QRect r2 = getRect(2); + p.fillRect(r1, QColor(200, 200, 250)); + p.drawText(r1, "Drag from here to move a window based on QCursor::pos()"); + p.fillRect(r2, QColor(250, 200, 200)); + p.drawText(r2, "Drag from here to move a window based on mouse event position"); + + if (moving) { + p.setPen(Qt::darkGray); + QFont f = font(); + f.setPointSize(8); + p.setFont(f); + p.drawEllipse(mousePos, 30,60); + QPoint pt = mousePos - QPoint(0, 60); + QPoint pt2 = pt - QPoint(30,10); + QPoint offs(30, 0); + p.drawLine(pt, pt2); + p.drawLine(pt2 - offs, pt2 + offs); + p.drawText(pt2 - offs, "mouse pos"); + + p.setPen(QColor(50,130,70)); + QPoint cursorPos = mapFromGlobal(QCursor::pos()); + pt = cursorPos - QPoint(0, 30); + pt2 = pt + QPoint(60, -20); + p.drawEllipse(cursorPos, 60, 30); + p.drawLine(pt, pt2); + p.drawLine(pt2 - offs, pt2 + offs); + p.drawText(pt2 - offs, "cursor pos"); + } } - QScopedPointer<MainWindow> mainWindow; - if (parser.isSet(mainWindowOption)) { - mainWindow.reset(new MainWindow); - mainWindow->show(); + void mousePressEvent(QMouseEvent *e) + { + if (moving) + return; + QRect r1 = getRect(1); + QRect r2 = getRect(2); + + moving = r1.contains(e->pos()) || r2.contains(e->pos()); + if (!moving) + return; + useCursorPos = r1.contains(e->pos()); + + if (!moveLabel) + moveLabel = new QLabel(this,Qt::BypassWindowManagerHint|Qt::FramelessWindowHint|Qt::Window ); + + if (useCursorPos) + moveLabel->setText("I'm following QCursor::pos()"); + else + moveLabel->setText("I'm following QMouseEvent::globalPos()"); + moveLabel->adjustSize(); + mouseMoveEvent(e); + moveLabel->show(); } - QScopedPointer<StandardIcons> icons; - if (parser.isSet(standardIconsOption)) { - icons.reset(new StandardIcons); - icons->resize(510, 510); - icons->show(); + void mouseReleaseEvent(QMouseEvent *) + { + if (moveLabel) + moveLabel->hide(); + update(); + moving = false; } - QScopedPointer<Caching> caching; - if (parser.isSet(cachingOption)) { - caching.reset(new Caching); - caching->resize(300, 300); - caching->show(); + void mouseMoveEvent(QMouseEvent *e) + { + if (!moving) + return; + QPoint pos = useCursorPos ? QCursor::pos() : e->globalPos(); + pos -= moveLabel->rect().center(); + moveLabel->move(pos); + mousePos = e->pos(); + update(); } - QScopedPointer<Style> style; - if (parser.isSet(styleOption)) { - style.reset(new Style); - style->show(); +private: + QLabel *moveLabel; + bool useCursorPos; + bool moving; + QPoint mousePos; +}; + + +class ScreenDisplayer : public QWidget +{ +public: + ScreenDisplayer() + : QWidget(), moveLabel(0), scaleFactor(1.0) + { } - QScopedPointer<Fonts> fonts; - if (parser.isSet(fontsOption)) { - fonts.reset(new Fonts); - fonts->show(); + void timerEvent(QTimerEvent *) { + update(); } - QScopedPointer<IconDrawing> iconDrawing; - if (parser.isSet(iconDrawingOption)) { - iconDrawing.reset(new IconDrawing); - iconDrawing->show(); + void mousePressEvent(QMouseEvent *) { + 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) { + if (!moveLabel) + return; + moveLabel->move(e->pos() / scaleFactor); + QString str; + QDebug dbg(&str); + dbg.setAutoInsertSpaces(false); + dbg << moveLabel->geometry(); + moveLabel->setText(str); + } + void mouseReleaseEvent(QMouseEvent *) { + if (moveLabel) + moveLabel->hide(); + } + void showEvent(QShowEvent *) { + refreshTimer.start(300, this); } + void hideEvent(QHideEvent *) { + refreshTimer.stop(); + } + void paintEvent(QPaintEvent *) { + QPainter p(this); + QRectF total; + QList<QScreen*> screens = qApp->screens(); + foreach (QScreen *screen, screens) { + total |= screen->geometry(); + } + if (total.isEmpty()) + return; + + scaleFactor = qMin(width()/total.width(), height()/total.height()); + + p.fillRect(rect(), Qt::black); + p.scale(scaleFactor, scaleFactor); + p.translate(-total.topLeft()); + p.setPen(QPen(Qt::white, 10)); + p.setBrush(Qt::gray); + - QScopedPointer<Buttons> buttons; - if (parser.isSet(buttonsOption)) { - buttons.reset(new Buttons); - buttons->show(); + foreach (QScreen *screen, screens) { + p.drawRect(screen->geometry()); + QFont f = font(); + f.setPixelSize(screen->geometry().height() / 8); + p.setFont(f); + p.drawText(screen->geometry(), Qt::AlignCenter, screen->name()); + } + p.setBrush(QColor(200,220,255,127)); + foreach (QWidget *widget, QApplication::topLevelWidgets()) { + if (!widget->isHidden()) + p.drawRect(widget->geometry()); + } + + QPolygon cursorShape; + cursorShape << QPoint(0,0) << QPoint(20, 60) + << QPoint(30, 50) << QPoint(60, 80) + << QPoint(80, 60) << QPoint(50, 30) + << QPoint(60, 20); + cursorShape.translate(QCursor::pos()); + p.drawPolygon(cursorShape); } +private: + QLabel *moveLabel; + QBasicTimer refreshTimer; + qreal scaleFactor; +}; + +class PhysicalSizeTest : public QWidget +{ +Q_OBJECT +public: + PhysicalSizeTest() : QWidget(), m_ignoreResize(false) {} + void paintEvent(QPaintEvent *event); + void resizeEvent(QResizeEvent *) { + qreal ppi = window()->windowHandle()->screen()->physicalDotsPerInchX(); + QSizeF s = size(); + if (!m_ignoreResize) + m_physicalSize = s / ppi; + } + bool event(QEvent *event) { + if (event->type() == QEvent::ScreenChangeInternal) { + // we will get resize events when the scale factor changes + m_ignoreResize = true; + QTimer::singleShot(100, this, SLOT(handleScreenChange())); + } + return QWidget::event(event); + } +public slots: + 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; +}; + +void PhysicalSizeTest::paintEvent(QPaintEvent *) +{ + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + + qreal ppi = window()->windowHandle()->screen()->physicalDotsPerInchX(); + qreal ppmm = ppi / 25.4; + qreal h = 15 * ppmm; + QRectF rulerRect(0,0, width(), h); + rulerRect.moveCenter(rect().center()); + + QFont f = font(); + f.setPixelSize(18); + p.setFont(f); + + // draw a rectangle in (Qt) pixel coordinates, for comparison + QRect pixelRect(0, 0, 300, 50); + pixelRect.moveTopLeft(QPoint(5 * ppmm, rulerRect.bottom() + 5 * ppmm)); + p.fillRect(pixelRect, QColor(199,222,255)); + p.drawText(pixelRect, "This rectangle is 300x50 pixels"); + + f.setPixelSize(4 * ppmm); + p.setFont(f); + + QRectF topRect(0, 0, width(), rulerRect.top()); + p.drawText(topRect, Qt::AlignCenter, "The ruler is drawn in physical units.\nThis window tries to keep its physical size\nwhen moved between screens."); + + // draw a ruler in real physical coordinates + + p.fillRect(rulerRect, QColor(255, 222, 111)); + + QPen linePen(Qt::black, 0.3 * ppmm); + p.setPen(linePen); + f.setBold(true); + p.setFont(f); + + qreal vCenter = rulerRect.center().y(); + p.drawLine(0, vCenter, width(), vCenter); + + // cm + for (int i = 0;;) { + i++; + qreal x = i * ppmm; + if (x > width()) + break; + qreal y = rulerRect.bottom(); + qreal len; + if (i % 5) + len = 2 * ppmm; + else if (i % 10) + len = 3 * ppmm; + else + len = h / 2; + + p.drawLine(QPointF(x, y), QPointF(x, y - len)); + if (i % 10 == 5) { + QRectF textR(0, 0, 5 * ppmm, h / 2 - 2 * ppmm); + textR.moveTopLeft(QPointF(x, vCenter)); + int n = i / 10 + 1; + if (n % 10 == 0) + p.setPen(Qt::red); + p.drawText(textR, Qt::AlignCenter, QString::number(n)); + p.setPen(linePen); + } + } + + //inches + for (int i = 0;;) { + i++; + qreal x = i * ppi / 16; + if (x > width()) + break; + qreal y = rulerRect.top(); + + qreal d = h / 10; + qreal len; + if (i % 2) + len = 1 * d; + else if (i % 4) + len = 2 * d; + else if (i % 8) + len = 3 * d; + else if (i % 16) + len = 4 * d; + else + len = h / 2; + + p.drawLine(QPointF(x, y), QPointF(x, y + len)); + if (i % 16 == 12) { + QRectF textR(0, 0, 0.25 * ppi, h / 2 - 2 * d); + textR.moveBottomLeft(QPointF(x, vCenter)); + p.drawText(textR, Qt::AlignCenter, QString::number(1 + i/16)); + } + } + +} + +int main(int argc, char **argv) +{ + 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" + "--interactive is a special option and opens a configuration" + " window."); + parser.addHelpOption(); + parser.addVersionOption(); + QCommandLineOption controllerOption("interactive", "Show configuration window."); + parser.addOption(controllerOption); + + + DemoContainerList demoList; + demoList << new DemoContainer<PixmapPainter>("pixmap", "Test pixmap painter"); + demoList << new DemoContainer<Labels>("label", "Test Labels"); + demoList << new DemoContainer<MainWindow>("mainwindow", "Test QMainWindow"); + demoList << new DemoContainer<StandardIcons>("standard-icons", "Test standard icons"); + demoList << new DemoContainer<Caching>("caching", "Test caching"); + demoList << new DemoContainer<Style>("styles", "Test style"); + demoList << new DemoContainer<Fonts>("fonts", "Test fonts"); + demoList << new DemoContainer<IconDrawing>("icondrawing", "Test icon drawing"); + demoList << new DemoContainer<Buttons>("buttons", "Test buttons"); + demoList << new DemoContainer<LinePainter>("linepainter", "Test line painting"); + demoList << new DemoContainer<DragWidget>("draganddrop", "Test drag and drop"); + demoList << new DemoContainer<CursorTester>("cursorpos", "Test cursor and window positioning"); + demoList << new DemoContainer<ScreenDisplayer>("screens", "Test screen and window positioning"); + demoList << new DemoContainer<PhysicalSizeTest>("physicalsize", "Test manual highdpi support using physicalDotsPerInch"); + + + foreach (DemoContainerBase *demo, demoList) + parser.addOption(demo->option()); + + parser.process(app); + + //controller takes ownership of all demos + DemoController controller(&demoList, &parser); + + if (parser.isSet(controllerOption) || argumentCount <= 1) + controller.show(); if (QApplication::topLevelWidgets().isEmpty()) parser.showHelp(0); return app.exec(); } + +#include "main.moc" diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 0a1987d647f4927a84815e528b8e78a53008509d..cffe76b2b41bc5fd9b3a05b8f4137e9b8b3c4d23 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -58,7 +58,7 @@ contains(QT_CONFIG, opengl) { win32 { SUBDIRS -= network_remote_stresstest network_stresstest # disable some tests on wince because of missing dependencies - wince*:SUBDIRS -= lance windowmodality + wince: SUBDIRS -= lance windowmodality } lessThan(QT_MAJOR_VERSION, 5): SUBDIRS -= bearerex lance qnetworkaccessmanager/qget qmimedatabase qnetworkreply \ diff --git a/tests/manual/widgets/itemviews/qheaderview/qheaderviewtest1.cpp b/tests/manual/widgets/itemviews/qheaderview/qheaderviewtest1.cpp index 1e26af8f5724921a7b994589bfa4d063eee9b85e..af11e2a098c3c956609cb92a211190e7fb77a709 100644 --- a/tests/manual/widgets/itemviews/qheaderview/qheaderviewtest1.cpp +++ b/tests/manual/widgets/itemviews/qheaderview/qheaderviewtest1.cpp @@ -140,10 +140,12 @@ private: QTableView *setupTableView() { tableView = new QTableView; - m.setRowCount(500); + const int rowCount = 200; + m.setRowCount(rowCount); m.setColumnCount(250); tableView->setSelectionMode(QAbstractItemView::SingleSelection); tableView->setModel(&m); + tableView->verticalHeader()->swapSections(rowCount - 1, 5); return tableView; } diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 3bf0546ac1628e8ab51979526bb102d1e8db8de8..c4455eeb63a62a144ba888c7c71d28545b64594c 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -169,7 +169,7 @@ Configure::Configure(int& argc, char** argv) dictionary[ "WMSDK" ] = "auto"; dictionary[ "QML_DEBUG" ] = "yes"; dictionary[ "PLUGIN_MANIFESTS" ] = "no"; - dictionary[ "DIRECTWRITE" ] = "no"; + dictionary[ "DIRECTWRITE" ] = "auto"; dictionary[ "DIRECT2D" ] = "no"; dictionary[ "NIS" ] = "no"; dictionary[ "NEON" ] = "auto"; @@ -2010,8 +2010,8 @@ bool Configure::displayHelp() desc("WMF_BACKEND", "yes","-wmf-backend", "Compile in the windows media foundation backend into Qt Multimedia.\n"); desc("QML_DEBUG", "no", "-no-qml-debug", "Do not build the in-process QML debugging support."); desc("QML_DEBUG", "yes", "-qml-debug", "Build the in-process QML debugging support.\n"); - desc("DIRECTWRITE", "no", "-no-directwrite", "Do not build support for DirectWrite font rendering."); - desc("DIRECTWRITE", "yes", "-directwrite", "Build support for DirectWrite font rendering (requires DirectWrite availability on target systems, e.g. Windows Vista with Platform Update, Windows 7, etc.)\n"); + desc("DIRECTWRITE", "no", "-no-directwrite", "Do not build support for DirectWrite font rendering."); + desc("DIRECTWRITE", "yes", "-directwrite", "Build support for DirectWrite font rendering.\n"); desc("DIRECT2D", "no", "-no-direct2d", "Do not build the Direct2D platform plugin."); desc("DIRECT2D", "yes", "-direct2d", "Build the Direct2D platform plugin (experimental,\n" @@ -2291,7 +2291,7 @@ bool Configure::checkAvailability(const QString &part) } else if (part == "WMF_BACKEND") { available = findFile("mfapi.h") && findFile("mf.lib"); } else if (part == "DIRECTWRITE") { - available = findFile("dwrite.h") && findFile("d2d1.h") && findFile("dwrite.lib"); + available = tryCompileProject("win/directwrite"); } else if (part == "DIRECT2D") { available = tryCompileProject("qpa/direct2d"); } else if (part == "ICONV") { @@ -2510,6 +2510,9 @@ void Configure::autoDetection() if (dictionary["FONT_CONFIG"] == "auto") dictionary["FONT_CONFIG"] = checkAvailability("FONT_CONFIG") ? "yes" : "no"; + if (dictionary["DIRECTWRITE"] == "auto") + dictionary["DIRECTWRITE"] = checkAvailability("DIRECTWRITE") ? "yes" : "no"; + // Mark all unknown "auto" to the default value.. for (QMap<QString,QString>::iterator i = dictionary.begin(); i != dictionary.end(); ++i) { if (i.value() == "auto") @@ -2907,6 +2910,9 @@ void Configure::generateOutputVars() if (dictionary["AUDIO_BACKEND"] == "yes") qtConfig += "audio-backend"; + if (dictionary["QML_DEBUG"] == "no") + qtConfig += "no-qml-debug"; + if (dictionary["WMF_BACKEND"] == "yes") qtConfig += "wmf-backend"; @@ -3621,7 +3627,6 @@ void Configure::generateConfigfiles() if (dictionary["OPENSSL"] == "no") qconfigList += "QT_NO_OPENSSL"; if (dictionary["OPENSSL"] == "linked") qconfigList += "QT_LINKED_OPENSSL"; if (dictionary["DBUS"] == "no") qconfigList += "QT_NO_DBUS"; - if (dictionary["QML_DEBUG"] == "no") qconfigList += "QT_NO_QML_DEBUGGER"; if (dictionary["FREETYPE"] == "no") qconfigList += "QT_NO_FREETYPE"; if (dictionary["HARFBUZZ"] == "no") qconfigList += "QT_NO_HARFBUZZ"; if (dictionary["NATIVE_GESTURES"] == "no") qconfigList += "QT_NO_NATIVE_GESTURES";