summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config_help.txt3
-rw-r--r--dist/changes-5.10.1154
-rw-r--r--doc/src/images/borderlayout-example.pngbin6163 -> 9126 bytes
-rw-r--r--examples/widgets/doc/src/borderlayout.qdoc28
-rw-r--r--examples/widgets/doc/src/editabletreemodel.qdoc30
-rw-r--r--mkspecs/features/resources.prf2
-rw-r--r--src/concurrent/qtconcurrentmedian.h1
-rw-r--r--src/corelib/thread/qthread_unix.cpp13
-rw-r--r--src/corelib/tools/qstring.cpp9
-rw-r--r--src/gui/kernel/qguiapplication.cpp87
-rw-r--r--src/platformsupport/windowsuiautomation/uiaattributeids_p.h11
-rw-r--r--src/platformsupport/windowsuiautomation/uiaclientinterfaces_p.h11
-rw-r--r--src/platformsupport/windowsuiautomation/uiacontroltypeids_p.h11
-rw-r--r--src/platformsupport/windowsuiautomation/uiaerrorids_p.h11
-rw-r--r--src/platformsupport/windowsuiautomation/uiaeventids_p.h11
-rw-r--r--src/platformsupport/windowsuiautomation/uiageneralids_p.h11
-rw-r--r--src/platformsupport/windowsuiautomation/uiapatternids_p.h11
-rw-r--r--src/platformsupport/windowsuiautomation/uiapropertyids_p.h11
-rw-r--r--src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h11
-rw-r--r--src/platformsupport/windowsuiautomation/uiatypes_p.h11
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm6
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp3
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql.cpp11
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp25
-rw-r--r--src/widgets/graphicsview/qgraphicsitem_p.h1
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.cpp26
-rw-r--r--tests/auto/corelib/tools/qstring/tst_qstring.cpp8
-rw-r--r--tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp121
-rw-r--r--tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp33
-rw-r--r--tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp2
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp225
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp76
-rw-r--r--tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp1
-rw-r--r--tests/benchmarks/sql/kernel/kernel.pro1
-rw-r--r--tests/benchmarks/sql/kernel/qsqlrecord/qsqlrecord.pro5
-rw-r--r--tests/benchmarks/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp191
36 files changed, 922 insertions, 250 deletions
diff --git a/config_help.txt b/config_help.txt
index 4be797cc6b..f61601ec7a 100644
--- a/config_help.txt
+++ b/config_help.txt
@@ -274,7 +274,8 @@ Gui, printing, widget options:
(Windows only)
-combined-angle-lib .. Merge LibEGL and LibGLESv2 into LibANGLE (Windows only)
- -qpa <name> .......... Select default QPA backend (e.g., xcb, cocoa, windows)
+ -qpa <name> .......... Select default QPA backend(s) (e.g., xcb, cocoa, windows)
+ A prioritized list separated by semi-colons.
-xcb-xlib............. Enable Xcb-Xlib support [auto]
Platform backends:
diff --git a/dist/changes-5.10.1 b/dist/changes-5.10.1
new file mode 100644
index 0000000000..1c9854fa64
--- /dev/null
+++ b/dist/changes-5.10.1
@@ -0,0 +1,154 @@
+Qt 5.10.1 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.10.0.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+http://doc.qt.io/qt-5/index.html
+
+The Qt version 5.10 series is binary compatible with the 5.9.x series.
+Applications compiled for 5.9 will continue to run with 5.10.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+This release contains all fixes included in the Qt 5.9.4 release.
+
+****************************************************************************
+* Library *
+****************************************************************************
+
+QtCore
+------
+
+ - [QTBUG-64529] Fixed a compilation issue with qfloat16 if AVX2 support is
+ enabled in the compiler. Since all processors that support AVX2 also
+ support F16C, for GCC and Clang it is recommended to either add -mf16c
+ to your build or to use the corresponding -march= switch.
+
+ - QCoreApplication:
+ * [QTBUG-58919] Fixed a crash if QCoreApplication is recreated on Windows
+ and the passed argv parameter is different.
+
+ - QFile:
+ * [QTBUG-64103] Fixed a regression in doing rename() on Android
+ Marshmallow.
+
+ - QFileInfo:
+ * [QTBUG-30148] Fixed isWritable() on Windows to return whether the given
+ file is writable only under current privilege levels. Previously, the
+ result would take into account privilege elevation.
+
+ - QMetaObject:
+ * [QTBUG-65462] Fixed a memory leak that happened when the new-style
+ call to invokeMethod() was used.
+
+ - QObject:
+ * [QTBUG-65712] Improved performance of QObject::deleteLater.
+ * Fixed a crash that could happen if the context QObject pointer passed to
+ new-style connect() was null.
+
+ - QPluginLoader:
+ * [QTBUG-65197] Fixed a bug that would cause the Qt plugin scanning
+ system to allocate too much memory and possibly crash the process.
+
+ - QProcess:
+ * [QTBUG-65076] Fixed a regression that made QProcess be unable to find
+ executables when the PATH environment variable on some Unix systems
+ wasn't set. This behavior should not be relied upon since many systems
+ do not have sensible fallback values for PATH.
+
+ - QRandomGenerator:
+ * [QTBUG-65414] Fixed compilation on Windows if the windows.h header was
+ included before this qrandom.h.
+
+ - QSettings:
+ * [QTBUG-64121] Fixed reading from NTFS symbolic links.
+
+ - QStandardPaths:
+ * [QTBUG-65076] findExecutable() will now apply the default value for
+ the PATH environment variable (as returned by the POSIX confstr(3)
+ function or found in <paths.h>) if the variable isn't set in the
+ environment.
+ * [QTBUG-65687] Fixed a memory leak with displayName() on Apple platforms.
+ * On Windows, it is now possible to resolve configuration paths even
+ without QCoreApplication created.
+
+ - QString:
+ * [QTBUG-65939] Fixed a regression from 5.9 that caused comparing
+ default-constructed QStrings to be sorted after non-empty strings.
+
+ - QTextBoundaryFinder:
+ * [QTBUG-63191] Fixed a bug in the generating of Unicode data, affecting
+ the joining properties of characters like U+200C ZWNJ.
+
+ - QXmlStreamWriter:
+ * [QTBUG-63538] Empty namespace URIs are now possible.
+
+ - State Machine:
+ * [QTBUG-61463] Fixed a failed assertion that could happen when emitting a
+ signal from another thread.
+
+QtGui
+-----
+
+ - Text:
+ * [QTBUG-61882] Fixed a bug where mixing different writing systems with
+ emojis could lead to missing glyphs.
+ * [QTBUG-65519] Fixed ZWJ and ZWNJ control characters when fallback
+ fonts are in use.
+
+****************************************************************************
+* Platform-specific Changes *
+****************************************************************************
+
+ - QNX:
+ * [QTBUG-64033] Fixed the detection of slog2 with QNX 7.0
+
+ - Windows:
+ * Named pipes internally created by QProcess now contain the PID in their
+ name to ensure uniqueness.
+ * [QTBUG-65940] Fixed asserts and crashes in QWinEventNotifier.
+
+ - WinRT:
+ * -qdevel and -qdebug are removed from the command line arguments and
+ not passed to the application.
+
+****************************************************************************
+* Third-Party Code *
+****************************************************************************
+
+ - libjpeg-turbo was updated to version 1.5.3
+
+****************************************************************************
+* Tools *
+****************************************************************************
+
+configure & build system
+------------------------
+
+ - [QTBUG-65753] Fixed installation of resource sources in some examples.
+ - Qt's pkg-config .pc files now add -DQT_{module}_LIB to CFLAGS.
+
+qmake
+-----
+
+ - [QTBUG-65106] The value of QT is now silently ignored when the sub-
+ project already failed requires()/REQUIRES.
+ - [QTBUG-63442] Fixed an issue that would cause warnings with CMake 3.10
+ for projects that used AUTOMOC.
+ - [QTBUG-63637][MinGW] Fixed cross compilation from Linux.
+ - [QTBUG-65103] Introduced precompile_header_c CONFIG option for MSVC to
+ enable precompiled header for C sources.
+ - [QTBUG-65477][Darwin] Added escaping to @BUNDLEIDENTIFIER@.
+ - [Darwin] Rewrote handling of placeholders in Info.plist; the preferred
+ style is now ${} and is consistent between Xcode and Makefile generators.
+ - [Windows] Fixed path separators when setting working directory in
+ "make check".
+ - [Windows] Paths which are relative to the current drive's root are not
+ treated as absolute any more.
diff --git a/doc/src/images/borderlayout-example.png b/doc/src/images/borderlayout-example.png
index e856e06572..27b939bc2e 100644
--- a/doc/src/images/borderlayout-example.png
+++ b/doc/src/images/borderlayout-example.png
Binary files differ
diff --git a/examples/widgets/doc/src/borderlayout.qdoc b/examples/widgets/doc/src/borderlayout.qdoc
index c8f2ae4196..6572bfe578 100644
--- a/examples/widgets/doc/src/borderlayout.qdoc
+++ b/examples/widgets/doc/src/borderlayout.qdoc
@@ -36,6 +36,34 @@
\image borderlayout-example.png
+ The constructor of the Window class creates a QTextBrowser object,
+ to which a BorderLayout named \c layout is added. The declaration
+ of the BorderLayout class is quoted at the end of this document.
+
+ \quotefromfile layouts/borderlayout/window.cpp
+ \skipto Window::Window()
+ \printuntil BorderLayout
+
+ Several labeled widgets are added to \c layout with the orientation
+ \c {Center}, \c {North}, \c {West}, \c {East 1}, \c {East 2}, and
+ \c {South}.
+
+ \skipto layout->addWidget
+ \printuntil setWindowTitle
+
+ createLabel() in class \c Window sets the text of the labeled widgets
+ and the style.
+
+ \skipto QLabel *Window::createLabel
+ \printuntil /^\}/
+
+ Class BorderLayout contains all the utilitarian functions for formatting
+ the widgets it contains.
+
+ \quotefromfile layouts/borderlayout/borderlayout.h
+ \skipto class
+ \printuntil /^\}/
+
For more information, visit the \l{Layout Management} page.
\include examples-run.qdocinc
diff --git a/examples/widgets/doc/src/editabletreemodel.qdoc b/examples/widgets/doc/src/editabletreemodel.qdoc
index 87249a578e..68e10e3e78 100644
--- a/examples/widgets/doc/src/editabletreemodel.qdoc
+++ b/examples/widgets/doc/src/editabletreemodel.qdoc
@@ -153,7 +153,7 @@
We can retrieve pointers stored in this way by calling the
\l{QModelIndex::}{internalPointer()} function on the relevant model
index - we create our own \l{TreeModel::getItem}{getItem()} function to
- do this work for us, and call it from our \l{TreeModel::data}{data()}
+ do the work for us, and call it from our \l{TreeModel::data}{data()}
and \l{TreeModel::parent}{parent()} implementations.
Storing pointers to items is convenient when we control how they are
@@ -169,7 +169,7 @@
\row \li \b{Storing information in the underlying data structure}
Several pieces of data are stored as QVariant objects in the \c itemData
- member of each \c TreeItem instance
+ member of each \c TreeItem instance.
The diagram shows how pieces of information,
represented by the labels \b{a}, \b{b} and \b{c} in the
@@ -227,8 +227,8 @@
\section1 TreeItem Class Definition
The \c TreeItem class provides simple items that contain several
- pieces of data, and which can provide information about their parent
- and child items:
+ pieces of data, including information about their parent and
+ child items:
\snippet itemviews/editabletreemodel/treeitem.h 0
@@ -302,7 +302,7 @@
\snippet itemviews/editabletreemodel/treeitem.cpp 11
To make implementation of the model easier, we return true to indicate
- whether the data was set successfully, or false if an invalid column
+ that the data was set successfully.
Editable models often need to be resizable, enabling rows and columns to
be inserted and removed. The insertion of rows beneath a given model index
@@ -356,29 +356,29 @@
We call the internal \l{TreeModel::setupModelData}{setupModelData()}
function to convert the textual data supplied to a data structure we can
use with the model. Other models may be initialized with a ready-made
- data structure, or use an API to a library that maintains its own data.
+ data structure, or use an API from a library that maintains its own data.
- The destructor only has to delete the root item; all child items will
- be recursively deleted by the \c TreeItem destructor.
+ The destructor only has to delete the root item, which will cause all child
+ items to be recursively deleted.
\snippet itemviews/editabletreemodel/treemodel.cpp 1
\target TreeModel::getItem
Since the model's interface to the other model/view components is based
- on model indexes, and the internal data structure is item-based, many of
- the functions implemented by the model need to be able to convert any
- given model index to its corresponding item. For convenience and
+ on model indexes, and since the internal data structure is item-based,
+ many of the functions implemented by the model need to be able to convert
+ any given model index to its corresponding item. For convenience and
consistency, we have defined a \c getItem() function to perform this
repetitive task:
\snippet itemviews/editabletreemodel/treemodel.cpp 4
- This function assumes that each model index it is passed corresponds to
- a valid item in memory. If the index is invalid, or its internal pointer
- does not refer to a valid item, the root item is returned instead.
+ Each model index passed to this function should correspond to a valid
+ item in memory. If the index is invalid, or its internal pointer does
+ not refer to a valid item, the root item is returned instead.
The model's \c rowCount() implementation is simple: it first uses the
- \c getItem() function to obtain the relevant item, then returns the
+ \c getItem() function to obtain the relevant item; then it returns the
number of children it contains:
\snippet itemviews/editabletreemodel/treemodel.cpp 8
diff --git a/mkspecs/features/resources.prf b/mkspecs/features/resources.prf
index de769b4b86..3f5979202c 100644
--- a/mkspecs/features/resources.prf
+++ b/mkspecs/features/resources.prf
@@ -64,7 +64,7 @@ for(resource, RESOURCES) {
"</qresource>" \
"</RCC>"
- !write_file($$OUT_PWD/$$resource_file, resource_file_content): \
+ !write_file($$absolute_path($$resource_file, $$OUT_PWD), resource_file_content): \
error()
}
diff --git a/src/concurrent/qtconcurrentmedian.h b/src/concurrent/qtconcurrentmedian.h
index 87e6b2935d..864b2d33d5 100644
--- a/src/concurrent/qtconcurrentmedian.h
+++ b/src/concurrent/qtconcurrentmedian.h
@@ -135,6 +135,7 @@ public:
MedianDouble()
: currentMedian(), currentIndex(0), valid(false), dirty(true)
{
+ std::fill_n(values, static_cast<int>(BufferSize), 0.0);
}
void reset()
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 6248842d78..9ad32b162d 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -83,19 +83,6 @@
#include <sys/pstat.h>
#endif
-#if defined(Q_OS_MAC)
-# ifdef qDebug
-# define old_qDebug qDebug
-# undef qDebug
-# endif
-
-# ifdef old_qDebug
-# undef qDebug
-# define qDebug QT_NO_QDEBUG_MACRO
-# undef old_qDebug
-# endif
-#endif
-
#if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE)
#include <sys/prctl.h>
#endif
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index b465bdc0f4..ed56f99771 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -568,10 +568,6 @@ static int ucstricmp(const QChar *a, const QChar *ae, const QChar *b, const QCha
{
if (a == b)
return (ae - be);
- if (a == 0)
- return be - b;
- if (b == 0)
- return a - ae;
const QChar *e = ae;
if (be - b < ae - a)
@@ -600,11 +596,6 @@ static int ucstricmp(const QChar *a, const QChar *ae, const QChar *b, const QCha
// Case-insensitive comparison between a Unicode string and a QLatin1String
static int ucstricmp(const QChar *a, const QChar *ae, const char *b, const char *be)
{
- if (!a)
- return be - b;
- if (!b)
- return a - ae;
-
auto e = ae;
if (be - b < ae - a)
e = a + (be - b);
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index f7da94d111..12390928f0 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -525,21 +525,21 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME
\li \c{-platform} \e {platformName[:options]}, specifies the
\l{Qt Platform Abstraction} (QPA) plugin.
- Overridden by the \c QT_QPA_PLATFORM environment variable.
+ Overrides the \c QT_QPA_PLATFORM environment variable.
\li \c{-platformpluginpath} \e path, specifies the path to platform
plugins.
- Overridden by the \c QT_QPA_PLATFORM_PLUGIN_PATH environment
- variable.
+ Overrides the \c QT_QPA_PLATFORM_PLUGIN_PATH environment variable.
\li \c{-platformtheme} \e platformTheme, specifies the platform theme.
- Overridden by the \c QT_QPA_PLATFORMTHEME environment variable.
+ Overrides the \c QT_QPA_PLATFORMTHEME environment variable.
\li \c{-plugin} \e plugin, specifies additional plugins to load. The argument
may appear multiple times.
- Overridden by the \c QT_QPA_GENERIC_PLUGINS environment variable.
+ Concatenated with the plugins in the \c QT_QPA_GENERIC_PLUGINS environment
+ variable.
\li \c{-qmljsdebugger=}, activates the QML/JS debugger with a specified port.
The value must be of format \c{port:1234}\e{[,block]}, where
@@ -1125,6 +1125,8 @@ QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
\li \c openwfd
\li \c qnx
\li \c windows
+ \li \c wayland is a platform plugin for modern Linux desktops and some
+ embedded systems.
\li \c xcb is the X11 plugin used on regular desktop Linux platforms.
\endlist
@@ -1138,33 +1140,47 @@ QString QGuiApplication::platformName()
*QGuiApplicationPrivate::platform_name : QString();
}
-static void init_platform(const QString &pluginArgument, const QString &platformPluginPath, const QString &platformThemeName, int &argc, char **argv)
-{
- // Split into platform name and arguments
- QStringList arguments = pluginArgument.split(QLatin1Char(':'));
- const QString name = arguments.takeFirst().toLower();
- QString argumentsKey = name;
- argumentsKey[0] = argumentsKey.at(0).toUpper();
- arguments.append(QLibraryInfo::platformPluginArguments(argumentsKey));
+Q_LOGGING_CATEGORY(lcQpaPluginLoading, "qt.qpa.plugin");
+
+static void init_platform(const QString &pluginNamesWithArguments, const QString &platformPluginPath, const QString &platformThemeName, int &argc, char **argv)
+{
+ QStringList plugins = pluginNamesWithArguments.split(QLatin1Char(';'));
+ QStringList platformArguments;
+ QStringList availablePlugins = QPlatformIntegrationFactory::keys(platformPluginPath);
+ for (auto pluginArgument : plugins) {
+ // Split into platform name and arguments
+ QStringList arguments = pluginArgument.split(QLatin1Char(':'));
+ const QString name = arguments.takeFirst().toLower();
+ QString argumentsKey = name;
+ argumentsKey[0] = argumentsKey.at(0).toUpper();
+ arguments.append(QLibraryInfo::platformPluginArguments(argumentsKey));
+
+ // Create the platform integration.
+ QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, argc, argv, platformPluginPath);
+ if (Q_UNLIKELY(!QGuiApplicationPrivate::platform_integration)) {
+ if (availablePlugins.contains(name)) {
+ qCInfo(lcQpaPluginLoading).nospace().noquote()
+ << "Could not load the Qt platform plugin \"" << name << "\" in \""
+ << QDir::toNativeSeparators(platformPluginPath) << "\" even though it was found.";
+ } else {
+ qCWarning(lcQpaPluginLoading).nospace().noquote()
+ << "Could not find the Qt platform plugin \"" << name << "\" in \""
+ << QDir::toNativeSeparators(platformPluginPath) << "\"";
+ }
+ } else {
+ QGuiApplicationPrivate::platform_name = new QString(name);
+ platformArguments = arguments;
+ break;
+ }
+ }
- // Create the platform integration.
- QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, argc, argv, platformPluginPath);
if (Q_UNLIKELY(!QGuiApplicationPrivate::platform_integration)) {
- QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
+ QString fatalMessage = QStringLiteral("This application failed to start because no Qt platform plugin could be initialized. "
+ "Reinstalling the application may fix this problem.\n");
- QString fatalMessage;
- if (keys.contains(name)) {
- fatalMessage = QStringLiteral("This application failed to start because it could not load the Qt platform plugin \"%2\"\nin \"%3\", even though it was found. ").arg(name, QDir::toNativeSeparators(platformPluginPath));
- fatalMessage += QStringLiteral("This is usually due to missing dependencies, which you can verify by setting the env variable QT_DEBUG_PLUGINS to 1.\n\n");
- } else {
- fatalMessage = QStringLiteral("This application failed to start because it could not find the Qt platform plugin \"%2\"\nin \"%3\".\n\n").arg(name, QDir::toNativeSeparators(platformPluginPath));
- }
+ if (!availablePlugins.isEmpty())
+ fatalMessage += QStringLiteral("\nAvailable platform plugins are: %1.\n").arg(availablePlugins.join(QLatin1String(", ")));
- if (!keys.isEmpty()) {
- fatalMessage += QStringLiteral("Available platform plugins are: %1.\n\n").arg(
- keys.join(QLatin1String(", ")));
- }
- fatalMessage += QStringLiteral("Reinstalling the application may fix this problem.");
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
// Windows: Display message box unless it is a console application
// or debug build showing an assert box.
@@ -1172,11 +1188,10 @@ static void init_platform(const QString &pluginArgument, const QString &platform
MessageBox(0, (LPCTSTR)fatalMessage.utf16(), (LPCTSTR)(QCoreApplication::applicationName().utf16()), MB_OK | MB_ICONERROR);
#endif // Q_OS_WIN && !Q_OS_WINRT
qFatal("%s", qPrintable(fatalMessage));
+
return;
}
- QGuiApplicationPrivate::platform_name = new QString(name);
-
// Many platforms have created QScreens at this point. Finish initializing
// QHighDpiScaling to be prepared for early calls to qt_defaultDpi().
if (QGuiApplication::primaryScreen()) {
@@ -1223,9 +1238,9 @@ static void init_platform(const QString &pluginArgument, const QString &platform
#ifndef QT_NO_PROPERTIES
// Set arguments as dynamic properties on the native interface as
// boolean 'foo' or strings: 'foo=bar'
- if (!arguments.isEmpty()) {
+ if (!platformArguments.isEmpty()) {
if (QObject *nativeInterface = QGuiApplicationPrivate::platform_integration->nativeInterface()) {
- for (const QString &argument : qAsConst(arguments)) {
+ for (const QString &argument : qAsConst(platformArguments)) {
const int equalsPos = argument.indexOf(QLatin1Char('='));
const QByteArray name =
equalsPos != -1 ? argument.left(equalsPos).toUtf8() : argument.toUtf8();
@@ -1289,7 +1304,7 @@ void QGuiApplicationPrivate::createPlatformIntegration()
argv[j++] = argv[i];
continue;
}
- const bool isXcb = platformName == "xcb";
+ const bool xcbIsDefault = platformName.startsWith("xcb");
const char *arg = argv[i];
if (arg[1] == '-') // startsWith("--")
++arg;
@@ -1302,13 +1317,13 @@ void QGuiApplicationPrivate::createPlatformIntegration()
} else if (strcmp(arg, "-platformtheme") == 0) {
if (++i < argc)
platformThemeName = QString::fromLocal8Bit(argv[i]);
- } else if (strcmp(arg, "-qwindowgeometry") == 0 || (isXcb && strcmp(arg, "-geometry") == 0)) {
+ } else if (strcmp(arg, "-qwindowgeometry") == 0 || (xcbIsDefault && strcmp(arg, "-geometry") == 0)) {
if (++i < argc)
windowGeometrySpecification = QWindowGeometrySpecification::fromArgument(argv[i]);
- } else if (strcmp(arg, "-qwindowtitle") == 0 || (isXcb && strcmp(arg, "-title") == 0)) {
+ } else if (strcmp(arg, "-qwindowtitle") == 0 || (xcbIsDefault && strcmp(arg, "-title") == 0)) {
if (++i < argc)
firstWindowTitle = QString::fromLocal8Bit(argv[i]);
- } else if (strcmp(arg, "-qwindowicon") == 0 || (isXcb && strcmp(arg, "-icon") == 0)) {
+ } else if (strcmp(arg, "-qwindowicon") == 0 || (xcbIsDefault && strcmp(arg, "-icon") == 0)) {
if (++i < argc) {
icon = QString::fromLocal8Bit(argv[i]);
}
diff --git a/src/platformsupport/windowsuiautomation/uiaattributeids_p.h b/src/platformsupport/windowsuiautomation/uiaattributeids_p.h
index 52e7306a67..795cb9e551 100644
--- a/src/platformsupport/windowsuiautomation/uiaattributeids_p.h
+++ b/src/platformsupport/windowsuiautomation/uiaattributeids_p.h
@@ -40,6 +40,17 @@
#ifndef UIAATTRIBUTEIDS_H
#define UIAATTRIBUTEIDS_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.
+//
+
#define UIA_AnimationStyleAttributeId 40000
#define UIA_BackgroundColorAttributeId 40001
#define UIA_BulletStyleAttributeId 40002
diff --git a/src/platformsupport/windowsuiautomation/uiaclientinterfaces_p.h b/src/platformsupport/windowsuiautomation/uiaclientinterfaces_p.h
index b95c05f6a4..5ed79cdb47 100644
--- a/src/platformsupport/windowsuiautomation/uiaclientinterfaces_p.h
+++ b/src/platformsupport/windowsuiautomation/uiaclientinterfaces_p.h
@@ -40,6 +40,17 @@
#ifndef UIACLIENTINTERFACES_H
#define UIACLIENTINTERFACES_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 <Unknwn.h>
#ifndef __IUIAutomationElement_INTERFACE_DEFINED__
diff --git a/src/platformsupport/windowsuiautomation/uiacontroltypeids_p.h b/src/platformsupport/windowsuiautomation/uiacontroltypeids_p.h
index d77fc68da9..b5c5a0a4ff 100644
--- a/src/platformsupport/windowsuiautomation/uiacontroltypeids_p.h
+++ b/src/platformsupport/windowsuiautomation/uiacontroltypeids_p.h
@@ -40,6 +40,17 @@
#ifndef UIACONTROLTYPEIDS_H
#define UIACONTROLTYPEIDS_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.
+//
+
#define UIA_ButtonControlTypeId 50000
#define UIA_CalendarControlTypeId 50001
#define UIA_CheckBoxControlTypeId 50002
diff --git a/src/platformsupport/windowsuiautomation/uiaerrorids_p.h b/src/platformsupport/windowsuiautomation/uiaerrorids_p.h
index c25453007d..8c2a24dbc7 100644
--- a/src/platformsupport/windowsuiautomation/uiaerrorids_p.h
+++ b/src/platformsupport/windowsuiautomation/uiaerrorids_p.h
@@ -40,6 +40,17 @@
#ifndef UIAERRORIDS_H
#define UIAERRORIDS_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.
+//
+
#define UIA_E_ELEMENTNOTENABLED 0x80040200
#define UIA_E_ELEMENTNOTAVAILABLE 0x80040201
#define UIA_E_NOCLICKABLEPOINT 0x80040202
diff --git a/src/platformsupport/windowsuiautomation/uiaeventids_p.h b/src/platformsupport/windowsuiautomation/uiaeventids_p.h
index 2b414968ed..ed6c36834e 100644
--- a/src/platformsupport/windowsuiautomation/uiaeventids_p.h
+++ b/src/platformsupport/windowsuiautomation/uiaeventids_p.h
@@ -40,6 +40,17 @@
#ifndef UIAEVENTIDS_H
#define UIAEVENTIDS_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.
+//
+
#define UIA_ToolTipOpenedEventId 20000
#define UIA_ToolTipClosedEventId 20001
#define UIA_StructureChangedEventId 20002
diff --git a/src/platformsupport/windowsuiautomation/uiageneralids_p.h b/src/platformsupport/windowsuiautomation/uiageneralids_p.h
index 62c795b94a..220554f885 100644
--- a/src/platformsupport/windowsuiautomation/uiageneralids_p.h
+++ b/src/platformsupport/windowsuiautomation/uiageneralids_p.h
@@ -40,6 +40,17 @@
#ifndef UIAGENERALIDS_H
#define UIAGENERALIDS_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.
+//
+
#define UiaAppendRuntimeId 3
#define UiaRootObjectId -25
diff --git a/src/platformsupport/windowsuiautomation/uiapatternids_p.h b/src/platformsupport/windowsuiautomation/uiapatternids_p.h
index 114aabcaa5..d3f4c9bd7a 100644
--- a/src/platformsupport/windowsuiautomation/uiapatternids_p.h
+++ b/src/platformsupport/windowsuiautomation/uiapatternids_p.h
@@ -40,6 +40,17 @@
#ifndef UIAPATTERNIDS_H
#define UIAPATTERNIDS_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.
+//
+
#define UIA_InvokePatternId 10000
#define UIA_SelectionPatternId 10001
#define UIA_ValuePatternId 10002
diff --git a/src/platformsupport/windowsuiautomation/uiapropertyids_p.h b/src/platformsupport/windowsuiautomation/uiapropertyids_p.h
index 5c35c956f8..74e84147f6 100644
--- a/src/platformsupport/windowsuiautomation/uiapropertyids_p.h
+++ b/src/platformsupport/windowsuiautomation/uiapropertyids_p.h
@@ -40,6 +40,17 @@
#ifndef UIAPROPERTYIDS_H
#define UIAPROPERTYIDS_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.
+//
+
#define UIA_RuntimeIdPropertyId 30000
#define UIA_BoundingRectanglePropertyId 30001
#define UIA_ProcessIdPropertyId 30002
diff --git a/src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h b/src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h
index caae84755b..a6a2e4c20d 100644
--- a/src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h
+++ b/src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h
@@ -40,6 +40,17 @@
#ifndef UIASERVERINTERFACES_H
#define UIASERVERINTERFACES_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 <Unknwn.h>
#ifndef __IRawElementProviderSimple_INTERFACE_DEFINED__
diff --git a/src/platformsupport/windowsuiautomation/uiatypes_p.h b/src/platformsupport/windowsuiautomation/uiatypes_p.h
index 25d8b8cb2b..ea58417943 100644
--- a/src/platformsupport/windowsuiautomation/uiatypes_p.h
+++ b/src/platformsupport/windowsuiautomation/uiatypes_p.h
@@ -40,6 +40,17 @@
#ifndef UIATYPES_H
#define UIATYPES_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.
+//
+
typedef int PROPERTYID;
typedef int PATTERNID;
typedef int EVENTID;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 471a19adb0..3bc9055650 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1126,13 +1126,11 @@ void QCocoaWindow::handleGeometryChange()
// Guard against processing window system events during QWindow::setGeometry
// calls, which Qt and Qt applications do not expect.
if (!m_inSetGeometry)
- QWindowSystemInterface::flushWindowSystemEvents();
+ QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
}
void QCocoaWindow::handleExposeEvent(const QRegion &region)
{
- const QRect previouslyExposedRect = m_exposedRect;
-
// Ideally we'd implement isExposed() in terms of these properties,
// plus the occlusionState of the NSWindow, and let the expose event
// pull the exposed state out when needed. However, when the window
@@ -1326,7 +1324,7 @@ void QCocoaWindow::recreateWindowIfNeeded()
void QCocoaWindow::requestUpdate()
{
qCDebug(lcQpaCocoaDrawing) << "QCocoaWindow::requestUpdate" << window();
- [m_view requestUpdate];
+ [qnsview_cast(m_view) requestUpdate];
}
void QCocoaWindow::requestActivateWindow()
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index eae0ee7613..6ae52d9fd3 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -343,6 +343,9 @@ void QXcbShmImage::createShmSegment(size_t segmentSize)
void QXcbShmImage::destroyShmSegment(size_t segmentSize)
{
+#ifndef XCB_USE_SHM_FD
+ Q_UNUSED(segmentSize)
+#endif
auto cookie = xcb_shm_detach_checked(xcb_connection(), m_shm_info.shmseg);
xcb_generic_error_t *error = xcb_request_check(xcb_connection(), cookie);
if (error)
diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp
index 6f105f79ca..368b777ca5 100644
--- a/src/plugins/sqldrivers/psql/qsql_psql.cpp
+++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp
@@ -204,6 +204,7 @@ public:
void setDatestyle();
void setByteaOutput();
void detectBackslashEscape();
+ mutable QHash<int, QString> oidToTable;
};
void QPSQLDriverPrivate::appendTables(QStringList &tl, QSqlQuery &t, QChar type)
@@ -815,18 +816,20 @@ QSqlRecord QPSQLResult::record() const
f.setName(QString::fromUtf8(PQfname(d->result, i)));
else
f.setName(QString::fromLocal8Bit(PQfname(d->result, i)));
-
+ const int tableOid = PQftable(d->result, i);
+ auto &tableName = d->drv_d_func()->oidToTable[tableOid];
// WARNING: We cannot execute any other SQL queries on
// the same db connection while forward-only mode is active
// (this would discard all results of forward-only query).
// So we just skip this...
- if (!isForwardOnly()) {
+ if (tableName.isEmpty() && !isForwardOnly()) {
QSqlQuery qry(driver()->createResult());
if (qry.exec(QStringLiteral("SELECT relname FROM pg_class WHERE pg_class.oid = %1")
- .arg(PQftable(d->result, i))) && qry.next()) {
- f.setTableName(qry.value(0).toString());
+ .arg(tableOid)) && qry.next()) {
+ tableName = qry.value(0).toString();
}
}
+ f.setTableName(tableName);
int ptype = PQftype(d->result, i);
f.setType(qDecodePSQLType(ptype));
int len = PQfsize(d->result, i);
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index 0bc3af2f77..cef1d1b6da 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -1134,19 +1134,26 @@ void QGraphicsItemPrivate::remapItemPos(QEvent *event, QGraphicsItem *item)
is untransformable, this function will correctly map \a pos from the scene using the
view's transformation.
*/
-QPointF QGraphicsItemPrivate::genericMapFromScene(const QPointF &pos,
- const QWidget *viewport) const
+
+QTransform QGraphicsItemPrivate::genericMapFromSceneTransform(const QWidget *viewport) const
{
Q_Q(const QGraphicsItem);
if (!itemIsUntransformable())
- return q->mapFromScene(pos);
- QGraphicsView *view = 0;
- if (viewport)
- view = qobject_cast<QGraphicsView *>(viewport->parentWidget());
- if (!view)
- return q->mapFromScene(pos);
+ return sceneTransform.inverted();
+ const QGraphicsView *view = viewport
+ ? qobject_cast<QGraphicsView *>(viewport->parentWidget())
+ : nullptr;
+ if (view == nullptr)
+ return sceneTransform.inverted();
// ### More ping pong than needed.
- return q->deviceTransform(view->viewportTransform()).inverted().map(view->mapFromScene(pos));
+ const QTransform viewportTransform = view->viewportTransform();
+ return viewportTransform * q->deviceTransform(viewportTransform).inverted();
+}
+
+QPointF QGraphicsItemPrivate::genericMapFromScene(const QPointF &pos,
+ const QWidget *viewport) const
+{
+ return genericMapFromSceneTransform(viewport).map(pos);
}
/*!
diff --git a/src/widgets/graphicsview/qgraphicsitem_p.h b/src/widgets/graphicsview/qgraphicsitem_p.h
index bae38473f9..9fc6c0794a 100644
--- a/src/widgets/graphicsview/qgraphicsitem_p.h
+++ b/src/widgets/graphicsview/qgraphicsitem_p.h
@@ -190,6 +190,7 @@ public:
void updateAncestorFlags();
void setIsMemberOfGroup(bool enabled);
void remapItemPos(QEvent *event, QGraphicsItem *item);
+ QTransform genericMapFromSceneTransform(const QWidget *viewport = nullptr) const;
QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const;
inline bool itemIsUntransformable() const
{
diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp
index 25b77aa02f..37c631483a 100644
--- a/src/widgets/graphicsview/qgraphicsscene.cpp
+++ b/src/widgets/graphicsview/qgraphicsscene.cpp
@@ -1286,10 +1286,11 @@ void QGraphicsScenePrivate::sendHoverEvent(QEvent::Type type, QGraphicsItem *ite
{
QGraphicsSceneHoverEvent event(type);
event.setWidget(hoverEvent->widget());
- event.setPos(item->d_ptr->genericMapFromScene(hoverEvent->scenePos(), hoverEvent->widget()));
+ const QTransform mapFromScene = item->d_ptr->genericMapFromSceneTransform(hoverEvent->widget());
+ event.setPos(mapFromScene.map(hoverEvent->scenePos()));
event.setScenePos(hoverEvent->scenePos());
event.setScreenPos(hoverEvent->screenPos());
- event.setLastPos(item->d_ptr->genericMapFromScene(hoverEvent->lastScenePos(), hoverEvent->widget()));
+ event.setLastPos(mapFromScene.map(hoverEvent->lastScenePos()));
event.setLastScenePos(hoverEvent->lastScenePos());
event.setLastScreenPos(hoverEvent->lastScreenPos());
event.setModifiers(hoverEvent->modifiers());
@@ -1312,14 +1313,16 @@ void QGraphicsScenePrivate::sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent)
if (item->isBlockedByModalPanel())
return;
+ const QTransform mapFromScene = item->d_ptr->genericMapFromSceneTransform(mouseEvent->widget());
+ const QPointF itemPos = mapFromScene.map(mouseEvent->scenePos());
for (int i = 0x1; i <= 0x10; i <<= 1) {
Qt::MouseButton button = Qt::MouseButton(i);
- mouseEvent->setButtonDownPos(button, mouseGrabberButtonDownPos.value(button, item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget())));
+ mouseEvent->setButtonDownPos(button, mouseGrabberButtonDownPos.value(button, itemPos));
mouseEvent->setButtonDownScenePos(button, mouseGrabberButtonDownScenePos.value(button, mouseEvent->scenePos()));
mouseEvent->setButtonDownScreenPos(button, mouseGrabberButtonDownScreenPos.value(button, mouseEvent->screenPos()));
}
- mouseEvent->setPos(item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget()));
- mouseEvent->setLastPos(item->d_ptr->genericMapFromScene(mouseEvent->lastScenePos(), mouseEvent->widget()));
+ mouseEvent->setPos(itemPos);
+ mouseEvent->setLastPos(mapFromScene.map(mouseEvent->lastScenePos()));
sendEvent(item, mouseEvent);
}
@@ -5858,10 +5861,17 @@ void QGraphicsScenePrivate::removeView(QGraphicsView *view)
void QGraphicsScenePrivate::updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent)
{
+ const QTransform mapFromScene =
+ item->d_ptr->genericMapFromSceneTransform(static_cast<const QWidget *>(touchEvent->target()));
+
for (auto &touchPoint : touchEvent->_touchPoints) {
- touchPoint.setRect(item->mapFromScene(touchPoint.sceneRect()).boundingRect());
- touchPoint.setStartPos(item->d_ptr->genericMapFromScene(touchPoint.startScenePos(), static_cast<QWidget *>(touchEvent->target())));
- touchPoint.setLastPos(item->d_ptr->genericMapFromScene(touchPoint.lastScenePos(), static_cast<QWidget *>(touchEvent->target())));
+ // Deprecated TouchPoint::setRect clobbers ellipseDiameters, restore
+ const QSizeF ellipseDiameters = touchPoint.ellipseDiameters();
+ touchPoint.setRect(mapFromScene.map(touchPoint.sceneRect()).boundingRect());
+ touchPoint.setEllipseDiameters(ellipseDiameters);
+ touchPoint.setPos(mapFromScene.map(touchPoint.scenePos()));
+ touchPoint.setStartPos(mapFromScene.map(touchPoint.startScenePos()));
+ touchPoint.setLastPos(mapFromScene.map(touchPoint.lastScenePos()));
}
}
diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
index c22998f804..6aa3c498aa 100644
--- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp
+++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
@@ -6091,8 +6091,14 @@ void tst_QString::compare_data()
QTest::addColumn<int>("csr"); // case sensitive result
QTest::addColumn<int>("cir"); // case insensitive result
-
// null strings
+ QTest::newRow("null-null") << QString() << QString() << 0 << 0;
+ QTest::newRow("text-null") << QString("a") << QString() << 1 << 1;
+ QTest::newRow("null-text") << QString() << QString("a") << -1 << -1;
+ QTest::newRow("null-empty") << QString() << QString("") << 0 << 0;
+ QTest::newRow("empty-null") << QString("") << QString() << 0 << 0;
+
+ // empty strings
QTest::newRow("data0") << QString("") << QString("") << 0 << 0;
QTest::newRow("data1") << QString("a") << QString("") << 1 << 1;
QTest::newRow("data2") << QString("") << QString("a") << -1 << -1;
diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
index baf2551dfb..aba99a9e20 100644
--- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
@@ -370,7 +370,8 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db )
<< qTableName("task_234422", __FILE__, db)
<< qTableName("test141895", __FILE__, db)
<< qTableName("qtest_oraOCINumber", __FILE__, db)
- << qTableName("bug2192", __FILE__, db);
+ << qTableName("bug2192", __FILE__, db)
+ << qTableName("tst_record", __FILE__, db);
if (dbType == QSqlDriver::PostgreSQL)
tablenames << qTableName("task_233829", __FILE__, db);
@@ -1009,6 +1010,29 @@ void tst_QSqlQuery::value()
}
}
+#define SETUP_RECORD_TABLE \
+ do { \
+ QVERIFY_SQL(q, exec("CREATE TABLE " + tst_record + " (id integer, extra varchar(50))")); \
+ for (int i = 0; i < 3; ++i) \
+ QVERIFY_SQL(q, exec(QString("INSERT INTO " + tst_record + " VALUES(%1, 'extra%1')").arg(i))); \
+ } while (0)
+
+#define CHECK_RECORD \
+ do { \
+ QVERIFY_SQL(q, exec(QString("select %1.id, %1.t_varchar, %1.t_char, %2.id, %2.extra from %1, %2 where " \
+ "%1.id = %2.id order by %1.id").arg(lowerQTest).arg(tst_record))); \
+ QCOMPARE(q.record().fieldName(0).toLower(), QString("id")); \
+ QCOMPARE(q.record().field(0).tableName().toLower(), lowerQTest); \
+ QCOMPARE(q.record().fieldName(1).toLower(), QString("t_varchar")); \
+ QCOMPARE(q.record().field(1).tableName().toLower(), lowerQTest); \
+ QCOMPARE(q.record().fieldName(2).toLower(), QString("t_char")); \
+ QCOMPARE(q.record().field(2).tableName().toLower(), lowerQTest); \
+ QCOMPARE(q.record().fieldName(3).toLower(), QString("id")); \
+ QCOMPARE(q.record().field(3).tableName().toLower(), tst_record); \
+ QCOMPARE(q.record().fieldName(4).toLower(), QString("extra")); \
+ QCOMPARE(q.record().field(4).tableName().toLower(), tst_record); \
+ } while (0)
+
void tst_QSqlQuery::record()
{
QFETCH( QString, dbName );
@@ -1030,6 +1054,26 @@ void tst_QSqlQuery::record()
QCOMPARE( q.record().fieldName( 0 ).toLower(), QString( "id" ) );
QCOMPARE( q.value( 0 ).toInt(), 2 );
+
+ const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
+ if (dbType == QSqlDriver::Oracle)
+ QSKIP("Getting the tablename is not supported in Oracle");
+ const auto lowerQTest = qtest.toLower();
+ for (int i = 0; i < 3; ++i)
+ QCOMPARE(q.record().field(i).tableName().toLower(), lowerQTest);
+ q.clear();
+ const auto tst_record = qTableName("tst_record", __FILE__, db).toLower();
+ SETUP_RECORD_TABLE;
+ CHECK_RECORD;
+ q.clear();
+
+ // Recreate the tables, in a different order
+ const QStringList tables = { qtest, tst_record, qTableName("qtest_null", __FILE__, db) };
+ tst_Databases::safeDropTables(db, tables);
+ SETUP_RECORD_TABLE;
+ createTestTables(db);
+ populateTestTables(db);
+ CHECK_RECORD;
}
void tst_QSqlQuery::isValid()
@@ -2667,8 +2711,22 @@ void tst_QSqlQuery::lastInsertId()
QSqlQuery q( db );
- QVERIFY_SQL( q, exec( "insert into " + qtest + " values (41, 'VarChar41', 'Char41')" ) );
-
+ 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) {
+ const auto tst_lastInsertId = qTableName("tst_lastInsertId", __FILE__, db);
+ tst_Databases::safeDropTable(db, tst_lastInsertId);
+ QVERIFY_SQL(q, exec(QStringLiteral("create table ") + tst_lastInsertId +
+ QStringLiteral(" (id serial not null, t_varchar "
+ "varchar(20), t_char char(20), primary key(id))")));
+ QVERIFY_SQL(q, exec(QStringLiteral("insert into ") + tst_lastInsertId +
+ QStringLiteral(" (t_varchar, t_char) values "
+ "('VarChar41', 'Char41')")));
+ } else {
+ QVERIFY_SQL(q, exec(QStringLiteral("insert into ") + qtest +
+ QStringLiteral(" values (41, 'VarChar41', 'Char41')")));
+ }
QVariant v = q.lastInsertId();
QVERIFY( v.isValid() );
@@ -3225,10 +3283,19 @@ void tst_QSqlQuery::timeStampParsing()
const QString tableName(qTableName("timeStampParsing", __FILE__, db));
tst_Databases::safeDropTable(db, tableName);
QSqlQuery q(db);
- QVERIFY_SQL(q, exec(QStringLiteral("CREATE TABLE ") + tableName
- + QStringLiteral(" (id integer, datefield timestamp)")));
- QVERIFY_SQL(q, exec(QStringLiteral("INSERT INTO ") + tableName
- + QStringLiteral(" (datefield) VALUES (current_timestamp)")));
+ QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
+ if (dbType == QSqlDriver::PostgreSQL) {
+ QVERIFY_SQL(q, exec(QStringLiteral("CREATE TABLE ") + tableName + QStringLiteral("("
+ "id serial NOT NULL, "
+ "datefield timestamp, primary key(id));")));
+ } else {
+ QVERIFY_SQL(q, exec(QStringLiteral("CREATE TABLE ") + tableName + QStringLiteral("("
+ "\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT,"
+ "\"datefield\" timestamp);")));
+ }
+ QVERIFY_SQL(q, exec(
+ QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (datefield) VALUES (current_timestamp);"
+ )));
QVERIFY_SQL(q, exec(QStringLiteral("SELECT * FROM ") + tableName));
while (q.next())
QVERIFY(q.value(1).toDateTime().isValid());
@@ -3599,15 +3666,17 @@ void tst_QSqlQuery::QTBUG_18435()
void tst_QSqlQuery::QTBUG_5251()
{
+ // Since QSqlTableModel will escape the identifiers, we need to escape
+ // them for databases that are case sensitive
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
const QString timetest(qTableName("timetest", __FILE__, db));
-
+ tst_Databases::safeDropTable(db, timetest);
QSqlQuery q(db);
- q.exec("DROP TABLE " + timetest);
- QVERIFY_SQL(q, exec("CREATE TABLE " + timetest + " (t TIME)"));
- QVERIFY_SQL(q, exec("INSERT INTO " + timetest + " VALUES ('1:2:3.666')"));
+ QVERIFY_SQL(q, exec(QStringLiteral("CREATE TABLE \"") + timetest + QStringLiteral("\" (t TIME)")));
+ QVERIFY_SQL(q, exec(QStringLiteral("INSERT INTO \"") + timetest +
+ QStringLiteral("\" VALUES ('1:2:3.666')")));
QSqlTableModel timetestModel(0,db);
timetestModel.setEditStrategy(QSqlTableModel::OnManualSubmit);
@@ -3620,7 +3689,8 @@ void tst_QSqlQuery::QTBUG_5251()
QVERIFY_SQL(timetestModel, submitAll());
QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"), QString("00:12:34.500"));
- QVERIFY_SQL(q, exec("UPDATE " + timetest + " SET t = '0:11:22.33'"));
+ QVERIFY_SQL(q, exec(QStringLiteral("UPDATE \"") + timetest +
+ QStringLiteral("\" SET t = '0:11:22.33'")));
QVERIFY_SQL(timetestModel, select());
QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"), QString("00:11:22.330"));
@@ -4197,12 +4267,18 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QVariant::Type intType = QVariant::Int;
+ QVariant::Type sumType = intType;
+ QVariant::Type countType = intType;
// QPSQL uses LongLong for manipulation of integers
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- if (dbType == QSqlDriver::PostgreSQL)
- intType = QVariant::LongLong;
- else if (dbType == QSqlDriver::Oracle)
- intType = QVariant::Double;
+ if (dbType == QSqlDriver::PostgreSQL) {
+ sumType = countType = QVariant::LongLong;
+ } else if (dbType == QSqlDriver::Oracle) {
+ intType = sumType = countType = QVariant::Double;
+ } else if (dbType == QSqlDriver::MySqlServer) {
+ sumType = QVariant::Double;
+ countType = QVariant::LongLong;
+ }
{
const QString tableName(qTableName("numericFunctionsWithIntValues", __FILE__, db));
tst_Databases::safeDropTable( db, tableName );
@@ -4215,10 +4291,8 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QVERIFY(q.next());
if (dbType == QSqlDriver::SQLite)
QCOMPARE(q.record().field(0).type(), QVariant::Invalid);
- else if (dbType == QSqlDriver::MySqlServer)
- QCOMPARE(q.record().field(0).type(), QVariant::Double);
else
- QCOMPARE(q.record().field(0).type(), intType);
+ QCOMPARE(q.record().field(0).type(), sumType);
QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id) VALUES (1)"));
QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id) VALUES (2)"));
@@ -4226,10 +4300,7 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QVERIFY_SQL(q, exec("SELECT SUM(id) FROM " + tableName));
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), 3);
- if (dbType == QSqlDriver::MySqlServer)
- QCOMPARE(q.record().field(0).type(), QVariant::Double);
- else
- QCOMPARE(q.record().field(0).type(), intType);
+ QCOMPARE(q.record().field(0).type(), sumType);
QVERIFY_SQL(q, exec("SELECT AVG(id) FROM " + tableName));
QVERIFY(q.next());
@@ -4245,7 +4316,7 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QVERIFY_SQL(q, exec("SELECT COUNT(id) FROM " + tableName));
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), 2);
- QCOMPARE(q.record().field(0).type(), dbType != QSqlDriver::MySqlServer ? intType : QVariant::LongLong);
+ QCOMPARE(q.record().field(0).type(), countType);
QVERIFY_SQL(q, exec("SELECT MIN(id) FROM " + tableName));
QVERIFY(q.next());
@@ -4288,7 +4359,7 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QVERIFY_SQL(q, exec("SELECT COUNT(id) FROM " + tableName));
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), 2);
- QCOMPARE(q.record().field(0).type(), dbType != QSqlDriver::MySqlServer ? intType : QVariant::LongLong);
+ QCOMPARE(q.record().field(0).type(), countType);
QVERIFY_SQL(q, exec("SELECT MIN(id) FROM " + tableName));
QVERIFY(q.next());
diff --git a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
index 84cca482fb..f1c55df1ef 100644
--- a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
+++ b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
@@ -385,6 +385,7 @@ void tst_QSqlRelationalTableModel::setData()
model.setRelation(1, QSqlRelation(reltest5, "title", "abbrev"));
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
+ model.setSort(0, Qt::AscendingOrder);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0,1)).toString(), QString("Mr"));
@@ -783,24 +784,32 @@ void tst_QSqlRelationalTableModel::sort()
QVERIFY_SQL(model, select());
QCOMPARE(model.rowCount(), 6);
- QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister"));
- QCOMPARE(model.data(model.index(1, 2)).toString(), QString("mister"));
- QCOMPARE(model.data(model.index(2, 2)).toString(), QString("herr"));
- QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr"));
- QCOMPARE(model.data(model.index(4, 2)).toString(), QString(""));
- QCOMPARE(model.data(model.index(5, 2)).toString(), QString(""));
+
+ QStringList stringsInDatabaseOrder;
+ // PostgreSQL puts the null ones (from the table with the original value) first in descending order
+ // which translate to empty strings in the related table
+ if (dbType == QSqlDriver::PostgreSQL)
+ stringsInDatabaseOrder << "" << "" << "mister" << "mister" << "herr" << "herr";
+ else
+ stringsInDatabaseOrder << "mister" << "mister" << "herr" << "herr" << "" << "";
+ for (int i = 0; i < 6; ++i)
+ QCOMPARE(model.data(model.index(i, 2)).toString(), stringsInDatabaseOrder.at(i));
model.setSort(3, Qt::AscendingOrder);
QVERIFY_SQL(model, select());
+ // PostgreSQL puts the null ones (from the table with the original value) first in descending order
+ // which translate to empty strings in the related table
+ stringsInDatabaseOrder.clear();
+ if (dbType == QSqlDriver::PostgreSQL)
+ stringsInDatabaseOrder << "herr" << "mister" << "mister" << "mister" << "mister" << "";
+ else if (dbType != QSqlDriver::Sybase)
+ stringsInDatabaseOrder << "" << "herr" << "mister" << "mister" << "mister" << "mister";
+
if (dbType != QSqlDriver::Sybase) {
QCOMPARE(model.rowCount(), 6);
- QCOMPARE(model.data(model.index(0, 3)).toString(), QString(""));
- QCOMPARE(model.data(model.index(1, 3)).toString(), QString("herr"));
- QCOMPARE(model.data(model.index(2, 3)).toString(), QString("mister"));
- QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister"));
- QCOMPARE(model.data(model.index(4, 3)).toString(), QString("mister"));
- QCOMPARE(model.data(model.index(5, 3)).toString(), QString("mister"));
+ for (int i = 0; i < 6; ++i)
+ QCOMPARE(model.data(model.index(i, 3)).toString(), stringsInDatabaseOrder.at(i));
} else {
QCOMPARE(model.data(model.index(0, 3)).toInt(), 1);
QCOMPARE(model.data(model.index(1, 3)).toInt(), 2);
diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
index bf76ed2bb6..ded360ef8d 100644
--- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
+++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
@@ -275,7 +275,7 @@ void tst_QSqlTableModel::init()
void tst_QSqlTableModel::cleanup()
{
- repopulateTestTables();
+ recreateTestTables();
}
void tst_QSqlTableModel::select()
diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
index 26831002ce..4f4a11a79c 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -38,6 +38,7 @@
#include <QAbstractTextDocumentLayout>
#include <QBitmap>
#include <QCursor>
+#include <QDesktopWidget>
#include <QScreen>
#include <QLabel>
#include <QDial>
@@ -54,10 +55,13 @@
#include <QPushButton>
#include <QLineEdit>
#include <QGraphicsLinearLayout>
+#include <QTransform>
#include <float.h>
#include <QStyleHints>
Q_DECLARE_METATYPE(QPainterPath)
+Q_DECLARE_METATYPE(QSizeF)
+Q_DECLARE_METATYPE(QTransform)
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
#include <windows.h>
@@ -435,6 +439,8 @@ private slots:
void focusHandling();
void touchEventPropagation_data();
void touchEventPropagation();
+ void touchEventTransformation_data();
+ void touchEventTransformation();
void deviceCoordinateCache_simpleRotations();
void resolvePaletteForItemChildren();
@@ -465,6 +471,7 @@ private slots:
private:
QList<QGraphicsItem *> paintedItems;
+ QTouchDevice *m_touchDevice = nullptr;
};
void tst_QGraphicsItem::construction()
@@ -10945,6 +10952,95 @@ void tst_QGraphicsItem::focusHandling()
QCOMPARE(scene.focusItem(), focusableUnder);
}
+class TouchEventTestee : public QGraphicsRectItem
+{
+public:
+ TouchEventTestee(const QSizeF &size = QSizeF(100, 100)) :
+ QGraphicsRectItem(QRectF(QPointF(), size))
+ {
+ setAcceptTouchEvents(true);
+ setFlag(QGraphicsItem::ItemIsFocusable, false);
+ }
+
+ QList<QTouchEvent::TouchPoint> touchBeginPoints() const { return m_touchBeginPoints; }
+ int touchBeginEventCount() const { return m_touchBeginPoints.size(); }
+
+ QList<QTouchEvent::TouchPoint> touchUpdatePoints() const { return m_touchUpdatePoints; }
+ int touchUpdateEventCount() const { return m_touchUpdatePoints.size(); }
+
+protected:
+ bool sceneEvent(QEvent *ev) override
+ {
+ switch (ev->type()) {
+ case QEvent::TouchBegin:
+ m_touchBeginPoints.append(static_cast<const QTouchEvent *>(ev)->touchPoints().constFirst());
+ ev->accept();
+ return true;
+ case QEvent::TouchUpdate:
+ m_touchUpdatePoints.append(static_cast<const QTouchEvent *>(ev)->touchPoints().constFirst());
+ ev->accept();
+ return true;
+ default:
+ break;
+ }
+
+ return QGraphicsRectItem::sceneEvent(ev);
+ }
+
+private:
+ QList<QTouchEvent::TouchPoint> m_touchBeginPoints;
+ QList<QTouchEvent::TouchPoint> m_touchUpdatePoints;
+};
+
+static QList<QTouchEvent::TouchPoint>
+ createTouchPoints(const QGraphicsView &view,
+ const QPointF &scenePos,
+ const QSizeF &ellipseDiameters,
+ Qt::TouchPointState state = Qt::TouchPointPressed)
+{
+ QTouchEvent::TouchPoint tp(0);
+ tp.setState(state);
+ tp.setScenePos(scenePos);
+ tp.setStartScenePos(scenePos);
+ tp.setLastScenePos(scenePos);
+ const QPointF screenPos = view.viewport()->mapToGlobal(view.mapFromScene(scenePos));
+ tp.setScreenPos(screenPos);
+ tp.setStartScreenPos(screenPos);
+ tp.setLastScreenPos(screenPos);
+ tp.setEllipseDiameters(ellipseDiameters);
+ const QSizeF screenSize = QApplication::desktop()->screenGeometry(&view).size();
+ tp.setNormalizedPos(QPointF(screenPos.x() / screenSize.width(), screenPos.y() / screenSize.height()));
+ return QList<QTouchEvent::TouchPoint>() << tp;
+}
+
+static bool comparePointF(const QPointF &p1, const QPointF &p2)
+{
+ return qFuzzyCompare(p1.x(), p2.x()) && qFuzzyCompare(p1.y(), p2.y());
+}
+
+static bool compareSizeF(const QSizeF &s1, const QSizeF &s2)
+{
+ return qFuzzyCompare(s1.width(), s2.width()) && qFuzzyCompare(s1.height(), s2.height());
+}
+
+static QByteArray msgPointFComparisonFailed(const QPointF &p1, const QPointF &p2)
+{
+ return QByteArray::number(p1.x()) + ", " + QByteArray::number(p1.y())
+ + " != " + QByteArray::number(p2.x()) + ", " + QByteArray::number(p2.y());
+}
+
+static QByteArray msgSizeFComparisonFailed(const QSizeF &s1, const QSizeF &s2)
+{
+ return QByteArray::number(s1.width()) + 'x' + QByteArray::number(s1.height())
+ + " != " + QByteArray::number(s2.width()) + 'x' + QByteArray::number(s2.height());
+}
+
+#define COMPARE_POINTF(ACTUAL, EXPECTED) \
+ QVERIFY2(comparePointF(ACTUAL, EXPECTED), msgPointFComparisonFailed(ACTUAL, EXPECTED).constData())
+
+#define COMPARE_SIZEF(ACTUAL, EXPECTED) \
+ QVERIFY2(compareSizeF(ACTUAL, EXPECTED), msgSizeFComparisonFailed(ACTUAL, EXPECTED).constData())
+
void tst_QGraphicsItem::touchEventPropagation_data()
{
QTest::addColumn<QGraphicsItem::GraphicsItemFlag>("flag");
@@ -10963,29 +11059,7 @@ void tst_QGraphicsItem::touchEventPropagation()
QFETCH(QGraphicsItem::GraphicsItemFlag, flag);
QFETCH(int, expectedCount);
- class Testee : public QGraphicsRectItem
- {
- public:
- int touchBeginEventCount;
-
- Testee()
- : QGraphicsRectItem(0, 0, 100, 100)
- , touchBeginEventCount(0)
- {
- setAcceptTouchEvents(true);
- setFlag(QGraphicsItem::ItemIsFocusable, false);
- }
-
- bool sceneEvent(QEvent *ev)
- {
- if (ev->type() == QEvent::TouchBegin)
- ++touchBeginEventCount;
-
- return QGraphicsRectItem::sceneEvent(ev);
- }
- };
-
- Testee *touchEventReceiver = new Testee;
+ TouchEventTestee *touchEventReceiver = new TouchEventTestee;
QGraphicsItem *topMost = new QGraphicsRectItem(touchEventReceiver->boundingRect());
QGraphicsScene scene;
@@ -10998,26 +11072,107 @@ void tst_QGraphicsItem::touchEventPropagation()
topMost->setFlag(flag, true);
QGraphicsView view(&scene);
+ view.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1String("::")
+ + QLatin1String(QTest::currentDataTag()));
view.setSceneRect(touchEventReceiver->boundingRect());
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
- QCOMPARE(touchEventReceiver->touchBeginEventCount, 0);
+ QCOMPARE(touchEventReceiver->touchBeginEventCount(), 0);
- QTouchEvent::TouchPoint tp(0);
- tp.setState(Qt::TouchPointPressed);
- tp.setScenePos(view.sceneRect().center());
- tp.setLastScenePos(view.sceneRect().center());
+ const QPointF scenePos = view.sceneRect().center();
+ sendMousePress(&scene, scenePos);
+ if (m_touchDevice == nullptr)
+ m_touchDevice = QTest::createTouchDevice();
+ QTouchEvent touchBegin(QEvent::TouchBegin, m_touchDevice, Qt::NoModifier, Qt::TouchPointPressed,
+ createTouchPoints(view, scenePos, QSizeF(10, 10)));
+ touchBegin.setTarget(view.viewport());
- QList<QTouchEvent::TouchPoint> touchPoints;
- touchPoints << tp;
+ qApp->sendEvent(&scene, &touchBegin);
+ QCOMPARE(touchEventReceiver->touchBeginEventCount(), expectedCount);
+}
- sendMousePress(&scene, tp.scenePos());
- QTouchDevice *device = QTest::createTouchDevice();
- QTouchEvent touchBegin(QEvent::TouchBegin, device, Qt::NoModifier, Qt::TouchPointPressed, touchPoints);
+void tst_QGraphicsItem::touchEventTransformation_data()
+{
+ QTest::addColumn<QGraphicsItem::GraphicsItemFlag>("flag");
+ QTest::addColumn<QTransform>("viewTransform");
+ QTest::addColumn<QPointF>("touchScenePos");
+ QTest::addColumn<QSizeF>("ellipseDiameters");
+ QTest::addColumn<QPointF>("expectedItemPos");
+
+ QTest::newRow("notransform")
+ << QGraphicsItem::ItemIsSelectable << QTransform()
+ << QPointF(150, 150) << QSizeF(7, 8) << QPointF(50, 50);
+ QTest::newRow("scaled")
+ << QGraphicsItem::ItemIsSelectable << QTransform::fromScale(0.5, 0.5)
+ << QPointF(150, 150) << QSizeF(7, 8) << QPointF(50, 50);
+ // QTBUG-66192: When the item ignores the downscaling transformation,
+ // it will receive the touch point at 25,25 instead of 50,50.
+ QTest::newRow("scaled/ItemIgnoresTransformations")
+ << QGraphicsItem::ItemIgnoresTransformations << QTransform::fromScale(0.5, 0.5)
+ << QPointF(150, 150) << QSizeF(7, 8) << QPointF(25, 25);
+}
+
+void tst_QGraphicsItem::touchEventTransformation()
+{
+ QFETCH(QGraphicsItem::GraphicsItemFlag, flag);
+ QFETCH(QTransform, viewTransform);
+ QFETCH(QPointF, touchScenePos);
+ QFETCH(QSizeF, ellipseDiameters);
+ QFETCH(QPointF, expectedItemPos);
+
+ TouchEventTestee *touchEventReceiver = new TouchEventTestee;
+
+ QGraphicsScene scene;
+ scene.addItem(touchEventReceiver);
+ const QPointF itemPos(100, 100);
+
+ touchEventReceiver->setPos(itemPos);
+
+ touchEventReceiver->setFlag(flag, true);
+
+ QGraphicsView view(&scene);
+ view.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1String("::")
+ + QLatin1String(QTest::currentDataTag()));
+ view.setSceneRect(QRectF(QPointF(0, 0), QSizeF(300, 300)));
+ view.setTransform(viewTransform);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QCOMPARE(touchEventReceiver->touchBeginEventCount(), 0);
+
+ if (m_touchDevice == nullptr)
+ m_touchDevice = QTest::createTouchDevice();
+ QTouchEvent touchBegin(QEvent::TouchBegin, m_touchDevice, Qt::NoModifier, Qt::TouchPointPressed,
+ createTouchPoints(view, touchScenePos, ellipseDiameters));
+ touchBegin.setTarget(view.viewport());
+
+ QCoreApplication::sendEvent(&scene, &touchBegin);
+ QCOMPARE(touchEventReceiver->touchBeginEventCount(), 1);
+
+ const QTouchEvent::TouchPoint touchBeginPoint = touchEventReceiver->touchBeginPoints().constFirst();
+
+ COMPARE_POINTF(touchBeginPoint.scenePos(), touchScenePos);
+ COMPARE_POINTF(touchBeginPoint.startScenePos(), touchScenePos);
+ COMPARE_POINTF(touchBeginPoint.lastScenePos(), touchScenePos);
+ COMPARE_POINTF(touchBeginPoint.pos(), expectedItemPos);
+ COMPARE_SIZEF(touchBeginPoint.ellipseDiameters(), ellipseDiameters); // Must remain untransformed
+
+ QTouchEvent touchUpdate(QEvent::TouchUpdate, m_touchDevice, Qt::NoModifier, Qt::TouchPointMoved,
+ createTouchPoints(view, touchScenePos, ellipseDiameters, Qt::TouchPointMoved));
+ touchUpdate.setTarget(view.viewport());
+
+ QCoreApplication::sendEvent(&scene, &touchUpdate);
+ QCOMPARE(touchEventReceiver->touchUpdateEventCount(), 1);
+
+ const QTouchEvent::TouchPoint touchUpdatePoint = touchEventReceiver->touchUpdatePoints().constFirst();
+
+ COMPARE_POINTF(touchUpdatePoint.scenePos(), touchScenePos);
+ COMPARE_POINTF(touchBeginPoint.startScenePos(), touchScenePos);
+ COMPARE_POINTF(touchUpdatePoint.lastScenePos(), touchScenePos);
+ COMPARE_POINTF(touchUpdatePoint.pos(), expectedItemPos);
+ COMPARE_SIZEF(touchUpdatePoint.ellipseDiameters(), ellipseDiameters); // Must remain untransformed
- qApp->sendEvent(&scene, &touchBegin);
- QCOMPARE(touchEventReceiver->touchBeginEventCount, expectedCount);
}
void tst_QGraphicsItem::deviceCoordinateCache_simpleRotations()
diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
index fe8571abf1..3b340d06ab 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
@@ -254,7 +254,6 @@ private slots:
void zeroScale();
void focusItemChangedSignal();
void minimumRenderSize();
- void checkTouchPointsEllipseDiameters();
// task specific tests below me
void task139710_bspTreeCrash();
@@ -4765,81 +4764,6 @@ void tst_QGraphicsScene::minimumRenderSize()
QVERIFY(smallChild->repaints > smallerGrandChild->repaints);
}
-class TouchItem : public QGraphicsRectItem
-{
-public:
- TouchItem() : QGraphicsRectItem(QRectF(-10, -10, 20, 20)),
- seenTouch(false)
- {
- setAcceptTouchEvents(true);
- setFlag(QGraphicsItem::ItemIgnoresTransformations);
- }
- bool seenTouch;
- QList<QTouchEvent::TouchPoint> touchPoints;
-protected:
- bool sceneEvent(QEvent *event) override
- {
- switch (event->type()) {
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- seenTouch = true;
- touchPoints = static_cast<QTouchEvent *>(event)->touchPoints();
- event->accept();
- return true;
- default:
- break;
- }
- return QGraphicsRectItem::sceneEvent(event);
- }
-};
-
-void tst_QGraphicsScene::checkTouchPointsEllipseDiameters()
-{
- QGraphicsScene scene;
- QGraphicsView view(&scene);
- scene.setSceneRect(1, 1, 198, 198);
- view.scale(1.5, 1.5);
- view.setFocus();
- TouchItem *rect = new TouchItem;
- scene.addItem(rect);
- view.show();
- QApplication::setActiveWindow(&view);
- QVERIFY(QTest::qWaitForWindowActive(&view));
-
- const QSizeF ellipseDiameters(10.0, 10.0);
- QTouchEvent::TouchPoint touchPoint(0);
- touchPoint.setState(Qt::TouchPointPressed);
- touchPoint.setPos(view.mapFromScene(rect->mapToScene(rect->boundingRect().center())));
- touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint()));
- touchPoint.setEllipseDiameters(ellipseDiameters);
-
- QList<QTouchEvent::TouchPoint> touchPoints = { touchPoint };
-
- QTouchDevice *testDevice = QTest::createTouchDevice(QTouchDevice::TouchPad);
- QTouchEvent touchEvent(QEvent::TouchBegin,
- testDevice,
- Qt::NoModifier,
- Qt::TouchPointPressed,
- touchPoints);
- QApplication::sendEvent(view.viewport(), &touchEvent);
- QVERIFY(rect->seenTouch);
- QVERIFY(rect->touchPoints.size() == 1);
- QCOMPARE(ellipseDiameters, rect->touchPoints.first().ellipseDiameters());
-
- rect->seenTouch = false;
- rect->touchPoints.clear();
- QTouchEvent touchUpdateEvent(QEvent::TouchUpdate,
- testDevice,
- Qt::NoModifier,
- Qt::TouchPointMoved,
- touchPoints);
- QApplication::sendEvent(view.viewport(), &touchEvent);
- QVERIFY(rect->seenTouch);
- QVERIFY(rect->touchPoints.size() == 1);
- QCOMPARE(ellipseDiameters, rect->touchPoints.first().ellipseDiameters());
-}
-
void tst_QGraphicsScene::taskQTBUG_15977_renderWithDeviceCoordinateCache()
{
QGraphicsScene scene;
diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
index 045c242fb4..9015c03f3f 100644
--- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
@@ -411,6 +411,7 @@ void tst_QLineEdit::cleanup()
{
delete m_testWidget;
m_testWidget = 0;
+ m_platformInputContext.m_commitString.clear();
}
void tst_QLineEdit::experimental()
diff --git a/tests/benchmarks/sql/kernel/kernel.pro b/tests/benchmarks/sql/kernel/kernel.pro
index f907feeeac..63887daf5f 100644
--- a/tests/benchmarks/sql/kernel/kernel.pro
+++ b/tests/benchmarks/sql/kernel/kernel.pro
@@ -1,3 +1,4 @@
TEMPLATE = subdirs
SUBDIRS = \
qsqlquery \
+ qsqlrecord
diff --git a/tests/benchmarks/sql/kernel/qsqlrecord/qsqlrecord.pro b/tests/benchmarks/sql/kernel/qsqlrecord/qsqlrecord.pro
new file mode 100644
index 0000000000..840a11bfbe
--- /dev/null
+++ b/tests/benchmarks/sql/kernel/qsqlrecord/qsqlrecord.pro
@@ -0,0 +1,5 @@
+TARGET = tst_bench_qsqlrecord
+
+SOURCES += tst_qsqlrecord.cpp
+
+QT = core sql testlib core-private sql-private
diff --git a/tests/benchmarks/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp b/tests/benchmarks/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp
new file mode 100644
index 0000000000..465dabca0e
--- /dev/null
+++ b/tests/benchmarks/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2018 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtSql/QtSql>
+
+#include "../../../../auto/sql/kernel/qsqldatabase/tst_databases.h"
+
+const QString qtest(qTableName("qtest", __FILE__, QSqlDatabase()));
+
+class tst_QSqlRecord : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QSqlRecord();
+ virtual ~tst_QSqlRecord();
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void benchmarkRecord_data() { generic_data(); }
+ void benchmarkRecord();
+
+private:
+ void generic_data(const QString &engine = QString());
+ void dropTestTables(QSqlDatabase db);
+ void createTestTables(QSqlDatabase db);
+ void populateTestTables(QSqlDatabase db);
+
+ tst_Databases dbs;
+};
+
+QTEST_MAIN(tst_QSqlRecord)
+
+tst_QSqlRecord::tst_QSqlRecord()
+{
+}
+
+tst_QSqlRecord::~tst_QSqlRecord()
+{
+}
+
+void tst_QSqlRecord::initTestCase()
+{
+ dbs.open();
+ for (const auto &dbName : qAsConst(dbs.dbNames)) {
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ dropTestTables(db); // In case of leftovers
+ createTestTables(db);
+ populateTestTables(db);
+ }
+}
+
+void tst_QSqlRecord::cleanupTestCase()
+{
+ for (const auto &dbName : qAsConst(dbs.dbNames)) {
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ dropTestTables(db);
+ }
+ dbs.close();
+}
+
+void tst_QSqlRecord::init()
+{
+}
+
+void tst_QSqlRecord::cleanup()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
+
+ if (QTest::currentTestFailed() && (dbType == QSqlDriver::Oracle ||
+ db.driverName().startsWith("QODBC"))) {
+ // Since Oracle ODBC has a problem when encountering an error, we init again
+ db.close();
+ db.open();
+ }
+}
+
+void tst_QSqlRecord::generic_data(const QString &engine)
+{
+ if (dbs.fillTestTable(engine) == 0) {
+ if (engine.isEmpty())
+ QSKIP("No database drivers are available in this Qt configuration");
+ else
+ QSKIP(QString("No database drivers of type %1 are available in this Qt configuration").arg(engine).toLocal8Bit());
+ }
+}
+
+void tst_QSqlRecord::dropTestTables(QSqlDatabase db)
+{
+ QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
+ QStringList tablenames;
+ // drop all the tables in case a testcase failed
+ tablenames << qtest
+ << qTableName("record", __FILE__, db);
+ tst_Databases::safeDropTables(db, tablenames);
+
+ if (dbType == QSqlDriver::Oracle) {
+ QSqlQuery q(db);
+ q.exec("DROP PACKAGE " + qTableName("pkg", __FILE__, db));
+ }
+}
+
+void tst_QSqlRecord::createTestTables(QSqlDatabase db)
+{
+ QSqlQuery q(db);
+ switch (tst_Databases::getDatabaseType(db)) {
+ case QSqlDriver::PostgreSQL:
+ QVERIFY_SQL(q, exec("set client_min_messages='warning'"));
+ QVERIFY_SQL(q, exec("create table " + qtest + " (id serial NOT NULL, t_varchar varchar(20), "
+ "t_char char(20), primary key(id)) WITH OIDS"));
+ break;
+ case QSqlDriver::MySqlServer:
+ QVERIFY_SQL(q, exec("set table_type=innodb"));
+ Q_FALLTHROUGH();
+ default:
+ QVERIFY_SQL(q, exec("create table " + qtest + " (id int " + tst_Databases::autoFieldName(db) +
+ " NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id))"));
+ break;
+ }
+}
+
+void tst_QSqlRecord::populateTestTables(QSqlDatabase db)
+{
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec("delete from " + qtest));
+ QVERIFY_SQL(q, exec("insert into " + qtest + " values (1, 'VarChar1', 'Char1')"));
+ QVERIFY_SQL(q, exec("insert into " + qtest + " values (2, 'VarChar2', 'Char2')"));
+ QVERIFY_SQL(q, exec("insert into " + qtest + " values (3, 'VarChar3', 'Char3')"));
+ QVERIFY_SQL(q, exec("insert into " + qtest + " values (4, 'VarChar4', 'Char4')"));
+ QVERIFY_SQL(q, exec("insert into " + qtest + " values (5, 'VarChar5', 'Char5')"));
+}
+
+void tst_QSqlRecord::benchmarkRecord()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ const auto tableName = qTableName("record", __FILE__, db);
+ {
+ QSqlQuery qry(db);
+ QVERIFY_SQL(qry, exec("create table " + tableName + " (id int NOT NULL, t_varchar varchar(20), "
+ "t_char char(20), primary key(id))"));
+ for (int i = 0; i < 1000; i++)
+ QVERIFY_SQL(qry, exec(QString("INSERT INTO " + tableName +
+ " VALUES (%1, 'VarChar%1', 'Char%1')").arg(i)));
+ QVERIFY_SQL(qry, exec(QString("SELECT * from ") + tableName));
+ QBENCHMARK {
+ while (qry.next())
+ qry.record();
+ }
+ }
+ tst_Databases::safeDropTables(db, QStringList() << tableName);
+}
+
+#include "tst_qsqlrecord.moc"