Merge remote-tracking branch 'origin/5.11' into dev
Change-Id: I9c90d71fde002544fd97df7e8a2690953cf9f817
This commit is contained in:
commit
b949c44783
@ -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:
|
||||
|
154
dist/changes-5.10.1
vendored
Normal file
154
dist/changes-5.10.1
vendored
Normal file
@ -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.
|
Binary file not shown.
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 8.9 KiB |
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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,8 +1140,14 @@ QString QGuiApplication::platformName()
|
||||
*QGuiApplicationPrivate::platform_name : QString();
|
||||
}
|
||||
|
||||
static void init_platform(const QString &pluginArgument, const QString &platformPluginPath, const QString &platformThemeName, int &argc, char **argv)
|
||||
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();
|
||||
@ -1150,21 +1158,29 @@ static void init_platform(const QString &pluginArgument, const QString &platform
|
||||
// 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;
|
||||
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");
|
||||
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 {
|
||||
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));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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 (Q_UNLIKELY(!QGuiApplicationPrivate::platform_integration)) {
|
||||
QString fatalMessage = QStringLiteral("This application failed to start because no Qt platform plugin could be initialized. "
|
||||
"Reinstalling the application may fix this problem.\n");
|
||||
|
||||
if (!availablePlugins.isEmpty())
|
||||
fatalMessage += QStringLiteral("\nAvailable platform plugins are: %1.\n").arg(availablePlugins.join(QLatin1String(", ")));
|
||||
|
||||
#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]);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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__
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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__
|
||||
|
@ -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;
|
||||
|
@ -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 ®ion)
|
||||
{
|
||||
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()
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -275,7 +275,7 @@ void tst_QSqlTableModel::init()
|
||||
|
||||
void tst_QSqlTableModel::cleanup()
|
||||
{
|
||||
repopulateTestTables();
|
||||
recreateTestTables();
|
||||
}
|
||||
|
||||
void tst_QSqlTableModel::select()
|
||||
|
@ -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());
|
||||
|
||||
QList<QTouchEvent::TouchPoint> touchPoints;
|
||||
touchPoints << tp;
|
||||
|
||||
sendMousePress(&scene, tp.scenePos());
|
||||
QTouchDevice *device = QTest::createTouchDevice();
|
||||
QTouchEvent touchBegin(QEvent::TouchBegin, device, Qt::NoModifier, Qt::TouchPointPressed, touchPoints);
|
||||
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());
|
||||
|
||||
qApp->sendEvent(&scene, &touchBegin);
|
||||
QCOMPARE(touchEventReceiver->touchBeginEventCount, expectedCount);
|
||||
QCOMPARE(touchEventReceiver->touchBeginEventCount(), expectedCount);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
void tst_QGraphicsItem::deviceCoordinateCache_simpleRotations()
|
||||
|
@ -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;
|
||||
|
@ -411,6 +411,7 @@ void tst_QLineEdit::cleanup()
|
||||
{
|
||||
delete m_testWidget;
|
||||
m_testWidget = 0;
|
||||
m_platformInputContext.m_commitString.clear();
|
||||
}
|
||||
|
||||
void tst_QLineEdit::experimental()
|
||||
|
@ -1,3 +1,4 @@
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS = \
|
||||
qsqlquery \
|
||||
qsqlrecord
|
||||
|
5
tests/benchmarks/sql/kernel/qsqlrecord/qsqlrecord.pro
Normal file
5
tests/benchmarks/sql/kernel/qsqlrecord/qsqlrecord.pro
Normal file
@ -0,0 +1,5 @@
|
||||
TARGET = tst_bench_qsqlrecord
|
||||
|
||||
SOURCES += tst_qsqlrecord.cpp
|
||||
|
||||
QT = core sql testlib core-private sql-private
|
191
tests/benchmarks/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp
Normal file
191
tests/benchmarks/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp
Normal file
@ -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"
|
Loading…
Reference in New Issue
Block a user