Merge remote-tracking branch 'origin/5.11' into dev

Change-Id: Iec636692e8b7d1fe1bc0476e49c5054a5892d639
This commit is contained in:
Qt Forward Merge Bot 2018-02-22 09:19:56 +01:00
commit 9f33b84b09
26 changed files with 303 additions and 1427 deletions

View File

@ -26,7 +26,7 @@
****************************************************************************/
/*!
\example json/savegame
\example serialization/savegame
\title JSON Save Game Example
\brief The JSON Save Game example demonstrates how to save and load a
@ -50,12 +50,12 @@
It provides read() and write() functions to serialise its member variables.
\snippet json/savegame/character.h 0
\snippet serialization/savegame/character.h 0
Of particular interest to us are the read and write function
implementations:
\snippet json/savegame/character.cpp 0
\snippet serialization/savegame/character.cpp 0
In the read() function, we assign Character's members values from the
QJsonObject argument. You can use either \l QJsonObject::operator[]() or
@ -64,7 +64,7 @@
check if the keys are valid before attempting to read them with
QJsonObject::contains().
\snippet json/savegame/character.cpp 1
\snippet serialization/savegame/character.cpp 1
In the write() function, we do the reverse of the read() function; assign
values from the Character object to the JSON object. As with accessing
@ -74,13 +74,13 @@
Next up is the Level class:
\snippet json/savegame/level.h 0
\snippet serialization/savegame/level.h 0
We want to have several levels in our game, each with several NPCs, so we
keep a QVector of Character objects. We also provide the familiar read() and
write() functions.
\snippet json/savegame/level.cpp 0
\snippet serialization/savegame/level.cpp 0
Containers can be written and read to and from JSON using QJsonArray. In our
case, we construct a QJsonArray from the value associated with the key
@ -94,7 +94,7 @@
element is used as the key to construct the container when reading it back
in.
\snippet json/savegame/level.cpp 1
\snippet serialization/savegame/level.cpp 1
Again, the write() function is similar to the read() function, except
reversed.
@ -102,7 +102,7 @@
Having established the Character and Level classes, we can move on to
the Game class:
\snippet json/savegame/game.h 0
\snippet serialization/savegame/game.h 0
First of all, we define the \c SaveFormat enum. This will allow us to
specify the format in which the game should be saved: \c Json or \c Binary.
@ -112,12 +112,12 @@
The read() and write() functions are used by saveGame() and loadGame().
\snippet json/savegame/game.cpp 0
\snippet serialization/savegame/game.cpp 0
To setup a new game, we create the player and populate the levels and their
NPCs.
\snippet json/savegame/game.cpp 1
\snippet serialization/savegame/game.cpp 1
The first thing we do in the read() function is tell the player to read
itself. We then clear the level array so that calling loadGame() on the
@ -125,11 +125,11 @@
We then populate the level array by reading each Level from a QJsonArray.
\snippet json/savegame/game.cpp 2
\snippet serialization/savegame/game.cpp 2
We write the game to JSON similarly to how we write Level.
\snippet json/savegame/game.cpp 3
\snippet serialization/savegame/game.cpp 3
When loading a saved game in loadGame(), the first thing we do is open the
save file based on which format it was saved to; \c "save.json" for JSON,
@ -144,7 +144,7 @@
After constructing the QJsonDocument, we instruct the Game object to read
itself and then return \c true to indicate success.
\snippet json/savegame/game.cpp 4
\snippet serialization/savegame/game.cpp 4
Not surprisingly, saveGame() looks very much like loadGame(). We determine
the file extension based on the format, print a warning and return \c false
@ -155,7 +155,7 @@
We are now ready to enter main():
\snippet json/savegame/main.cpp 0
\snippet serialization/savegame/main.cpp 0
Since we're only interested in demonstrating \e serialization of a game with
JSON, our game is not actually playable. Therefore, we only need
@ -169,7 +169,7 @@
assume that the player had a great time and made lots of progress, altering
the internal state of our Character, Level and Game objects.
\snippet json/savegame/main.cpp 1
\snippet serialization/savegame/main.cpp 1
When the player has finished, we save their game. For demonstration
purposes, we can serialize to either JSON or binary. You can examine the

View File

@ -0,0 +1,82 @@
#
# This file is used as a basis for the following compilers, when targeting
# MinGW-w64:
#
# - GCC
# - Clang
#
# Compiler-specific settings go into win32-g++/qmake.conf and
# win32-clang-g++/qmake.conf
#
load(device_config)
include(gcc-base.conf)
include(g++-base.conf)
# modifications to gcc-base.conf and g++-base.conf
MAKEFILE_GENERATOR = MINGW
QMAKE_PLATFORM = win32 mingw
CONFIG += debug_and_release debug_and_release_target precompile_header
DEFINES += UNICODE _UNICODE WIN32
QMAKE_COMPILER_DEFINES += __GNUC__ _WIN32
# can't add 'DEFINES += WIN64' and 'QMAKE_COMPILER_DEFINES += _WIN64' defines for
# x86_64 platform similar to 'msvc-desktop.conf' toolchain, because, unlike for MSVC,
# 'QMAKE_TARGET.arch' is inherently unavailable.
QMAKE_LEX = flex
QMAKE_LEXFLAGS =
QMAKE_YACC = bison -y
QMAKE_YACCFLAGS = -d
QMAKE_CFLAGS_SSE2 += -mstackrealign
QMAKE_CXXFLAGS_RTTI_ON = -frtti
QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti
QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads
QMAKE_INCDIR =
QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src
QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src
QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads
QMAKE_LFLAGS_RELEASE = -Wl,-s
QMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console
QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows
QMAKE_LFLAGS_DLL = -shared
QMAKE_LFLAGS_GCSECTIONS = -Wl,--gc-sections
equals(QMAKE_HOST.os, Windows) {
QMAKE_LINK_OBJECT_MAX = 10
QMAKE_LINK_OBJECT_SCRIPT = object_script
}
QMAKE_EXT_OBJ = .o
QMAKE_EXT_RES = _res.o
QMAKE_PREFIX_SHLIB =
QMAKE_EXTENSION_SHLIB = dll
QMAKE_PREFIX_STATICLIB = lib
QMAKE_EXTENSION_STATICLIB = a
QMAKE_LIB_EXTENSIONS = a dll.a
QMAKE_LIBS =
QMAKE_LIBS_GUI = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lws2_32 -lole32 -luuid -luser32 -ladvapi32
QMAKE_LIBS_NETWORK = -lws2_32
QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32
QMAKE_LIBS_OPENGL_ES2 = -lgdi32 -luser32
QMAKE_LIBS_OPENGL_ES2_DEBUG = -lgdi32 -luser32
QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32
QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain
QMAKE_IDL = midl
QMAKE_LIB = $${CROSS_COMPILE}ar -rc
QMAKE_RC = $${CROSS_COMPILE}windres
QMAKE_STRIP = $${CROSS_COMPILE}strip
QMAKE_STRIPFLAGS_LIB += --strip-unneeded
QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy
QMAKE_NM = $${CROSS_COMPILE}nm -P
include(angle.conf)
include(windows-vulkan.conf)

View File

@ -44,7 +44,7 @@ contains(TEMPLATE, .*app): \
for(ex, EXAMPLE_FILES): \
sourcefiles += $$files($$absolute_path($$ex, $$_PRO_FILE_PWD_))
for(res, RESOURCES) {
!contains(res, \\.qrc$): \
!contains(res, .*\\.qrc): \
next()
rfile = $$absolute_path($$res, $$_PRO_FILE_PWD_)
rpath = $$dirname(rfile)

View File

@ -7,84 +7,21 @@
# configure -xplatform win32-clang-g++ -device-option CROSS_COMPILE=x86_64-w64-mingw32-
#
load(device_config)
include(../common/gcc-base.conf)
include(../common/g++-base.conf)
include(../common/angle.conf)
include(../common/windows-vulkan.conf)
include(../common/g++-win32.conf)
# modifications to gcc-base.conf and g++-base.conf
# modifications to g++-win32.conf
MAKEFILE_GENERATOR = MINGW
QMAKE_PLATFORM = win32 mingw
CONFIG += debug_and_release debug_and_release_target precompile_header
DEFINES += UNICODE _UNICODE WIN32
QMAKE_COMPILER = gcc clang llvm # clang pretends to be gcc
QMAKE_COMPILER_DEFINES += __GNUC__ _WIN32
# can't add 'DEFINES += WIN64' and 'QMAKE_COMPILER_DEFINES += _WIN64' defines for
# x86_64 platform similar to 'msvc-desktop.conf' toolchain, because, unlike for MSVC,
# 'QMAKE_TARGET.arch' is inherently unavailable.
QMAKE_COMPILER += clang llvm # clang pretends to be gcc
QMAKE_CC = $${CROSS_COMPILE}clang
QMAKE_LEX = flex
QMAKE_LEXFLAGS =
QMAKE_YACC = bison -y
QMAKE_YACCFLAGS = -d
QMAKE_CFLAGS +=
QMAKE_CFLAGS_WARN_ON += -Wextra -Wno-ignored-attributes
QMAKE_CFLAGS_SSE2 += -mstackrealign
QMAKE_CXX = $${CROSS_COMPILE}clang++
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
QMAKE_CXXFLAGS +=
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_RTTI_ON = -frtti
QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti
QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads
QMAKE_INCDIR =
QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src
QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src
QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
QMAKE_LINK = $${CROSS_COMPILE}clang++
QMAKE_LINK_C = $${CROSS_COMPILE}clang
QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads
QMAKE_LFLAGS_RELEASE = -Wl,-s
QMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console
QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows
QMAKE_LFLAGS_DLL = -shared
QMAKE_LFLAGS_GCSECTIONS = -Wl,--gc-sections
equals(QMAKE_HOST.os, Windows) {
QMAKE_LINK_OBJECT_MAX = 10
QMAKE_LINK_OBJECT_SCRIPT = object_script
}
QMAKE_EXT_OBJ = .o
QMAKE_EXT_RES = _res.o
QMAKE_PREFIX_SHLIB =
QMAKE_EXTENSION_SHLIB = dll
QMAKE_PREFIX_STATICLIB = lib
QMAKE_EXTENSION_STATICLIB = a
QMAKE_LIB_EXTENSIONS = a dll.a
QMAKE_LIBS =
QMAKE_LIBS_GUI = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lws2_32 -lole32 -luuid -luser32 -ladvapi32
QMAKE_LIBS_NETWORK = -lws2_32
QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32
QMAKE_LIBS_OPENGL_ES2 = -lgdi32 -luser32
QMAKE_LIBS_OPENGL_ES2_DEBUG = -lgdi32 -luser32
QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32
QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain
QMAKE_IDL = midl
QMAKE_LIB = $${CROSS_COMPILE}ar -rc
QMAKE_RC = $${CROSS_COMPILE}windres
QMAKE_STRIP = $${CROSS_COMPILE}strip
QMAKE_STRIPFLAGS_LIB += --strip-unneeded
QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy
QMAKE_NM = $${CROSS_COMPILE}nm -P
load(qt_config)

View File

@ -7,83 +7,19 @@
# configure -xplatform win32-g++ -device-option CROSS_COMPILE=i686-w64-mingw32-
#
load(device_config)
include(../common/gcc-base.conf)
include(../common/g++-base.conf)
include(../common/angle.conf)
include(../common/windows-vulkan.conf)
include(../common/g++-win32.conf)
# modifications to gcc-base.conf and g++-base.conf
MAKEFILE_GENERATOR = MINGW
QMAKE_PLATFORM = win32 mingw
CONFIG += debug_and_release debug_and_release_target precompile_header
DEFINES += UNICODE _UNICODE WIN32
QMAKE_COMPILER_DEFINES += __GNUC__ _WIN32
# can't add 'DEFINES += WIN64' and 'QMAKE_COMPILER_DEFINES += _WIN64' defines for
# x86_64 platform similar to 'msvc-desktop.conf' toolchain, because, unlike for MSVC,
# 'QMAKE_TARGET.arch' is inherently unavailable.
# modifications to g++-win32.conf
QMAKE_CC = $${CROSS_COMPILE}gcc
QMAKE_LEX = flex
QMAKE_LEXFLAGS =
QMAKE_YACC = bison -y
QMAKE_YACCFLAGS = -d
QMAKE_CFLAGS += -fno-keep-inline-dllexport
QMAKE_CFLAGS_WARN_ON += -Wextra
QMAKE_CFLAGS_SSE2 += -mstackrealign
QMAKE_CXX = $${CROSS_COMPILE}g++
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_RTTI_ON = -frtti
QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti
QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads
QMAKE_INCDIR =
QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src
QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src
QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
QMAKE_LINK = $${CROSS_COMPILE}g++
QMAKE_LINK_C = $${CROSS_COMPILE}gcc
QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads
QMAKE_LFLAGS_RELEASE = -Wl,-s
QMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console
QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows
QMAKE_LFLAGS_DLL = -shared
QMAKE_LFLAGS_GCSECTIONS = -Wl,--gc-sections
equals(QMAKE_HOST.os, Windows) {
QMAKE_LINK_OBJECT_MAX = 10
QMAKE_LINK_OBJECT_SCRIPT = object_script
}
QMAKE_EXT_OBJ = .o
QMAKE_EXT_RES = _res.o
QMAKE_PREFIX_SHLIB =
QMAKE_EXTENSION_SHLIB = dll
QMAKE_PREFIX_STATICLIB = lib
QMAKE_EXTENSION_STATICLIB = a
QMAKE_LIB_EXTENSIONS = a dll.a
QMAKE_LIBS =
QMAKE_LIBS_GUI = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lws2_32 -lole32 -luuid -luser32 -ladvapi32
QMAKE_LIBS_NETWORK = -lws2_32
QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32
QMAKE_LIBS_OPENGL_ES2 = -lgdi32 -luser32
QMAKE_LIBS_OPENGL_ES2_DEBUG = -lgdi32 -luser32
QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32
QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain
QMAKE_IDL = midl
QMAKE_LIB = $${CROSS_COMPILE}ar -rc
QMAKE_RC = $${CROSS_COMPILE}windres
QMAKE_STRIP = $${CROSS_COMPILE}strip
QMAKE_STRIPFLAGS_LIB += --strip-unneeded
QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy
QMAKE_NM = $${CROSS_COMPILE}nm -P
load(qt_config)

View File

@ -45,7 +45,7 @@
access.
More details about the JSON data format can be found at \l{http://json.org}{json.org}
and in \l{https://tools.ietf.org/html/rfc7159}{RFC-7159}.
and in \l{http://tools.ietf.org/html/rfc4627}{RFC-4627}.
\tableofcontents

View File

@ -549,7 +549,7 @@ using qsizetype = QIntegerForSizeof<std::size_t>::Signed;
# define Q_ALWAYS_INLINE inline
#endif
#ifdef Q_CC_GNU
#if defined(Q_CC_GNU) && defined(Q_OS_WIN)
# define QT_INIT_METAOBJECT __attribute__((init_priority(101)))
#else
# define QT_INIT_METAOBJECT

File diff suppressed because it is too large Load Diff

View File

@ -315,7 +315,7 @@ void QBitArray::fill(bool value, int begin, int end)
\since 5.11
Creates a QBitArray with the dense bit array located at \a data, with \a
len bits. The byte array at \a data must be at least \a size / 8 (rounded up)
size bits. The byte array at \a data must be at least \a size / 8 (rounded up)
bytes long.
If \a size is not a multiple of 8, this function will include the lowest

View File

@ -161,10 +161,26 @@ bool QOpenGLProgramBinaryCache::setProgramBinary(uint programId, uint blobFormat
QOpenGLExtraFunctions *funcs = QOpenGLContext::currentContext()->extraFunctions();
while (funcs->glGetError() != GL_NO_ERROR) { }
funcs->glProgramBinary(programId, blobFormat, p, blobSize);
int err = funcs->glGetError();
GLenum err = funcs->glGetError();
if (err != GL_NO_ERROR) {
qCDebug(DBG_SHADER_CACHE, "Program binary failed to load for program %u, size %d, "
"format 0x%x, err = 0x%x",
programId, blobSize, blobFormat, err);
return false;
}
GLint linkStatus = 0;
funcs->glGetProgramiv(programId, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE) {
qCDebug(DBG_SHADER_CACHE, "Program binary failed to load for program %u, size %d, "
"format 0x%x, linkStatus = 0x%x, err = 0x%x",
programId, blobSize, blobFormat, linkStatus, err);
return false;
}
qCDebug(DBG_SHADER_CACHE, "Program binary set for program %u, size %d, format 0x%x, err = 0x%x",
programId, blobSize, blobFormat, err);
return err == 0;
return true;
}
#ifdef Q_OS_UNIX

View File

@ -3824,13 +3824,7 @@ bool QOpenGLShaderProgramPrivate::linkBinary()
bool needsCompile = true;
if (binCache.load(cacheKey, q->programId())) {
qCDebug(DBG_SHADER_CACHE, "Program binary received from cache");
linkBinaryRecursion = true;
bool ok = q->link();
linkBinaryRecursion = false;
if (ok)
needsCompile = false;
else
qCDebug(DBG_SHADER_CACHE, "Link failed after glProgramBinary");
needsCompile = false;
}
bool needsSave = false;

View File

@ -46,6 +46,7 @@
#include "private/qnoncontiguousbytedevice_p.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QDateTime>
QT_BEGIN_NAMESPACE

View File

@ -889,7 +889,7 @@ QMap<QByteArray, QVariant> QSslConfiguration::backendConfig() const
/*!
\since 5.11
Sets an option in the backend-specific configuration.
Sets the option \a name in the backend-specific configuration to \a value.
Options supported by the OpenSSL (>= 1.0.2) backend are available in the \l
{https://www.openssl.org/docs/manmaster/man3/SSL_CONF_cmd.html#SUPPORTED-CONFIGURATION-FILE-COMMANDS}

View File

@ -237,6 +237,7 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
default:
break;
}
break;
case WM_GETOBJECT:
return QtWindows::AccessibleObjectFromWindowRequest;
case WM_SETFOCUS:

View File

@ -41,6 +41,7 @@
#include <QtTest/qtestassert.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qstring.h>
#include <stdio.h>
#include <stdlib.h>
@ -121,6 +122,29 @@ void QAbstractTestLogger::stopLogging()
{
}
void QAbstractTestLogger::addMessage(QtMsgType type, const QMessageLogContext &context,
const QString &message)
{
QAbstractTestLogger::MessageTypes messageType = [=]() {
switch (type) {
case QtDebugMsg: return QAbstractTestLogger::QDebug;
case QtInfoMsg: return QAbstractTestLogger::QInfo;
case QtCriticalMsg: return QAbstractTestLogger::QSystem;
case QtWarningMsg: return QAbstractTestLogger::QWarning;
case QtFatalMsg: return QAbstractTestLogger::QFatal;
}
Q_UNREACHABLE();
return QAbstractTestLogger::QFatal;
}();
QString formattedMessage = qFormatLogMessage(type, context, message);
// Note that we explicitly ignore the file and line of the context here,
// as that's what QTest::messageHandler used to do when calling the same
// overload directly.
addMessage(messageType, formattedMessage);
}
namespace QTest
{

View File

@ -95,6 +95,9 @@ public:
const char *file = 0, int line = 0) = 0;
virtual void addBenchmarkResult(const QBenchmarkResult &result) = 0;
virtual void addMessage(QtMsgType, const QMessageLogContext &,
const QString &);
virtual void addMessage(MessageTypes type, const QString &message,
const char *file = 0, int line = 0) = 0;

View File

@ -398,6 +398,11 @@ void QPlainTestLogger::addBenchmarkResult(const QBenchmarkResult &result)
printBenchmarkResult(result);
}
void QPlainTestLogger::addMessage(QtMsgType type, const QMessageLogContext &context, const QString &message)
{
QAbstractTestLogger::addMessage(type, context, message);
}
void QPlainTestLogger::addMessage(MessageTypes type, const QString &message,
const char *file, int line)
{

View File

@ -71,6 +71,9 @@ public:
const char *file = 0, int line = 0) override;
void addBenchmarkResult(const QBenchmarkResult &result) override;
void addMessage(QtMsgType, const QMessageLogContext &,
const QString &) override;
void addMessage(MessageTypes type, const QString &message,
const char *file = 0, int line = 0) override;

View File

@ -220,6 +220,12 @@ namespace QTest {
FOREACH_LOGGER(logger->addBenchmarkResult(result));
}
static void addMessage(QtMsgType type, const QMessageLogContext &context,
const QString &message)
{
FOREACH_LOGGER(logger->addMessage(type, context, message));
}
static void addMessage(QAbstractTestLogger::MessageTypes type, const QString &message,
const char *file = 0, int line = 0)
{
@ -289,11 +295,10 @@ namespace QTest {
QTEST_ASSERT(QTest::TestLoggers::loggerCount() != 0);
}
if (handleIgnoredMessage(type, message))
if (handleIgnoredMessage(type, message)) {
// the message is expected, so just swallow it.
return;
QString msg = qFormatLogMessage(type, context, message);
}
if (type != QtFatalMsg) {
if (counter.load() <= 0)
@ -306,22 +311,10 @@ namespace QTest {
}
}
switch (type) {
case QtDebugMsg:
QTest::TestLoggers::addMessage(QAbstractTestLogger::QDebug, msg);
break;
case QtInfoMsg:
QTest::TestLoggers::addMessage(QAbstractTestLogger::QInfo, msg);
break;
case QtCriticalMsg:
QTest::TestLoggers::addMessage(QAbstractTestLogger::QSystem, msg);
break;
case QtWarningMsg:
QTest::TestLoggers::addMessage(QAbstractTestLogger::QWarning, msg);
break;
case QtFatalMsg:
QTest::TestLoggers::addMessage(QAbstractTestLogger::QFatal, msg);
/* Right now, we're inside the custom message handler and we're
QTest::TestLoggers::addMessage(type, context, message);
if (type == QtFatalMsg) {
/* Right now, we're inside the custom message handler and we're
* being qt_message_output in qglobal.cpp. After we return from
* this function, it will proceed with calling exit() and abort()
* and hence crash. Therefore, we call these logging functions such
@ -329,7 +322,6 @@ namespace QTest {
QTestResult::addFailure("Received a fatal error.", "Unknown file", 0);
QTestLog::leaveTestFunction();
QTestLog::stopLogging();
break;
}
}
}

View File

@ -1836,7 +1836,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title)
"<p>Qt and the Qt logo are trademarks of The Qt Company Ltd.</p>"
"<p>Qt is The Qt Company Ltd product developed as an open source "
"project. See <a href=\"http://%3/\">%3</a> for more information.</p>"
).arg(QStringLiteral("2017"),
).arg(QStringLiteral("2018"),
QStringLiteral("qt.io/licensing"),
QStringLiteral("qt.io"));
QMessageBox *msgBox = new QMessageBox(parent);

View File

@ -2168,15 +2168,19 @@ void QHeaderViewPrivate::_q_sectionsAboutToBeChanged()
sectionItems[visual].size = lastSectionSize;
}
for (int i = 0; i < sectionItems.size(); ++i) {
const auto &s = sectionItems.at(i);
auto s = sectionItems.at(i);
// only add if the section is not default and not visually moved
if (s.size == defaultSectionSize && !s.isHidden && s.resizeMode == globalResizeMode)
continue;
const int logical = logicalIndex(i);
if (s.isHidden)
s.size = hiddenSectionSize.value(logical);
// ### note that we are using column or row 0
layoutChangePersistentSections.append({orientation == Qt::Horizontal
? model->index(0, logicalIndex(i), root)
: model->index(logicalIndex(i), 0, root),
? model->index(0, logical, root)
: model->index(logical, 0, root),
s});
if (layoutChangePersistentSections.size() > 1000)
@ -2201,6 +2205,30 @@ void QHeaderViewPrivate::_q_sectionsChanged()
return;
}
bool hasPersistantIndexes = false;
for (const auto &item : oldPersistentSections) {
if (item.index.isValid()) {
hasPersistantIndexes = true;
break;
}
}
// Though far from perfect we here try to retain earlier/existing behavior
// ### See QHeaderViewPrivate::_q_layoutAboutToBeChanged()
// When we don't have valid hasPersistantIndexes it can be due to
// - all sections are default sections
// - the row/column 0 which is used for persistent indexes is gone
// - all non-default sections were removed
// case one is trivial, in case two we assume nothing else changed (it's the best
// guess we can do - everything else can not be handled correctly for now)
// case three can not be handled correctly with layoutChanged - removeSections
// should be used instead for this
if (!hasPersistantIndexes) {
if (oldCount != newCount)
q->initializeSections();
return;
}
// adjust section size
if (newCount != oldCount) {
const int min = qBound(0, oldCount, newCount - 1);

View File

@ -222,8 +222,10 @@ void tst_QMimeDatabase::mimeTypeForName()
qWarning() << "ls not found";
else {
const QString executableType = QString::fromLatin1("application/x-executable");
const QString sharedLibType = QString::fromLatin1("application/x-sharedlib");
//QTest::newRow("executable") << exePath << executableType;
QCOMPARE(db.mimeTypeForFile(exePath).name(), executableType);
QVERIFY(db.mimeTypeForFile(exePath).name() == executableType ||
db.mimeTypeForFile(exePath).name() == sharedLibType);
}
#endif

View File

@ -2711,10 +2711,9 @@ void tst_QSqlQuery::lastInsertId()
QSqlQuery q( db );
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
// PostgreSQL >= 8.1 relies on lastval() which does not work if a value is
// manually inserted to the serial field, so we create a table specifically
if (dbType == QSqlDriver::PostgreSQL) {
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL) {
const auto tst_lastInsertId = qTableName("tst_lastInsertId", __FILE__, db);
tst_Databases::safeDropTable(db, tst_lastInsertId);
QVERIFY_SQL(q, exec(QStringLiteral("create table ") + tst_lastInsertId +
@ -3681,6 +3680,8 @@ void tst_QSqlQuery::QTBUG_5251()
QSqlTableModel timetestModel(0,db);
timetestModel.setEditStrategy(QSqlTableModel::OnManualSubmit);
timetestModel.setTable(timetest);
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL)
QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort);
QVERIFY_SQL(timetestModel, select());
QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"), QString("01:02:03.666"));

View File

@ -1547,6 +1547,8 @@ void tst_QSqlRelationalTableModel::relationOnFirstColumn()
//modify the model data
QVERIFY_SQL(model, setData(model.index(0, 0), 40));
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL)
QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort);
QVERIFY_SQL(model, submit());
QVERIFY_SQL(model, setData(model.index(1, 0), 50));
QVERIFY_SQL(model, submit());

View File

@ -360,6 +360,8 @@ void tst_QSqlTableModel::selectRow()
q.exec("UPDATE " + tbl + " SET a = 'Qt' WHERE id = 1");
QCOMPARE(model.data(idx).toString(), QString("b"));
model.selectRow(1);
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL)
QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort);
QCOMPARE(model.data(idx).toString(), QString("Qt"));
// Check if selectRow() refreshes a changed row.
@ -416,6 +418,8 @@ void tst_QSqlTableModel::selectRowOverride()
// both rows should have changed
QCOMPARE(model.data(idx).toString(), QString("Qt"));
idx = model.index(2, 1);
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL)
QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort);
QCOMPARE(model.data(idx).toString(), QString("Qt"));
q.exec("DELETE FROM " + tbl);
@ -826,6 +830,9 @@ void tst_QSqlTableModel::insertRowFailure()
values.setGenerated(1, true);
// populate 1 row
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::PostgreSQL && submitpolicy != QSqlTableModel::OnManualSubmit)
QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort);
QVERIFY_SQL(model, insertRecord(0, values));
QVERIFY_SQL(model, submitAll());
QVERIFY_SQL(model, select());
@ -869,6 +876,8 @@ void tst_QSqlTableModel::insertRowFailure()
// restore empty table
model.revertAll();
QVERIFY_SQL(model, removeRow(0));
if (dbType == QSqlDriver::PostgreSQL)
QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort);
QVERIFY_SQL(model, submitAll());
QVERIFY_SQL(model, select());
QCOMPARE(model.rowCount(), 0);
@ -1977,6 +1986,8 @@ void tst_QSqlTableModel::tableModifyWithBlank()
//Should be equivalent to QSqlQuery INSERT INTO... command)
QVERIFY_SQL(model, insertRow(0));
QVERIFY_SQL(model, setData(model.index(0,0),timeString));
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL)
QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort);
QVERIFY_SQL(model, submitAll());
//set a filter on the table so the only record we get is the one we just made

View File

@ -206,6 +206,7 @@ private slots:
void task248050_hideRow();
void QTBUG6058_reset();
void QTBUG7833_sectionClicked();
void checkLayoutChangeEmptyModel();
void QTBUG8650_crashOnInsertSections();
void QTBUG12268_hiddenMovedSectionSorting();
void QTBUG14242_hideSectionAutoSize();
@ -286,6 +287,13 @@ public:
endInsertColumns();
}
void removeFirstRow()
{
beginRemoveRows(QModelIndex(), 0, 0);
--rows;
endRemoveRows();
}
void removeLastRow()
{
beginRemoveRows(QModelIndex(), rows - 1, rows - 1);
@ -328,6 +336,24 @@ public:
emit layoutChanged();
}
void emitLayoutChanged()
{
emit layoutAboutToBeChanged();
emit layoutChanged();
}
void emitLayoutChangedWithRemoveFirstRow()
{
emit layoutAboutToBeChanged();
QModelIndexList milNew;
const auto milOld = persistentIndexList();
milNew.reserve(milOld.size());
for (int i = 0; i < milOld.size(); ++i)
milNew += QModelIndex();
changePersistentIndexList(milOld, milNew);
emit layoutChanged();
}
int cols, rows;
mutable bool wrongIndex;
};
@ -2286,7 +2312,9 @@ void tst_QHeaderView::QTBUG7833_sectionClicked()
tv.setModel(proxyModel);
const int section4Size = tv.horizontalHeader()->sectionSize(4) + 1;
const int section5Size = section4Size + 1;
tv.horizontalHeader()->resizeSection(4, section4Size);
tv.horizontalHeader()->resizeSection(5, section5Size);
tv.setColumnHidden(5, true);
tv.setColumnHidden(6, true);
tv.horizontalHeader()->swapSections(8, 10);
@ -2298,6 +2326,9 @@ void tst_QHeaderView::QTBUG7833_sectionClicked()
QCOMPARE(tv.horizontalHeader()->logicalIndex(8), 10);
QCOMPARE(tv.horizontalHeader()->logicalIndex(10), 8);
QCOMPARE(tv.horizontalHeader()->sectionSize(4), section4Size);
tv.setColumnHidden(5, false); // unhide, section size must be properly restored
QCOMPARE(tv.horizontalHeader()->sectionSize(5), section5Size);
tv.setColumnHidden(5, true);
QSignalSpy clickedSpy(tv.horizontalHeader(), SIGNAL(sectionClicked(int)));
QSignalSpy pressedSpy(tv.horizontalHeader(), SIGNAL(sectionPressed(int)));
@ -2327,6 +2358,51 @@ void tst_QHeaderView::QTBUG7833_sectionClicked()
QCOMPARE(pressedSpy.at(2).at(0).toInt(), 0);
}
void tst_QHeaderView::checkLayoutChangeEmptyModel()
{
QtTestModel tm;
tm.cols = 11;
QTableView tv;
tv.setModel(&tm);
const int section4Size = tv.horizontalHeader()->sectionSize(4) + 1;
const int section5Size = section4Size + 1;
tv.horizontalHeader()->resizeSection(4, section4Size);
tv.horizontalHeader()->resizeSection(5, section5Size);
tv.setColumnHidden(5, true);
tv.setColumnHidden(6, true);
tv.horizontalHeader()->swapSections(8, 10);
tv.sortByColumn(1, Qt::AscendingOrder);
tm.emitLayoutChanged();
QCOMPARE(tv.isColumnHidden(5), true);
QCOMPARE(tv.isColumnHidden(6), true);
QCOMPARE(tv.horizontalHeader()->sectionsMoved(), true);
QCOMPARE(tv.horizontalHeader()->logicalIndex(8), 10);
QCOMPARE(tv.horizontalHeader()->logicalIndex(10), 8);
QCOMPARE(tv.horizontalHeader()->sectionSize(4), section4Size);
tv.setColumnHidden(5, false); // unhide, section size must be properly restored
QCOMPARE(tv.horizontalHeader()->sectionSize(5), section5Size);
tv.setColumnHidden(5, true);
// adjust
tm.rows = 3;
tm.emitLayoutChanged();
// remove the row used for QPersistenModelIndexes
tm.emitLayoutChangedWithRemoveFirstRow();
QCOMPARE(tv.isColumnHidden(5), true);
QCOMPARE(tv.isColumnHidden(6), true);
QCOMPARE(tv.horizontalHeader()->sectionsMoved(), true);
QCOMPARE(tv.horizontalHeader()->logicalIndex(8), 10);
QCOMPARE(tv.horizontalHeader()->logicalIndex(10), 8);
QCOMPARE(tv.horizontalHeader()->sectionSize(4), section4Size);
tv.setColumnHidden(5, false); // unhide, section size must be properly restored
QCOMPARE(tv.horizontalHeader()->sectionSize(5), section5Size);
tv.setColumnHidden(5, true);
}
void tst_QHeaderView::QTBUG8650_crashOnInsertSections()
{
QStringList headerLabels;