Merge remote-tracking branch 'origin/5.12.1' into 5.12
Change-Id: Icebd151eae0cf9d400319a42573290d1a911ce26bb10
commit
e3da05f39a
|
|
@ -0,0 +1,167 @@
|
|||
Qt 5.12.1 is a bug-fix release. It maintains both forward and backward
|
||||
compatibility (source and binary) with Qt 5.12.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.12 series is binary compatible with the 5.11.x series.
|
||||
Applications compiled for 5.11 will continue to run with 5.12.
|
||||
|
||||
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.
|
||||
|
||||
****************************************************************************
|
||||
* Important Behavior Changes *
|
||||
****************************************************************************
|
||||
|
||||
- qmake / WinRT:
|
||||
* Cross-builds will now ignore pre-set values of %INCLUDE% and %LIB%
|
||||
when building target executables. If necessary, use configure's -I and
|
||||
-L switches when building Qt, and pass QMAKE_INCDIR and QMAKE_LIBDIR
|
||||
on qmake's command line when building own projects.
|
||||
|
||||
****************************************************************************
|
||||
* Documentation *
|
||||
****************************************************************************
|
||||
|
||||
- Fixed the icons for the "file save" action that were inaccurate
|
||||
representations of a 3.5-inch floppy disk (the cut edge was on the wrong
|
||||
side). Now all floppy representations are physically accurate.
|
||||
|
||||
****************************************************************************
|
||||
* QtCore *
|
||||
****************************************************************************
|
||||
|
||||
- [QTBUG-71256] QString, QByteArray and QLocale's toDouble return an infinity
|
||||
on overflow (since 5.7), while setting ok to false; this was at odds with
|
||||
their documented behavior of returning 0 on failure. The documentation now
|
||||
reflects the actual behavior.
|
||||
- [QTBUG-71868] QString, QByteArray and QLocale's toFloat returned an
|
||||
infinity on double-overflow (since 5.7) but returned 0 on a finite double
|
||||
outside float's range, while setting ok to false; this was at odds with
|
||||
their documented behavior of returning 0 on any failure. They also
|
||||
succeeded, returning zero, on underflow of float's range, unless double
|
||||
underflowed, where they failed. Changed the handling of values outside
|
||||
float's range to match that of values outside double's range: fail,
|
||||
returning an infinity on overflow or zero on underflow. The documentation
|
||||
now reflects the revised behavior, which matches toDouble().
|
||||
|
||||
- QCborStreamReader:
|
||||
* [QTBUG-71426] Made setDevice() clear the last error.
|
||||
|
||||
- QCollator:
|
||||
* [QTBUG-58621] Added support for collation in the C locale, albeit this is
|
||||
only well-defined for ASCII. Collation sort keys remain unsupported on
|
||||
Darwin.
|
||||
|
||||
- QContiguousCache:
|
||||
* [QTBUG-52125] Fixed a memory leak.
|
||||
|
||||
- QObject:
|
||||
* [QTBUG-32340] Fixed a bug that caused isSignalConnected() to return
|
||||
true if the signal was connected and later disconnected.
|
||||
* [QTBUG-71550] Fixed a bug that caused isSignalConnected() not to
|
||||
report signals that were connected by the QML engine.
|
||||
|
||||
- QPluginLoader:
|
||||
* [QTBUG-71443] Fixed the parsing of ELF headers (Linux, FreeBSD, Solaris,
|
||||
etc.), which could cause certain valid plugins to not be deteced as
|
||||
valid.
|
||||
|
||||
- QRegularExpression:
|
||||
* [QTBUG-72539] The wildcardToRegularExpression method now returns a
|
||||
properly anchored pattern.
|
||||
|
||||
- QSettings:
|
||||
* [QTBUG-72007] Fixed QSettings parsing of blank spaces after comment lines
|
||||
in INI-style configuration files.
|
||||
|
||||
- QStringListModel:
|
||||
* setData will now emit the dataChanged() signal only if the string set
|
||||
is different from the one already contained in the model
|
||||
|
||||
- QSysInfo:
|
||||
* [QTBUG-72489] Now returns "Mojave" in prettyProductName() for macOS
|
||||
10.14.
|
||||
|
||||
- QUrl:
|
||||
* [QTBUG-71973] Changed the normalization done by
|
||||
QUrl::NormalizePathSegments) to match what web browsers do for non-local
|
||||
URLs.
|
||||
|
||||
****************************************************************************
|
||||
* QtGui *
|
||||
****************************************************************************
|
||||
|
||||
- Text:
|
||||
* Fixed a bug where eliding text could change the height of its bounding
|
||||
rectangle for certain fonts.
|
||||
* Improved appearance of monochrome text on some platforms.
|
||||
* Fixed so ShowTabsAndSpaces will use the correct font.
|
||||
|
||||
****************************************************************************
|
||||
* QtSql *
|
||||
****************************************************************************
|
||||
|
||||
- PostgreSQL:
|
||||
* Added support for PostgreSQL 11
|
||||
|
||||
****************************************************************************
|
||||
* QtWidgets *
|
||||
****************************************************************************
|
||||
|
||||
- Reverted a Qt 5.12.0 behavior change in QToolTip that made plain tooltip
|
||||
text be wrapped automatically.
|
||||
- [QTBUG-72844] Fixed a regression related to accepting a Drag'n'Drop event.
|
||||
- [QTBUG-27110] Reverted a change that caused a regression related to
|
||||
styling a QListView using CSS.
|
||||
|
||||
- QWidgetLineControl/security:
|
||||
* Zero-out the string that contains a password entered into the
|
||||
QLineEdit
|
||||
* Preallocate a buffer for the string that contains the entered value
|
||||
when the QLineEdit serves as a password input field to minimize
|
||||
reallocations.
|
||||
|
||||
****************************************************************************
|
||||
* Platform Specific Changes *
|
||||
****************************************************************************
|
||||
|
||||
- Android:
|
||||
* QClipboard now supports HTML and URI data.
|
||||
|
||||
- Windows:
|
||||
* Reduced the number of font engines that are created when loading new
|
||||
fonts, fixing crashes in some special cases where a large number of
|
||||
fonts are created during a short period of time.
|
||||
|
||||
- X11:
|
||||
* [QTBUG-71296] Fixed a bug with open/close hand cursors not being shown
|
||||
correctly.
|
||||
* [QTBUG-46626][QTBUG-70756] Fixed a bug with dialogs hidden by other
|
||||
windows in certain use cases.
|
||||
|
||||
****************************************************************************
|
||||
* Third-Party Code *
|
||||
****************************************************************************
|
||||
|
||||
- [QTBUG-65503] Removed xkbcommon from bundled sources. This library is
|
||||
present on all supported platforms. The minimal required version now is
|
||||
0.5.0.
|
||||
- Updated bundled SQLite to version 3.26.0.
|
||||
|
||||
****************************************************************************
|
||||
* Tools *
|
||||
****************************************************************************
|
||||
|
||||
- moc now parses enum struct the same way as enum class therefore that
|
||||
keyword can be used with the Q_ENUM macro as well as Q_FLAG and
|
||||
Q_DECLARE_FLAGS.
|
||||
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
dita.metadata.default.author = Qt Project
|
||||
dita.metadata.default.permissions = all
|
||||
dita.metadata.default.publisher = Qt Project
|
||||
dita.metadata.default.copyryear = 2018
|
||||
dita.metadata.default.copyryear = 2019
|
||||
dita.metadata.default.copyrholder = The Qt Company Ltd
|
||||
dita.metadata.default.audience = programmer
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ HTML.footer += \
|
|||
" <ul id=\"menu-footer-submenu\" class=\"right clearfix\"><li id=\"menu-item-1795\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1795\"><a title=\"Sign into your account.\" href=\"https://account.qt.io/login\">Sign In</a></li>\n" \
|
||||
" <li id=\"menu-item-10375\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-10375\"><a href=\"mailto:feedback@theqtcompany.com?Subject=Feedback%20about%20doc.qt.io%20site\">Feedback</a></li>\n" \
|
||||
" <li id=\"menu-item-1494\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1494\"><a href=\"http://qt.io/contact-us/\">Contact us</a></li>\n" \
|
||||
" <li id=\"menu-item-4472\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4472\"><a href=\"http://qt.io/about-us/\">© 2018 The Qt Company</a></li>\n" \
|
||||
" <li id=\"menu-item-4472\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4472\"><a href=\"http://qt.io/about-us/\">© 2019 The Qt Company</a></li>\n" \
|
||||
" </ul>\n" \
|
||||
"</div>\n" \
|
||||
"</div>\n" \
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ HTML.footer = \
|
|||
"</div>\n" \
|
||||
"<div class=\"footer\">\n" \
|
||||
" <p>\n" \
|
||||
" <acronym title=\"Copyright\">©</acronym> 2018 The Qt Company Ltd.\n" \
|
||||
" <acronym title=\"Copyright\">©</acronym> 2019 The Qt Company Ltd.\n" \
|
||||
" Documentation contributions included herein are the copyrights of\n" \
|
||||
" their respective owners.<br/>" \
|
||||
" The documentation provided herein is licensed under the terms of the" \
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
HTML.footer = \
|
||||
" </div>\n" \
|
||||
" <p class=\"copy-notice\">\n" \
|
||||
" <acronym title=\"Copyright\">©</acronym> 2018 The Qt Company Ltd.\n" \
|
||||
" <acronym title=\"Copyright\">©</acronym> 2019 The Qt Company Ltd.\n" \
|
||||
" Documentation contributions included herein are the copyrights of\n" \
|
||||
" their respective owners. " \
|
||||
" The documentation provided herein is licensed under the terms of the" \
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ include(unix.conf)
|
|||
|
||||
QMAKE_RESOURCE = /Developer/Tools/Rez
|
||||
QMAKE_EXTENSION_SHLIB = dylib
|
||||
QMAKE_EXTENSIONS_AUX_SHLIB = tbd
|
||||
QMAKE_LIBDIR =
|
||||
|
||||
# sdk.prf will prefix the proper SDK sysroot
|
||||
|
|
|
|||
|
|
@ -531,8 +531,11 @@ defineTest(qtConfResolveLibs) {
|
|||
unix {
|
||||
# Under UNIX, we look for actual shared libraries, in addition
|
||||
# to static ones.
|
||||
shexts = $$QMAKE_EXTENSION_SHLIB $$QMAKE_EXTENSIONS_AUX_SHLIB
|
||||
for (ext, shexts) {
|
||||
lcan += $${QMAKE_PREFIX_SHLIB}$${lib}.$${ext}
|
||||
}
|
||||
lcan += \
|
||||
$${QMAKE_PREFIX_SHLIB}$${lib}.$${QMAKE_EXTENSION_SHLIB} \
|
||||
$${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB}
|
||||
} else {
|
||||
# Under Windows, we look only for static libraries, as even for DLLs
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
QMAKE_TARGET_COMPANY = The Qt Company Ltd.
|
||||
isEmpty(QMAKE_TARGET_PRODUCT): QMAKE_TARGET_PRODUCT = Qt5
|
||||
isEmpty(QMAKE_TARGET_DESCRIPTION): QMAKE_TARGET_DESCRIPTION = C++ Application Development Framework
|
||||
QMAKE_TARGET_COPYRIGHT = Copyright (C) 2018 The Qt Company Ltd.
|
||||
QMAKE_TARGET_COPYRIGHT = Copyright (C) 2019 The Qt Company Ltd.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ build_pass {
|
|||
windeployqt.commands = $$QMAKE_WINDEPLOYQT $$WINDEPLOYQT_OPTIONS -list target $$WINDEPLOYQT_TARGET > $$WINDEPLOYQT_OUTPUT
|
||||
|
||||
windeployqt_clean.commands = if exist $$WINDEPLOYQT_OUTPUT for /f %i in ($$WINDEPLOYQT_OUTPUT) do $$QMAKE_DEL_FILE %~fi && $$QMAKE_DEL_DIR %~pi
|
||||
QMAKE_EXTRA_TARGETS += windeployqt_clean
|
||||
DISTCLEAN_DEPS += windeployqt_clean
|
||||
QMAKE_DISTCLEAN += $$WINDEPLOYQT_OUTPUT
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -424,6 +424,9 @@ MakefileGenerator::init()
|
|||
}
|
||||
incs.append(project->specDir());
|
||||
|
||||
const auto platform = v["QMAKE_PLATFORM"];
|
||||
resolveDependenciesInFrameworks = platform.contains("darwin");
|
||||
|
||||
const char * const cacheKeys[] = { "_QMAKE_STASH_", "_QMAKE_SUPER_CACHE_", nullptr };
|
||||
for (int i = 0; cacheKeys[i]; ++i) {
|
||||
if (v[cacheKeys[i]].isEmpty())
|
||||
|
|
@ -1839,6 +1842,33 @@ static QStringList splitDeps(const QString &indeps, bool lineMode)
|
|||
return deps;
|
||||
}
|
||||
|
||||
QString MakefileGenerator::resolveDependency(const QDir &outDir, const QString &file)
|
||||
{
|
||||
const QList<QMakeLocalFileName> &depdirs = QMakeSourceFileInfo::dependencyPaths();
|
||||
for (const auto &depdir : depdirs) {
|
||||
const QString &local = depdir.local();
|
||||
QString lf = outDir.absoluteFilePath(local + '/' + file);
|
||||
if (exists(lf))
|
||||
return lf;
|
||||
|
||||
if (resolveDependenciesInFrameworks) {
|
||||
// Given a file like "QtWidgets/QWidget", try to resolve it
|
||||
// as framework header "QtWidgets.framework/Headers/QWidget".
|
||||
int cut = file.indexOf('/');
|
||||
if (cut < 0 || cut + 1 >= file.size())
|
||||
continue;
|
||||
QStringRef framework = file.leftRef(cut);
|
||||
QStringRef include = file.midRef(cut + 1);
|
||||
if (local.endsWith('/' + framework + ".framework/Headers")) {
|
||||
lf = outDir.absoluteFilePath(local + '/' + include);
|
||||
if (exists(lf))
|
||||
return lf;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void
|
||||
MakefileGenerator::writeExtraCompilerTargets(QTextStream &t)
|
||||
{
|
||||
|
|
@ -1991,16 +2021,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t)
|
|||
} else if (exists(absFile)) {
|
||||
file = absFile;
|
||||
} else {
|
||||
QString localFile;
|
||||
QList<QMakeLocalFileName> depdirs = QMakeSourceFileInfo::dependencyPaths();
|
||||
for (QList<QMakeLocalFileName>::Iterator dit = depdirs.begin();
|
||||
dit != depdirs.end(); ++dit) {
|
||||
QString lf = outDir.absoluteFilePath((*dit).local() + '/' + file);
|
||||
if (exists(lf)) {
|
||||
localFile = lf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
QString localFile = resolveDependency(outDir, file);
|
||||
if (localFile.isEmpty()) {
|
||||
if (exists(file))
|
||||
warn_msg(WarnDeprecated, ".depend_command for extra compiler %s"
|
||||
|
|
@ -2088,16 +2109,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t)
|
|||
} else if (exists(absFile)) {
|
||||
file = absFile;
|
||||
} else {
|
||||
QString localFile;
|
||||
QList<QMakeLocalFileName> depdirs = QMakeSourceFileInfo::dependencyPaths();
|
||||
for (QList<QMakeLocalFileName>::Iterator dit = depdirs.begin();
|
||||
dit != depdirs.end(); ++dit) {
|
||||
QString lf = outDir.absoluteFilePath((*dit).local() + '/' + file);
|
||||
if (exists(lf)) {
|
||||
localFile = lf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
QString localFile = resolveDependency(outDir, file);
|
||||
if (localFile.isEmpty()) {
|
||||
if (exists(file))
|
||||
warn_msg(WarnDeprecated, ".depend_command for extra compiler %s"
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ class MakefileGenerator : protected QMakeSourceFileInfo
|
|||
{
|
||||
QString spec;
|
||||
bool no_io;
|
||||
bool resolveDependenciesInFrameworks = false;
|
||||
QHash<QString, bool> init_compiler_already;
|
||||
QString makedir, chkexists;
|
||||
QString build_args();
|
||||
|
|
@ -82,6 +83,7 @@ protected:
|
|||
void writeExportedVariables(QTextStream &t);
|
||||
void writeExtraVariables(QTextStream &t);
|
||||
void writeExtraTargets(QTextStream &t);
|
||||
QString resolveDependency(const QDir &outDir, const QString &file);
|
||||
void writeExtraCompilerTargets(QTextStream &t);
|
||||
void writeExtraCompilerVariables(QTextStream &t);
|
||||
bool writeDummyMakefile(QTextStream &t);
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
|
|||
if (impexts.isEmpty())
|
||||
impexts = project->values("QMAKE_EXTENSION_STATICLIB");
|
||||
QList<QMakeLocalFileName> dirs;
|
||||
for (const ProString &dlib : project->values("QMAKE_DEFAULT_LIBDIRS"))
|
||||
dirs.append(QMakeLocalFileName(dlib.toQString()));
|
||||
static const char * const lflags[] = { "LIBS", "LIBS_PRIVATE",
|
||||
"QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr };
|
||||
for (int i = 0; lflags[i]; i++) {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
"Description": "strtoll() and strtoull() are functions for converting a string to (unsigned) long long integer.",
|
||||
"Homepage": "https://github.com/freebsd/freebsd/",
|
||||
"Upstream": "https://raw.githubusercontent.com/freebsd/freebsd/raw/tree/master/lib/libc/stdlib/$file",
|
||||
"DownloadLocation": "https://github.com/freebsd/freebsd/tree/master/lib/libc/stdlib",
|
||||
"Version": "upstream has complicated with std locales; do not update",
|
||||
"Version": "18b29f3fb8abee5d57ed8f4a44f806bec7e0eeff",
|
||||
"License": "BSD 3-clause \"New\" or \"Revised\" License",
|
||||
|
|
|
|||
|
|
@ -69,8 +69,11 @@ DEFINES += FT2_BUILD_LIBRARY
|
|||
DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB
|
||||
include(../zlib_dependency.pri)
|
||||
|
||||
DEFINES += FT_CONFIG_OPTION_USE_PNG
|
||||
include($$OUT_PWD/../../gui/qtgui-config.pri)
|
||||
QMAKE_USE_PRIVATE += libpng
|
||||
QT_FOR_CONFIG += gui-private
|
||||
qtConfig(png) {
|
||||
DEFINES += FT_CONFIG_OPTION_USE_PNG
|
||||
QMAKE_USE_PRIVATE += libpng
|
||||
}
|
||||
|
||||
DEFINES += TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
"Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.",
|
||||
"Homepage": "https://www.sqlite.org/",
|
||||
"Version": "3.24.0",
|
||||
"DownloadLocation": "https://www.sqlite.org/2018/sqlite-amalgamation-3240000.zip",
|
||||
"Version": "3.26.0",
|
||||
"DownloadLocation": "https://www.sqlite.org/2018/sqlite-amalgamation-3260000.zip",
|
||||
"License": "Public Domain",
|
||||
"Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed."
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -123,9 +123,9 @@ extern "C" {
|
|||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.25.2"
|
||||
#define SQLITE_VERSION_NUMBER 3025002
|
||||
#define SQLITE_SOURCE_ID "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7"
|
||||
#define SQLITE_VERSION "3.26.0"
|
||||
#define SQLITE_VERSION_NUMBER 3026000
|
||||
#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
|
|
@ -2017,6 +2017,7 @@ struct sqlite3_mem_methods {
|
|||
** is invoked.
|
||||
**
|
||||
** <dl>
|
||||
** [[SQLITE_DBCONFIG_LOOKASIDE]]
|
||||
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
|
||||
** <dd> ^This option takes three additional arguments that determine the
|
||||
** [lookaside memory allocator] configuration for the [database connection].
|
||||
|
|
@ -2039,6 +2040,7 @@ struct sqlite3_mem_methods {
|
|||
** memory is in use leaves the configuration unchanged and returns
|
||||
** [SQLITE_BUSY].)^</dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
|
||||
** <dd> ^This option is used to enable or disable the enforcement of
|
||||
** [foreign key constraints]. There should be two additional arguments.
|
||||
|
|
@ -2049,6 +2051,7 @@ struct sqlite3_mem_methods {
|
|||
** following this call. The second parameter may be a NULL pointer, in
|
||||
** which case the FK enforcement setting is not reported back. </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
|
||||
** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
|
||||
** There should be two additional arguments.
|
||||
|
|
@ -2059,6 +2062,7 @@ struct sqlite3_mem_methods {
|
|||
** following this call. The second parameter may be a NULL pointer, in
|
||||
** which case the trigger setting is not reported back. </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
|
||||
** <dd> ^This option is used to enable or disable the two-argument
|
||||
** version of the [fts3_tokenizer()] function which is part of the
|
||||
|
|
@ -2072,6 +2076,7 @@ struct sqlite3_mem_methods {
|
|||
** following this call. The second parameter may be a NULL pointer, in
|
||||
** which case the new setting is not reported back. </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
|
||||
** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
|
||||
** interface independently of the [load_extension()] SQL function.
|
||||
|
|
@ -2089,7 +2094,7 @@ struct sqlite3_mem_methods {
|
|||
** be a NULL pointer, in which case the new setting is not reported back.
|
||||
** </dd>
|
||||
**
|
||||
** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
|
||||
** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
|
||||
** <dd> ^This option is used to change the name of the "main" database
|
||||
** schema. ^The sole argument is a pointer to a constant UTF8 string
|
||||
** which will become the new schema name in place of "main". ^SQLite
|
||||
|
|
@ -2098,6 +2103,7 @@ struct sqlite3_mem_methods {
|
|||
** until after the database connection closes.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]]
|
||||
** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
|
||||
** <dd> Usually, when a database in wal mode is closed or detached from a
|
||||
** database handle, SQLite checks if this will mean that there are now no
|
||||
|
|
@ -2111,7 +2117,7 @@ struct sqlite3_mem_methods {
|
|||
** have been disabled - 0 if they are not disabled, 1 if they are.
|
||||
** </dd>
|
||||
**
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
|
||||
** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
|
||||
** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
|
||||
** the [query planner stability guarantee] (QPSG). When the QPSG is active,
|
||||
** a single SQL query statement will always use the same algorithm regardless
|
||||
|
|
@ -2127,7 +2133,7 @@ struct sqlite3_mem_methods {
|
|||
** following this call.
|
||||
** </dd>
|
||||
**
|
||||
** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
|
||||
** [[SQLITE_DBCONFIG_TRIGGER_EQP]] <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
|
||||
** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
|
||||
** include output for any operations performed by trigger programs. This
|
||||
** option is used to set or clear (the default) a flag that governs this
|
||||
|
|
@ -2139,7 +2145,7 @@ struct sqlite3_mem_methods {
|
|||
** it is not disabled, 1 if it is.
|
||||
** </dd>
|
||||
**
|
||||
** <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
|
||||
** [[SQLITE_DBCONFIG_RESET_DATABASE]] <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
|
||||
** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
|
||||
** [VACUUM] in order to reset a database back to an empty database
|
||||
** with no schema and no content. The following process works even for
|
||||
|
|
@ -2158,6 +2164,18 @@ struct sqlite3_mem_methods {
|
|||
** Because resetting a database is destructive and irreversible, the
|
||||
** process requires the use of this obscure API and multiple steps to help
|
||||
** ensure that it does not happen by accident.
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
|
||||
** "defensive" flag for a database connection. When the defensive
|
||||
** flag is enabled, language features that allow ordinary SQL to
|
||||
** deliberately corrupt the database file are disabled. The disabled
|
||||
** features include but are not limited to the following:
|
||||
** <ul>
|
||||
** <li> The [PRAGMA writable_schema=ON] statement.
|
||||
** <li> Writes to the [sqlite_dbpage] virtual table.
|
||||
** <li> Direct writes to [shadow tables].
|
||||
** </ul>
|
||||
** </dd>
|
||||
** </dl>
|
||||
*/
|
||||
|
|
@ -2171,7 +2189,8 @@ struct sqlite3_mem_methods {
|
|||
#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
|
||||
#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
|
||||
#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */
|
||||
#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1010 /* Largest DBCONFIG */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Enable Or Disable Extended Result Codes
|
||||
|
|
@ -3609,9 +3628,19 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
|
|||
** on this hint by avoiding the use of [lookaside memory] so as not to
|
||||
** deplete the limited store of lookaside memory. Future versions of
|
||||
** SQLite may act on this hint differently.
|
||||
**
|
||||
** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
|
||||
** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
|
||||
** representation of the SQL statement should be calculated and then
|
||||
** associated with the prepared statement, which can be obtained via
|
||||
** the [sqlite3_normalized_sql()] interface.)^ The semantics used to
|
||||
** normalize a SQL statement are unspecified and subject to change.
|
||||
** At a minimum, literal values will be replaced with suitable
|
||||
** placeholders.
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_PREPARE_PERSISTENT 0x01
|
||||
#define SQLITE_PREPARE_NORMALIZE 0x02
|
||||
|
||||
/*
|
||||
** CAPI3REF: Compiling An SQL Statement
|
||||
|
|
@ -3769,6 +3798,11 @@ SQLITE_API int sqlite3_prepare16_v3(
|
|||
** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
|
||||
** string containing the SQL text of prepared statement P with
|
||||
** [bound parameters] expanded.
|
||||
** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
|
||||
** string containing the normalized SQL text of prepared statement P. The
|
||||
** semantics used to normalize a SQL statement are unspecified and subject
|
||||
** to change. At a minimum, literal values will be replaced with suitable
|
||||
** placeholders.
|
||||
**
|
||||
** ^(For example, if a prepared statement is created using the SQL
|
||||
** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
|
||||
|
|
@ -3784,14 +3818,16 @@ SQLITE_API int sqlite3_prepare16_v3(
|
|||
** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
|
||||
** option causes sqlite3_expanded_sql() to always return NULL.
|
||||
**
|
||||
** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
|
||||
** automatically freed when the prepared statement is finalized.
|
||||
** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
|
||||
** are managed by SQLite and are automatically freed when the prepared
|
||||
** statement is finalized.
|
||||
** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
|
||||
** is obtained from [sqlite3_malloc()] and must be free by the application
|
||||
** by passing it to [sqlite3_free()].
|
||||
*/
|
||||
SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
|
||||
SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
|
||||
SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Determine If An SQL Statement Writes The Database
|
||||
|
|
@ -6281,6 +6317,9 @@ struct sqlite3_module {
|
|||
int (*xSavepoint)(sqlite3_vtab *pVTab, int);
|
||||
int (*xRelease)(sqlite3_vtab *pVTab, int);
|
||||
int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
|
||||
/* The methods above are in versions 1 and 2 of the sqlite_module object.
|
||||
** Those below are for version 3 and greater. */
|
||||
int (*xShadowName)(const char*);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -7203,6 +7242,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
|
|||
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
|
||||
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
|
||||
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
|
||||
#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
|
||||
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
|
||||
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
|
||||
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
|
||||
|
|
@ -8615,6 +8655,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
|
|||
** can use to customize and optimize their behavior.
|
||||
**
|
||||
** <dl>
|
||||
** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
|
||||
** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
|
||||
** <dd>Calls of the form
|
||||
** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
|
||||
|
|
@ -9384,7 +9425,7 @@ struct sqlite3_rtree_query_info {
|
|||
sqlite3_int64 iRowid; /* Rowid for current entry */
|
||||
sqlite3_rtree_dbl rParentScore; /* Score of parent node */
|
||||
int eParentWithin; /* Visibility of parent node */
|
||||
int eWithin; /* OUT: Visiblity */
|
||||
int eWithin; /* OUT: Visibility */
|
||||
sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
|
||||
/* The following fields are only available in 3.8.11 and later */
|
||||
sqlite3_value **apSqlParam; /* Original SQL values of parameters */
|
||||
|
|
@ -9880,12 +9921,38 @@ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
|
|||
** consecutively. There is no chance that the iterator will visit a change
|
||||
** the applies to table X, then one for table Y, and then later on visit
|
||||
** another change for table X.
|
||||
**
|
||||
** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
|
||||
** may be modified by passing a combination of
|
||||
** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
|
||||
**
|
||||
** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b>
|
||||
** and therefore subject to change.
|
||||
*/
|
||||
SQLITE_API int sqlite3changeset_start(
|
||||
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
|
||||
int nChangeset, /* Size of changeset blob in bytes */
|
||||
void *pChangeset /* Pointer to blob containing changeset */
|
||||
);
|
||||
SQLITE_API int sqlite3changeset_start_v2(
|
||||
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
|
||||
int nChangeset, /* Size of changeset blob in bytes */
|
||||
void *pChangeset, /* Pointer to blob containing changeset */
|
||||
int flags /* SESSION_CHANGESETSTART_* flags */
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags for sqlite3changeset_start_v2
|
||||
**
|
||||
** The following flags may passed via the 4th parameter to
|
||||
** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
|
||||
**
|
||||
** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
|
||||
** Invert the changeset while iterating through it. This is equivalent to
|
||||
** inverting a changeset using sqlite3changeset_invert() before applying it.
|
||||
** It is an error to specify this flag with a patchset.
|
||||
*/
|
||||
#define SQLITE_CHANGESETSTART_INVERT 0x0002
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -10540,7 +10607,7 @@ SQLITE_API int sqlite3changeset_apply_v2(
|
|||
),
|
||||
void *pCtx, /* First argument passed to xConflict */
|
||||
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
|
||||
int flags /* Combination of SESSION_APPLY_* flags */
|
||||
int flags /* SESSION_CHANGESETAPPLY_* flags */
|
||||
);
|
||||
|
||||
/*
|
||||
|
|
@ -10558,8 +10625,14 @@ SQLITE_API int sqlite3changeset_apply_v2(
|
|||
** causes the sessions module to omit this savepoint. In this case, if the
|
||||
** caller has an open transaction or savepoint when apply_v2() is called,
|
||||
** it may revert the partially applied changeset by rolling it back.
|
||||
**
|
||||
** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
|
||||
** Invert the changeset before applying it. This is equivalent to inverting
|
||||
** a changeset using sqlite3changeset_invert() before applying it. It is
|
||||
** an error to specify this flag with a patchset.
|
||||
*/
|
||||
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
|
||||
#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
|
||||
|
||||
/*
|
||||
** CAPI3REF: Constants Passed To The Conflict Handler
|
||||
|
|
@ -10953,6 +11026,12 @@ SQLITE_API int sqlite3changeset_start_strm(
|
|||
int (*xInput)(void *pIn, void *pData, int *pnData),
|
||||
void *pIn
|
||||
);
|
||||
SQLITE_API int sqlite3changeset_start_v2_strm(
|
||||
sqlite3_changeset_iter **pp,
|
||||
int (*xInput)(void *pIn, void *pData, int *pnData),
|
||||
void *pIn,
|
||||
int flags
|
||||
);
|
||||
SQLITE_API int sqlite3session_changeset_strm(
|
||||
sqlite3_session *pSession,
|
||||
int (*xOutput)(void *pOut, const void *pData, int nData),
|
||||
|
|
@ -10979,6 +11058,45 @@ SQLITE_API int sqlite3rebaser_rebase_strm(
|
|||
void *pOut
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Configure global parameters
|
||||
**
|
||||
** The sqlite3session_config() interface is used to make global configuration
|
||||
** changes to the sessions module in order to tune it to the specific needs
|
||||
** of the application.
|
||||
**
|
||||
** The sqlite3session_config() interface is not threadsafe. If it is invoked
|
||||
** while any other thread is inside any other sessions method then the
|
||||
** results are undefined. Furthermore, if it is invoked after any sessions
|
||||
** related objects have been created, the results are also undefined.
|
||||
**
|
||||
** The first argument to the sqlite3session_config() function must be one
|
||||
** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The
|
||||
** interpretation of the (void*) value passed as the second parameter and
|
||||
** the effect of calling this function depends on the value of the first
|
||||
** parameter.
|
||||
**
|
||||
** <dl>
|
||||
** <dt>SQLITE_SESSION_CONFIG_STRMSIZE<dd>
|
||||
** By default, the sessions module streaming interfaces attempt to input
|
||||
** and output data in approximately 1 KiB chunks. This operand may be used
|
||||
** to set and query the value of this configuration setting. The pointer
|
||||
** passed as the second argument must point to a value of type (int).
|
||||
** If this value is greater than 0, it is used as the new streaming data
|
||||
** chunk size for both input and output. Before returning, the (int) value
|
||||
** pointed to by pArg is set to the final value of the streaming interface
|
||||
** chunk size.
|
||||
** </dl>
|
||||
**
|
||||
** This function returns SQLITE_OK if successful, or an SQLite error code
|
||||
** otherwise.
|
||||
*/
|
||||
SQLITE_API int sqlite3session_config(int op, void *pArg);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Values for sqlite3session_config().
|
||||
*/
|
||||
#define SQLITE_SESSION_CONFIG_STRMSIZE 1
|
||||
|
||||
/*
|
||||
** Make sure we can call this stuff from C++.
|
||||
|
|
|
|||
|
|
@ -612,7 +612,7 @@ public abstract class QtLoader {
|
|||
}
|
||||
|
||||
if (m_qtLibs != null) {
|
||||
String libPrefix = apkDeployFromSystem ? libsDir + "lib" : localPrefix + "lib/lib";
|
||||
String libPrefix = libsDir + "lib";
|
||||
for (int i = 0; i < m_qtLibs.length; i++)
|
||||
libraryList.add(libPrefix + m_qtLibs[i] + ".so");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,8 +83,12 @@ QString QWindowsLocalCodec::convertToUnicode(const char *chars, int length, Conv
|
|||
len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
|
||||
prev, 2, wc.data(), wc.length());
|
||||
if (len) {
|
||||
prepend = true;
|
||||
sp.append(QChar(wc[0]));
|
||||
if (mblen == 1) {
|
||||
state->remainingChars = 0;
|
||||
return sp;
|
||||
}
|
||||
prepend = true;
|
||||
mb++;
|
||||
mblen--;
|
||||
wc[0] = 0;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ excludedirs += snippets
|
|||
excludefiles += ../../../examples/widgets/tools/customcompleter/doc/src/customcompleter.qdoc \
|
||||
../../../examples/widgets/tools/codecs/doc/src/codecs.qdoc
|
||||
|
||||
# Included in qttestlib.qdocconf instead
|
||||
excludefiles += ../kernel/qtestsupport_core.cpp
|
||||
|
||||
manifestmeta.highlighted.names = "QtCore/JSON Save Game Example" \
|
||||
"QtCore/Local Fortune*"
|
||||
|
||||
|
|
|
|||
|
|
@ -2025,6 +2025,8 @@ static const char *osVer_helper(QOperatingSystemVersion version = QOperatingSyst
|
|||
return "Sierra";
|
||||
case 13:
|
||||
return "High Sierra";
|
||||
case 14:
|
||||
return "Mojave";
|
||||
}
|
||||
}
|
||||
// unknown, future version
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ template <> inline bool mul_overflow(qint64 v1, qint64 v2, qint64 *r)
|
|||
// as signed for the low bits and use a signed right shift to verify that
|
||||
// 'high' is nothing but sign bits that match the sign of 'low'.
|
||||
|
||||
qint64 high = __mulh(v1, v2);
|
||||
qint64 high = Q_SMULH(v1, v2);
|
||||
*r = qint64(quint64(v1) * quint64(v2));
|
||||
return (*r >> 63) != high;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -748,6 +748,21 @@ static int drivePrefixLength(const QString &path)
|
|||
}
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
static bool treatAsAbsolute(const QString &path)
|
||||
{
|
||||
// ### Qt 6: be consistent about absolute paths
|
||||
|
||||
// QFileInfo will use the right FS-engine for virtual file-systems
|
||||
// (e.g. resource paths). Unfortunately, for real file-systems, it relies
|
||||
// on QFileSystemEntry's isRelative(), which is flawed on MS-Win, ignoring
|
||||
// its (correct) isAbsolute(). So only use that isAbsolute() unless there's
|
||||
// a colon in the path.
|
||||
// FIXME: relies on virtual file-systems having colons in their prefixes.
|
||||
// The case of an MS-absolute C:/... path happens to work either way.
|
||||
return (path.contains(QLatin1Char(':')) && QFileInfo(path).isAbsolute())
|
||||
|| QFileSystemEntry(path).isAbsolute();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the path name of a file in the directory. Does \e not
|
||||
check if the file actually exists in the directory; but see
|
||||
|
|
@ -759,13 +774,10 @@ static int drivePrefixLength(const QString &path)
|
|||
*/
|
||||
QString QDir::filePath(const QString &fileName) const
|
||||
{
|
||||
const QDirPrivate* d = d_ptr.constData();
|
||||
// Mistrust our own isAbsolutePath() for real files; Q_OS_WIN needs a drive.
|
||||
if (fileName.startsWith(QLatin1Char(':')) // i.e. resource path
|
||||
? isAbsolutePath(fileName) : QFileSystemEntry(fileName).isAbsolute()) {
|
||||
if (treatAsAbsolute(fileName))
|
||||
return fileName;
|
||||
}
|
||||
|
||||
const QDirPrivate* d = d_ptr.constData();
|
||||
QString ret = d->dirEntry.filePath();
|
||||
if (fileName.isEmpty())
|
||||
return ret;
|
||||
|
|
@ -793,13 +805,10 @@ QString QDir::filePath(const QString &fileName) const
|
|||
*/
|
||||
QString QDir::absoluteFilePath(const QString &fileName) const
|
||||
{
|
||||
const QDirPrivate* d = d_ptr.constData();
|
||||
// Mistrust our own isAbsolutePath() for real files; Q_OS_WIN needs a drive.
|
||||
if (fileName.startsWith(QLatin1Char(':')) // i.e. resource path
|
||||
? isAbsolutePath(fileName) : QFileSystemEntry(fileName).isAbsolute()) {
|
||||
if (treatAsAbsolute(fileName))
|
||||
return fileName;
|
||||
}
|
||||
|
||||
const QDirPrivate* d = d_ptr.constData();
|
||||
d->resolveAbsoluteEntry();
|
||||
const QString absoluteDirPath = d->absoluteDirEntry.filePath();
|
||||
if (fileName.isEmpty())
|
||||
|
|
@ -2160,9 +2169,10 @@ bool QDir::match(const QString &filter, const QString &fileName)
|
|||
This method is shared with QUrl, so it doesn't deal with QDir::separator(),
|
||||
nor does it remove the trailing slash, if any.
|
||||
*/
|
||||
Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool allowUncPaths,
|
||||
bool *ok = nullptr)
|
||||
QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormalizations flags, bool *ok)
|
||||
{
|
||||
const bool allowUncPaths = QDirPrivate::AllowUncPaths & flags;
|
||||
const bool isRemote = QDirPrivate::RemotePath & flags;
|
||||
const int len = name.length();
|
||||
|
||||
if (ok)
|
||||
|
|
@ -2184,14 +2194,30 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all
|
|||
i -= prefixLength;
|
||||
|
||||
// replicate trailing slash (i > 0 checks for emptiness of input string p)
|
||||
if (i > 0 && p[i] == '/') {
|
||||
// except for remote paths because there can be /../ or /./ ending
|
||||
if (i > 0 && p[i] == '/' && !isRemote) {
|
||||
out[--used] = '/';
|
||||
--i;
|
||||
}
|
||||
|
||||
auto isDot = [](const ushort *p, int i) {
|
||||
return i > 1 && p[i - 1] == '.' && p[i - 2] == '/';
|
||||
};
|
||||
auto isDotDot = [](const ushort *p, int i) {
|
||||
return i > 2 && p[i - 1] == '.' && p[i - 2] == '.' && p[i - 3] == '/';
|
||||
};
|
||||
|
||||
while (i >= 0) {
|
||||
// remove trailing slashes
|
||||
// copy trailing slashes for remote urls
|
||||
if (p[i] == '/') {
|
||||
if (isRemote && !up) {
|
||||
if (isDot(p, i)) {
|
||||
i -= 2;
|
||||
continue;
|
||||
}
|
||||
out[--used] = p[i];
|
||||
}
|
||||
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -2203,10 +2229,17 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all
|
|||
}
|
||||
|
||||
// detect up dir
|
||||
if (i >= 1 && p[i] == '.' && p[i-1] == '.'
|
||||
&& (i == 1 || (i >= 2 && p[i-2] == '/'))) {
|
||||
if (i >= 1 && p[i] == '.' && p[i-1] == '.' && (i < 2 || p[i - 2] == '/')) {
|
||||
++up;
|
||||
i -= 2;
|
||||
i -= i >= 2 ? 3 : 2;
|
||||
|
||||
if (isRemote) {
|
||||
// moving up should consider empty path segments too (/path//../ -> /path/)
|
||||
while (i > 0 && up && p[i] == '/') {
|
||||
--up;
|
||||
--i;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -2216,7 +2249,27 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all
|
|||
|
||||
// skip or copy
|
||||
while (i >= 0) {
|
||||
if (p[i] == '/') { // do not copy slashes
|
||||
if (p[i] == '/') {
|
||||
// copy all slashes as is for remote urls if they are not part of /./ or /../
|
||||
if (isRemote && !up) {
|
||||
while (i > 0 && p[i] == '/' && !isDotDot(p, i)) {
|
||||
|
||||
if (isDot(p, i)) {
|
||||
i -= 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
out[--used] = p[i];
|
||||
--i;
|
||||
}
|
||||
|
||||
// in case of /./, jump over
|
||||
if (isDot(p, i))
|
||||
i -= 2;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
--i;
|
||||
break;
|
||||
}
|
||||
|
|
@ -2237,7 +2290,7 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all
|
|||
*ok = prefixLength == 0 || up == 0;
|
||||
|
||||
// add remaining '..'
|
||||
while (up) {
|
||||
while (up && !isRemote) {
|
||||
if (used != len && out[used] != '/') // is not empty and there isn't already a '/'
|
||||
out[--used] = '/';
|
||||
out[--used] = '.';
|
||||
|
|
@ -2283,7 +2336,7 @@ static QString qt_cleanPath(const QString &path, bool *ok)
|
|||
if (dir_separator != QLatin1Char('/'))
|
||||
name.replace(dir_separator, QLatin1Char('/'));
|
||||
|
||||
QString ret = qt_normalizePathSegments(name, OSSupportsUncPaths, ok);
|
||||
QString ret = qt_normalizePathSegments(name, OSSupportsUncPaths ? QDirPrivate::AllowUncPaths : QDirPrivate::DefaultNormalization, ok);
|
||||
|
||||
// Strip away last slash except for root directories
|
||||
if (ret.length() > 1 && ret.endsWith(QLatin1Char('/'))) {
|
||||
|
|
|
|||
|
|
@ -59,6 +59,14 @@ QT_BEGIN_NAMESPACE
|
|||
class QDirPrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
enum PathNormalization {
|
||||
DefaultNormalization = 0x00,
|
||||
AllowUncPaths = 0x01,
|
||||
RemotePath = 0x02
|
||||
};
|
||||
Q_DECLARE_FLAGS(PathNormalizations, PathNormalization)
|
||||
Q_FLAGS(PathNormalizations)
|
||||
|
||||
explicit QDirPrivate(const QString &path, const QStringList &nameFilters_ = QStringList(),
|
||||
QDir::SortFlags sort_ = QDir::SortFlags(QDir::Name | QDir::IgnoreCase),
|
||||
QDir::Filters filters_ = QDir::AllEntries);
|
||||
|
|
@ -97,6 +105,10 @@ public:
|
|||
mutable QFileSystemMetaData metaData;
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QDirPrivate::PathNormalizations)
|
||||
|
||||
Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormalizations flags, bool *ok = nullptr);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -253,7 +253,8 @@
|
|||
and contains no query or fragment, a local file path is returned.
|
||||
\value StripTrailingSlash The trailing slash is removed from the path, if one is present.
|
||||
\value NormalizePathSegments Modifies the path to remove redundant directory separators,
|
||||
and to resolve "."s and ".."s (as far as possible).
|
||||
and to resolve "."s and ".."s (as far as possible). For non-local paths, adjacent
|
||||
slashes are preserved.
|
||||
|
||||
Note that the case folding rules in \l{RFC 3491}{Nameprep}, which QUrl
|
||||
conforms to, require host names to always be converted to lower case,
|
||||
|
|
@ -419,10 +420,9 @@
|
|||
#endif
|
||||
#include "private/qipaddress_p.h"
|
||||
#include "qurlquery.h"
|
||||
#include "private/qdir_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
extern QString qt_normalizePathSegments(const QString &name, bool allowUncPaths,
|
||||
bool *ok = nullptr); // qdir.cpp
|
||||
|
||||
inline static bool isHex(char c)
|
||||
{
|
||||
|
|
@ -930,7 +930,7 @@ inline void QUrlPrivate::appendPath(QString &appendTo, QUrl::FormattingOptions o
|
|||
{
|
||||
QString thePath = path;
|
||||
if (options & QUrl::NormalizePathSegments) {
|
||||
thePath = qt_normalizePathSegments(path, false);
|
||||
thePath = qt_normalizePathSegments(path, isLocalFile() ? QDirPrivate::DefaultNormalization : QDirPrivate::RemotePath);
|
||||
}
|
||||
|
||||
QStringRef thePathRef(&thePath);
|
||||
|
|
|
|||
|
|
@ -59,8 +59,7 @@ Q_CORE_EXPORT void QTestPrivate::qSleep(int ms)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*! \fn template <typename Functor> bool qWaitFor(Functor predicate, int timeout)
|
||||
\relates QTest
|
||||
/*! \fn template <typename Functor> bool QTest::qWaitFor(Functor predicate, int timeout)
|
||||
|
||||
Waits for \a timeout milliseconds or until the \a predicate returns true.
|
||||
|
||||
|
|
@ -77,8 +76,7 @@ Q_CORE_EXPORT void QTestPrivate::qSleep(int ms)
|
|||
*/
|
||||
|
||||
|
||||
/*! \fn void qWait(int ms)
|
||||
\relates QTest
|
||||
/*! \fn void QTest::qWait(int ms)
|
||||
|
||||
Waits for \a ms milliseconds. While waiting, events will be processed and
|
||||
your test will stay responsive to user interface events or network communication.
|
||||
|
|
|
|||
|
|
@ -54,7 +54,10 @@ exampledirs += ../../../examples/gui \
|
|||
|
||||
imagedirs += images \
|
||||
../../../examples/gui/doc/images \
|
||||
../../../doc/src/images \
|
||||
../../../doc/src/images
|
||||
|
||||
# Included in qttestlib.qdocconf instead
|
||||
excludefiles += ../kernel/qtestsupport_gui.cpp
|
||||
|
||||
manifestmeta.highlighted.names = "QtGui/Analog Clock Window Example"
|
||||
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ static bool read_dib_infoheader(QDataStream &s, BMP_INFOHDR &bi)
|
|||
if (!(comp == BMP_RGB || (nbits == 4 && comp == BMP_RLE4) ||
|
||||
(nbits == 8 && comp == BMP_RLE8) || ((nbits == 16 || nbits == 32) && comp == BMP_BITFIELDS)))
|
||||
return false; // weird compression type
|
||||
if (bi.biWidth < 0 || quint64(bi.biWidth) * qAbs(bi.biHeight) > 16384 * 16384)
|
||||
if (bi.biWidth <= 0 || !bi.biHeight || quint64(bi.biWidth) * qAbs(bi.biHeight) > 16384 * 16384)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -3543,7 +3543,7 @@ void QImage::rgbSwapped_inplace()
|
|||
The loader attempts to read the image using the specified \a format, e.g.,
|
||||
PNG or JPG. If \a format is not specified (which is the default), it is
|
||||
auto-detected based on the file's suffix and header. For details, see
|
||||
{QImageReader::setAutoDetectImageFormat()}{QImageReader}.
|
||||
QImageReader::setAutoDetectImageFormat().
|
||||
|
||||
The file name can either refer to an actual file on disk or to one
|
||||
of the application's embedded resources. See the
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ public:
|
|||
virtual bool isActive() const;
|
||||
virtual bool isAncestorOf(const QPlatformWindow *child) const;
|
||||
virtual bool isEmbedded() const;
|
||||
virtual bool isForeignWindow() const { return window()->type() == Qt::ForeignWindow; };
|
||||
virtual bool isForeignWindow() const { return false; };
|
||||
virtual QPoint mapToGlobal(const QPoint &pos) const;
|
||||
virtual QPoint mapFromGlobal(const QPoint &pos) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -44,23 +44,21 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*! \fn bool qWaitForWindowActive(QWindow *window, int timeout)
|
||||
\relates QTest
|
||||
/*!
|
||||
\since 5.0
|
||||
|
||||
Waits for \a timeout milliseconds or until the \a window is active.
|
||||
|
||||
Returns \c true if \c window is active within \a timeout milliseconds, otherwise returns \c false.
|
||||
|
||||
\sa QTest::qWaitForWindowExposed(), QWindow::isActive()
|
||||
\sa qWaitForWindowExposed(), QWindow::isActive()
|
||||
*/
|
||||
Q_GUI_EXPORT bool QTest::qWaitForWindowActive(QWindow *window, int timeout)
|
||||
{
|
||||
return QTest::qWaitFor([&]() { return window->isActive(); }, timeout);
|
||||
}
|
||||
|
||||
/*! \fn bool qWaitForWindowExposed(QWindow *window, int timeout)
|
||||
\relates QTest
|
||||
/*!
|
||||
\since 5.0
|
||||
|
||||
Waits for \a timeout milliseconds or until the \a window is exposed.
|
||||
|
|
@ -73,7 +71,7 @@ Q_GUI_EXPORT bool QTest::qWaitForWindowActive(QWindow *window, int timeout)
|
|||
area is completely covered by other windows, or if the window is otherwise not visible. This function
|
||||
will then time out when waiting for such a window.
|
||||
|
||||
\sa QTest::qWaitForWindowActive(), QWindow::isExposed()
|
||||
\sa qWaitForWindowActive(), QWindow::isExposed()
|
||||
*/
|
||||
Q_GUI_EXPORT bool QTest::qWaitForWindowExposed(QWindow *window, int timeout)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -919,8 +919,7 @@ void QWindow::setFlag(Qt::WindowType flag, bool on)
|
|||
*/
|
||||
Qt::WindowType QWindow::type() const
|
||||
{
|
||||
Q_D(const QWindow);
|
||||
return static_cast<Qt::WindowType>(int(d->windowFlags & Qt::WindowType_Mask));
|
||||
return static_cast<Qt::WindowType>(int(flags() & Qt::WindowType_Mask));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -1953,13 +1953,14 @@ void QPdfEnginePrivate::writePage()
|
|||
"/Contents %d 0 R\n"
|
||||
"/Resources %d 0 R\n"
|
||||
"/Annots %d 0 R\n"
|
||||
"/MediaBox [0 0 %f %f]\n",
|
||||
"/MediaBox [0 0 %s %s]\n",
|
||||
pageRoot, pageStream, resources, annots,
|
||||
// make sure we use the pagesize from when we started the page, since the user may have changed it
|
||||
currentPage->pageSize.width() / userUnit, currentPage->pageSize.height() / userUnit);
|
||||
QByteArray::number(currentPage->pageSize.width() / userUnit, 'f').constData(),
|
||||
QByteArray::number(currentPage->pageSize.height() / userUnit, 'f').constData());
|
||||
|
||||
if (pdfVersion >= QPdfEngine::Version_1_6)
|
||||
xprintf("/UserUnit %f\n", userUnit);
|
||||
xprintf("/UserUnit %s\n", QByteArray::number(userUnit, 'f').constData());
|
||||
|
||||
xprintf(">>\n"
|
||||
"endobj\n");
|
||||
|
|
|
|||
|
|
@ -1972,14 +1972,18 @@ void QTextEngine::shape(int item) const
|
|||
}
|
||||
// fix log clusters to point to the previous glyph, as the object doesn't have a glyph of it's own.
|
||||
// This is required so that all entries in the array get initialized and are ordered correctly.
|
||||
ushort *lc = logClusters(&li);
|
||||
*lc = item ? lc[-1] : 0;
|
||||
if (layoutData->logClustersPtr) {
|
||||
ushort *lc = logClusters(&li);
|
||||
*lc = (lc != layoutData->logClustersPtr) ? lc[-1] : 0;
|
||||
}
|
||||
} else if (li.analysis.flags == QScriptAnalysis::Tab) {
|
||||
// set up at least the ascent/descent/leading of the script item for the tab
|
||||
fontEngine(li, &li.ascent, &li.descent, &li.leading);
|
||||
// see the comment above
|
||||
ushort *lc = logClusters(&li);
|
||||
*lc = item ? lc[-1] : 0;
|
||||
if (layoutData->logClustersPtr) {
|
||||
ushort *lc = logClusters(&li);
|
||||
*lc = (lc != layoutData->logClustersPtr) ? lc[-1] : 0;
|
||||
}
|
||||
} else {
|
||||
shapeText(item);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -464,8 +464,10 @@ static QNetworkInterface::InterfaceType probeIfType(int socket, int iftype, stru
|
|||
case IFM_ETHER:
|
||||
return QNetworkInterface::Ethernet;
|
||||
|
||||
#ifdef IFM_FDDI
|
||||
case IFM_FDDI:
|
||||
return QNetworkInterface::Fddi;
|
||||
#endif
|
||||
|
||||
case IFM_IEEE80211:
|
||||
return QNetworkInterface::Ieee80211;
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ namespace QPasswordDigestor {
|
|||
\a salt must always be 8 bytes long!
|
||||
|
||||
\note This function is provided for use with legacy applications and all
|
||||
new applications are recommended to use \l {pbkdf2} {PBKDF2}.
|
||||
new applications are recommended to use \l {deriveKeyPbkdf2} {PBKDF2}.
|
||||
|
||||
\sa deriveKeyPbkdf2, QCryptographicHash, QCryptographicHash::hashLength
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -99,13 +99,12 @@ static jfieldID m_selectionStartFieldID = 0;
|
|||
static jfieldID m_startOffsetFieldID = 0;
|
||||
static jfieldID m_textFieldID = 0;
|
||||
|
||||
Q_DECLARE_METATYPE(std::function<void()>)
|
||||
|
||||
static void runOnQtThread(const std::function<void()> &func)
|
||||
{
|
||||
const bool block = QGuiApplication::applicationState() >= Qt::ApplicationInactive;
|
||||
QMetaObject::invokeMethod(m_androidInputContext, "safeCall",
|
||||
block ? Qt::BlockingQueuedConnection : Qt::QueuedConnection, Q_ARG(std::function<void()>, func));
|
||||
AndroidDeadlockProtector protector;
|
||||
if (!protector.acquire())
|
||||
return;
|
||||
QMetaObject::invokeMethod(m_androidInputContext, "safeCall", Qt::BlockingQueuedConnection, Q_ARG(std::function<void()>, func));
|
||||
}
|
||||
|
||||
static jboolean beginBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
|
||||
|
|
@ -116,7 +115,7 @@ static jboolean beginBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
|
|||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||
qDebug("@@@ BEGINBATCH");
|
||||
#endif
|
||||
jboolean res;
|
||||
jboolean res = JNI_FALSE;
|
||||
runOnQtThread([&res]{res = m_androidInputContext->beginBatchEdit();});
|
||||
return res;
|
||||
}
|
||||
|
|
@ -130,7 +129,7 @@ static jboolean endBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
|
|||
qDebug("@@@ ENDBATCH");
|
||||
#endif
|
||||
|
||||
jboolean res;
|
||||
jboolean res = JNI_FALSE;
|
||||
runOnQtThread([&res]{res = m_androidInputContext->endBatchEdit();});
|
||||
return res;
|
||||
}
|
||||
|
|
@ -149,7 +148,7 @@ static jboolean commitText(JNIEnv *env, jobject /*thiz*/, jstring text, jint new
|
|||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||
qDebug() << "@@@ COMMIT" << str << newCursorPosition;
|
||||
#endif
|
||||
jboolean res;
|
||||
jboolean res = JNI_FALSE;
|
||||
runOnQtThread([&]{res = m_androidInputContext->commitText(str, newCursorPosition);});
|
||||
return res;
|
||||
}
|
||||
|
|
@ -162,7 +161,7 @@ static jboolean deleteSurroundingText(JNIEnv */*env*/, jobject /*thiz*/, jint le
|
|||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||
qDebug() << "@@@ DELETE" << leftLength << rightLength;
|
||||
#endif
|
||||
jboolean res;
|
||||
jboolean res = JNI_FALSE;
|
||||
runOnQtThread([&]{res = m_androidInputContext->deleteSurroundingText(leftLength, rightLength);});
|
||||
return res;
|
||||
}
|
||||
|
|
@ -175,7 +174,7 @@ static jboolean finishComposingText(JNIEnv */*env*/, jobject /*thiz*/)
|
|||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||
qDebug("@@@ FINISH");
|
||||
#endif
|
||||
jboolean res;
|
||||
jboolean res = JNI_FALSE;
|
||||
runOnQtThread([&]{res = m_androidInputContext->finishComposingText();});
|
||||
return res;
|
||||
}
|
||||
|
|
@ -185,7 +184,7 @@ static jint getCursorCapsMode(JNIEnv */*env*/, jobject /*thiz*/, jint reqModes)
|
|||
if (!m_androidInputContext)
|
||||
return 0;
|
||||
|
||||
jboolean res;
|
||||
jint res = 0;
|
||||
runOnQtThread([&]{res = m_androidInputContext->getCursorCapsMode(reqModes);});
|
||||
return res;
|
||||
}
|
||||
|
|
@ -270,7 +269,7 @@ static jboolean setComposingText(JNIEnv *env, jobject /*thiz*/, jstring text, ji
|
|||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||
qDebug() << "@@@ SET" << str << newCursorPosition;
|
||||
#endif
|
||||
jboolean res;
|
||||
jboolean res = JNI_FALSE;
|
||||
runOnQtThread([&]{res = m_androidInputContext->setComposingText(str, newCursorPosition);});
|
||||
return res;
|
||||
}
|
||||
|
|
@ -283,7 +282,7 @@ static jboolean setComposingRegion(JNIEnv */*env*/, jobject /*thiz*/, jint start
|
|||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||
qDebug() << "@@@ SETR" << start << end;
|
||||
#endif
|
||||
jboolean res;
|
||||
jboolean res = JNI_FALSE;
|
||||
runOnQtThread([&]{res = m_androidInputContext->setComposingRegion(start, end);});
|
||||
return res;
|
||||
}
|
||||
|
|
@ -297,7 +296,7 @@ static jboolean setSelection(JNIEnv */*env*/, jobject /*thiz*/, jint start, jint
|
|||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||
qDebug() << "@@@ SETSEL" << start << end;
|
||||
#endif
|
||||
jboolean res;
|
||||
jboolean res = JNI_FALSE;
|
||||
runOnQtThread([&]{res = m_androidInputContext->setSelection(start, end);});
|
||||
return res;
|
||||
|
||||
|
|
@ -311,7 +310,7 @@ static jboolean selectAll(JNIEnv */*env*/, jobject /*thiz*/)
|
|||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||
qDebug("@@@ SELALL");
|
||||
#endif
|
||||
jboolean res;
|
||||
jboolean res = JNI_FALSE;
|
||||
runOnQtThread([&]{res = m_androidInputContext->selectAll();});
|
||||
return res;
|
||||
}
|
||||
|
|
@ -324,7 +323,7 @@ static jboolean cut(JNIEnv */*env*/, jobject /*thiz*/)
|
|||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||
qDebug("@@@");
|
||||
#endif
|
||||
jboolean res;
|
||||
jboolean res = JNI_FALSE;
|
||||
runOnQtThread([&]{res = m_androidInputContext->cut();});
|
||||
return res;
|
||||
}
|
||||
|
|
@ -337,7 +336,7 @@ static jboolean copy(JNIEnv */*env*/, jobject /*thiz*/)
|
|||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||
qDebug("@@@");
|
||||
#endif
|
||||
jboolean res;
|
||||
jboolean res = JNI_FALSE;
|
||||
runOnQtThread([&]{res = m_androidInputContext->copy();});
|
||||
return res;
|
||||
}
|
||||
|
|
@ -350,7 +349,7 @@ static jboolean copyURL(JNIEnv */*env*/, jobject /*thiz*/)
|
|||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||
qDebug("@@@");
|
||||
#endif
|
||||
jboolean res;
|
||||
jboolean res = JNI_FALSE;
|
||||
runOnQtThread([&]{res = m_androidInputContext->copyURL();});
|
||||
return res;
|
||||
}
|
||||
|
|
@ -363,7 +362,7 @@ static jboolean paste(JNIEnv */*env*/, jobject /*thiz*/)
|
|||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||
qDebug("@@@ PASTE");
|
||||
#endif
|
||||
jboolean res;
|
||||
jboolean res = JNI_FALSE;
|
||||
runOnQtThread([&]{res = m_androidInputContext->paste();});
|
||||
return res;
|
||||
}
|
||||
|
|
@ -516,7 +515,6 @@ QAndroidInputContext::QAndroidInputContext()
|
|||
m_handleMode = Hidden;
|
||||
updateSelectionHandles();
|
||||
});
|
||||
qRegisterMetaType<std::function<void()>>();
|
||||
}
|
||||
|
||||
QAndroidInputContext::~QAndroidInputContext()
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ void QEglFSVivIntegration::platformInit()
|
|||
VivanteInit();
|
||||
mNativeDisplay = fbGetDisplay();
|
||||
#else
|
||||
mNativeDisplay = fbGetDisplayByIndex(framebufferIndex());
|
||||
mNativeDisplay = static_cast<EGLNativeDisplayType>(fbGetDisplayByIndex(framebufferIndex()));
|
||||
#endif
|
||||
|
||||
fbGetDisplayGeometry(mNativeDisplay, &width, &height);
|
||||
|
|
@ -88,7 +88,7 @@ EGLNativeWindowType QEglFSVivIntegration::createNativeWindow(QPlatformWindow *wi
|
|||
Q_UNUSED(window)
|
||||
Q_UNUSED(format)
|
||||
|
||||
EGLNativeWindowType eglWindow = fbCreateWindow(mNativeDisplay, 0, 0, size.width(), size.height());
|
||||
EGLNativeWindowType eglWindow = static_cast<EGLNativeWindowType>(fbCreateWindow(mNativeDisplay, 0, 0, size.width(), size.height()));
|
||||
return eglWindow;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ void QEglFSVivWaylandIntegration::platformInit()
|
|||
}
|
||||
|
||||
mWaylandDisplay = wl_display_create();
|
||||
mNativeDisplay = fbGetDisplay(mWaylandDisplay);
|
||||
mNativeDisplay = static_cast<EGLNativeDisplayType>(fbGetDisplay(mWaylandDisplay));
|
||||
fbGetDisplayGeometry(mNativeDisplay, &width, &height);
|
||||
mScreenSize.setHeight(height);
|
||||
mScreenSize.setWidth(width);
|
||||
|
|
@ -81,7 +81,7 @@ EGLNativeWindowType QEglFSVivWaylandIntegration::createNativeWindow(QPlatformWin
|
|||
Q_UNUSED(window)
|
||||
Q_UNUSED(format)
|
||||
|
||||
EGLNativeWindowType eglWindow = fbCreateWindow(mNativeDisplay, 0, 0, size.width(), size.height());
|
||||
EGLNativeWindowType eglWindow = static_cast<EGLNativeWindowType>(fbCreateWindow(mNativeDisplay, 0, 0, size.width(), size.height()));
|
||||
return eglWindow;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@
|
|||
# include "qwindowsdrag.h"
|
||||
#endif
|
||||
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <QtGui/qscreen.h>
|
||||
#include <QtGui/qtouchdevice.h>
|
||||
|
|
@ -201,6 +200,8 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
|
|||
return false;
|
||||
}
|
||||
|
||||
m_lastPointerType = pointerType;
|
||||
|
||||
// Handle non-client pen/touch as generic mouse events for compatibility with QDockWindow.
|
||||
if ((pointerType == QT_PT_TOUCH || pointerType == QT_PT_PEN) && (et & QtWindows::NonClientEventFlag)) {
|
||||
POINTER_INFO pointerInfo;
|
||||
|
|
@ -427,6 +428,15 @@ static bool isValidWheelReceiver(QWindow *candidate)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool isMenuWindow(QWindow *window)
|
||||
{
|
||||
if (window)
|
||||
if (QObject *fo = window->focusObject())
|
||||
if (fo->inherits("QMenu"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static QTouchDevice *createTouchDevice()
|
||||
{
|
||||
const int digitizers = GetSystemMetrics(SM_DIGITIZER);
|
||||
|
|
@ -455,6 +465,103 @@ QTouchDevice *QWindowsPointerHandler::ensureTouchDevice()
|
|||
return m_touchDevice;
|
||||
}
|
||||
|
||||
void QWindowsPointerHandler::handleCaptureRelease(QWindow *window,
|
||||
QWindow *currentWindowUnderPointer,
|
||||
HWND hwnd,
|
||||
QEvent::Type eventType,
|
||||
Qt::MouseButtons mouseButtons)
|
||||
{
|
||||
QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
|
||||
|
||||
// Qt expects the platform plugin to capture the mouse on any button press until release.
|
||||
if (!platformWindow->hasMouseCapture() && eventType == QEvent::MouseButtonPress) {
|
||||
|
||||
platformWindow->setMouseGrabEnabled(true);
|
||||
platformWindow->setFlag(QWindowsWindow::AutoMouseCapture);
|
||||
qCDebug(lcQpaEvents) << "Automatic mouse capture " << window;
|
||||
|
||||
// Implement "Click to focus" for native child windows (unless it is a native widget window).
|
||||
if (!window->isTopLevel() && !window->inherits("QWidgetWindow") && QGuiApplication::focusWindow() != window)
|
||||
window->requestActivate();
|
||||
|
||||
} else if (platformWindow->hasMouseCapture()
|
||||
&& platformWindow->testFlag(QWindowsWindow::AutoMouseCapture)
|
||||
&& eventType == QEvent::MouseButtonRelease
|
||||
&& !mouseButtons) {
|
||||
|
||||
platformWindow->setMouseGrabEnabled(false);
|
||||
qCDebug(lcQpaEvents) << "Releasing automatic mouse capture " << window;
|
||||
}
|
||||
|
||||
// Enter new window: track to generate leave event.
|
||||
// If there is an active capture, only track if the current window is capturing,
|
||||
// so we don't get extra leave when cursor leaves the application.
|
||||
if (window != m_currentWindow &&
|
||||
(!platformWindow->hasMouseCapture() || currentWindowUnderPointer == window)) {
|
||||
trackLeave(hwnd);
|
||||
m_currentWindow = window;
|
||||
}
|
||||
}
|
||||
|
||||
void QWindowsPointerHandler::handleEnterLeave(QWindow *window,
|
||||
QWindow *currentWindowUnderPointer,
|
||||
QPoint globalPos)
|
||||
{
|
||||
QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
|
||||
const bool hasCapture = platformWindow->hasMouseCapture();
|
||||
|
||||
// No enter or leave events are sent as long as there is an autocapturing window.
|
||||
if (!hasCapture || !platformWindow->testFlag(QWindowsWindow::AutoMouseCapture)) {
|
||||
|
||||
// Leave is needed if:
|
||||
// 1) There is no capture and we move from a window to another window.
|
||||
// Note: Leaving the application entirely is handled in translateMouseEvent(WM_MOUSELEAVE).
|
||||
// 2) There is capture and we move out of the capturing window.
|
||||
// 3) There is a new capture and we were over another window.
|
||||
if ((m_windowUnderPointer && m_windowUnderPointer != currentWindowUnderPointer
|
||||
&& (!hasCapture || window == m_windowUnderPointer))
|
||||
|| (hasCapture && m_previousCaptureWindow != window && m_windowUnderPointer
|
||||
&& m_windowUnderPointer != window)) {
|
||||
|
||||
qCDebug(lcQpaEvents) << "Leaving window " << m_windowUnderPointer;
|
||||
QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer);
|
||||
|
||||
if (hasCapture && currentWindowUnderPointer != window) {
|
||||
// Clear tracking if capturing and current window is not the capturing window
|
||||
// to avoid leave when mouse actually leaves the application.
|
||||
m_currentWindow = nullptr;
|
||||
// We are not officially in any window, but we need to set some cursor to clear
|
||||
// whatever cursor the left window had, so apply the cursor of the capture window.
|
||||
platformWindow->applyCursor();
|
||||
}
|
||||
}
|
||||
|
||||
// Enter is needed if:
|
||||
// 1) There is no capture and we move to a new window.
|
||||
// 2) There is capture and we move into the capturing window.
|
||||
// 3) The capture just ended and we are over non-capturing window.
|
||||
if ((currentWindowUnderPointer && m_windowUnderPointer != currentWindowUnderPointer
|
||||
&& (!hasCapture || currentWindowUnderPointer == window))
|
||||
|| (m_previousCaptureWindow && !hasCapture && currentWindowUnderPointer
|
||||
&& currentWindowUnderPointer != m_previousCaptureWindow)) {
|
||||
|
||||
QPoint wumLocalPos;
|
||||
if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(currentWindowUnderPointer)) {
|
||||
wumLocalPos = wumPlatformWindow->mapFromGlobal(globalPos);
|
||||
wumPlatformWindow->applyCursor();
|
||||
}
|
||||
qCDebug(lcQpaEvents) << "Entering window " << currentWindowUnderPointer;
|
||||
QWindowSystemInterface::handleEnterEvent(currentWindowUnderPointer, wumLocalPos, globalPos);
|
||||
}
|
||||
|
||||
// We need to track m_windowUnderPointer separately from m_currentWindow, as Windows
|
||||
// mouse tracking will not trigger WM_MOUSELEAVE for leaving window when mouse capture is set.
|
||||
m_windowUnderPointer = currentWindowUnderPointer;
|
||||
}
|
||||
|
||||
m_previousCaptureWindow = hasCapture ? window : nullptr;
|
||||
}
|
||||
|
||||
bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND hwnd,
|
||||
QtWindows::WindowsEventType et,
|
||||
MSG msg, PVOID vPointerInfo)
|
||||
|
|
@ -464,9 +571,7 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h
|
|||
const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos);
|
||||
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
|
||||
const Qt::MouseButtons mouseButtons = mouseButtonsFromPointerFlags(pointerInfo->pointerFlags);
|
||||
|
||||
QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
|
||||
QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
|
||||
|
||||
switch (msg.message) {
|
||||
case WM_NCPOINTERDOWN:
|
||||
|
|
@ -485,38 +590,17 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h
|
|||
keyModifiers, Qt::MouseEventNotSynthesized);
|
||||
return false; // To allow window dragging, etc.
|
||||
} else {
|
||||
if (eventType == QEvent::MouseButtonPress) {
|
||||
// Implement "Click to focus" for native child windows (unless it is a native widget window).
|
||||
if (!window->isTopLevel() && !window->inherits("QWidgetWindow") && QGuiApplication::focusWindow() != window)
|
||||
window->requestActivate();
|
||||
}
|
||||
if (currentWindowUnderPointer != m_windowUnderPointer) {
|
||||
if (m_windowUnderPointer && m_windowUnderPointer == m_currentWindow) {
|
||||
QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer);
|
||||
m_currentWindow = nullptr;
|
||||
}
|
||||
|
||||
if (currentWindowUnderPointer) {
|
||||
if (currentWindowUnderPointer != m_currentWindow) {
|
||||
QWindowSystemInterface::handleEnterEvent(currentWindowUnderPointer, localPos, globalPos);
|
||||
m_currentWindow = currentWindowUnderPointer;
|
||||
if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(currentWindowUnderPointer))
|
||||
wumPlatformWindow->applyCursor();
|
||||
trackLeave(hwnd);
|
||||
}
|
||||
} else {
|
||||
platformWindow->applyCursor();
|
||||
}
|
||||
m_windowUnderPointer = currentWindowUnderPointer;
|
||||
}
|
||||
handleCaptureRelease(window, currentWindowUnderPointer, hwnd, eventType, mouseButtons);
|
||||
handleEnterLeave(window, currentWindowUnderPointer, globalPos);
|
||||
|
||||
QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, button, eventType,
|
||||
keyModifiers, Qt::MouseEventNotSynthesized);
|
||||
|
||||
// The initial down click over the QSizeGrip area, which posts a resize WM_SYSCOMMAND
|
||||
// has go to through DefWindowProc() for resizing to work, so we return false here,
|
||||
// unless the mouse is captured, as it would mess with menu processing.
|
||||
return msg.message != WM_POINTERDOWN || GetCapture();
|
||||
// unless the click was on a menu, as it would mess with menu processing.
|
||||
return msg.message != WM_POINTERDOWN || isMenuWindow(window);
|
||||
}
|
||||
}
|
||||
case WM_POINTERHWHEEL:
|
||||
|
|
@ -641,6 +725,7 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
|
|||
// Only the primary pointer will generate mouse messages.
|
||||
enqueueTouchEvent(window, touchPoints, QWindowsKeyMapper::queryKeyboardModifiers());
|
||||
} else {
|
||||
flushTouchEvents(m_touchDevice);
|
||||
QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints,
|
||||
QWindowsKeyMapper::queryKeyboardModifiers());
|
||||
}
|
||||
|
|
@ -755,6 +840,16 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline bool isMouseEventSynthesizedFromPenOrTouch()
|
||||
{
|
||||
// For details, see
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/tablet/system-events-and-mouse-messages
|
||||
const LONG_PTR SIGNATURE_MASK = 0xFFFFFF00;
|
||||
const LONG_PTR MI_WP_SIGNATURE = 0xFF515700;
|
||||
|
||||
return ((::GetMessageExtraInfo() & SIGNATURE_MASK) == MI_WP_SIGNATURE);
|
||||
}
|
||||
|
||||
// Process old-style mouse messages here.
|
||||
bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result)
|
||||
{
|
||||
|
|
@ -763,8 +858,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW
|
|||
flushTabletEvents();
|
||||
|
||||
*result = 0;
|
||||
if (et != QtWindows::MouseWheelEvent && msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE)
|
||||
return false;
|
||||
|
||||
const QPoint eventPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
|
||||
QPoint localPos;
|
||||
|
|
@ -778,7 +871,26 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW
|
|||
}
|
||||
|
||||
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
|
||||
QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
|
||||
const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
|
||||
|
||||
// Handle "press and hold for right-clicking".
|
||||
// We have to synthesize it here as it only comes from Windows as a fake RMB.
|
||||
// MS docs say we could use bit 7 from extraInfo to distinguish pen from touch,
|
||||
// but on the Surface it is set for both. So we use the last pointer type.
|
||||
if (isMouseEventSynthesizedFromPenOrTouch()) {
|
||||
if ((msg.message == WM_RBUTTONDOWN || msg.message == WM_RBUTTONUP)
|
||||
&& (((m_lastPointerType == QT_PT_PEN)
|
||||
&& QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTabletEvents))
|
||||
|| ((m_lastPointerType == QT_PT_TOUCH)
|
||||
&& QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)))) {
|
||||
QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, Qt::RightButton,
|
||||
(msg.message == WM_RBUTTONDOWN) ? QEvent::MouseButtonPress
|
||||
: QEvent::MouseButtonRelease,
|
||||
keyModifiers, Qt::MouseEventSynthesizedBySystem);
|
||||
}
|
||||
// Messages synthesized from touch/pen are only used for flushing queues and press&hold.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (et == QtWindows::MouseWheelEvent) {
|
||||
|
||||
|
|
@ -799,50 +911,21 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW
|
|||
}
|
||||
|
||||
if (msg.message == WM_MOUSELEAVE) {
|
||||
|
||||
if (window == m_currentWindow) {
|
||||
QWindowSystemInterface::handleLeaveEvent(window);
|
||||
QWindow *leaveTarget = m_windowUnderPointer ? m_windowUnderPointer : m_currentWindow;
|
||||
qCDebug(lcQpaEvents) << "Leaving window " << leaveTarget;
|
||||
QWindowSystemInterface::handleLeaveEvent(leaveTarget);
|
||||
m_windowUnderPointer = nullptr;
|
||||
m_currentWindow = nullptr;
|
||||
platformWindow->applyCursor();
|
||||
}
|
||||
return false;
|
||||
|
||||
} else if (msg.message == WM_MOUSEMOVE) {
|
||||
|
||||
QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
|
||||
handleCaptureRelease(window, currentWindowUnderPointer, hwnd, QEvent::MouseMove, mouseButtons);
|
||||
handleEnterLeave(window, currentWindowUnderPointer, globalPos);
|
||||
}
|
||||
|
||||
// Windows sends a mouse move with no buttons pressed to signal "Enter"
|
||||
// when a window is shown over the cursor. Discard the event and only use
|
||||
// it for generating QEvent::Enter to be consistent with other platforms -
|
||||
// X11 and macOS.
|
||||
static QPoint lastMouseMovePos;
|
||||
const bool discardEvent = msg.wParam == 0 && (m_windowUnderPointer.isNull() || globalPos == lastMouseMovePos);
|
||||
lastMouseMovePos = globalPos;
|
||||
|
||||
QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
|
||||
|
||||
if (currentWindowUnderPointer != m_windowUnderPointer) {
|
||||
if (m_windowUnderPointer && m_windowUnderPointer == m_currentWindow) {
|
||||
QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer);
|
||||
m_currentWindow = nullptr;
|
||||
}
|
||||
|
||||
if (currentWindowUnderPointer) {
|
||||
if (currentWindowUnderPointer != m_currentWindow) {
|
||||
QWindowSystemInterface::handleEnterEvent(currentWindowUnderPointer, localPos, globalPos);
|
||||
m_currentWindow = currentWindowUnderPointer;
|
||||
if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(currentWindowUnderPointer))
|
||||
wumPlatformWindow->applyCursor();
|
||||
trackLeave(hwnd);
|
||||
}
|
||||
} else {
|
||||
platformWindow->applyCursor();
|
||||
}
|
||||
m_windowUnderPointer = currentWindowUnderPointer;
|
||||
}
|
||||
|
||||
const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
|
||||
|
||||
if (!discardEvent)
|
||||
QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, Qt::NoButton, QEvent::MouseMove,
|
||||
keyModifiers, Qt::MouseEventNotSynthesized);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include <QtCore/qpointer.h>
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -68,12 +69,16 @@ private:
|
|||
bool translateMouseTouchPadEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPointerInfo);
|
||||
bool translateTouchEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vTouchInfo, unsigned int count);
|
||||
bool translatePenEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPenInfo);
|
||||
void handleCaptureRelease(QWindow *window, QWindow *currentWindowUnderPointer, HWND hwnd, QEvent::Type eventType, Qt::MouseButtons mouseButtons);
|
||||
void handleEnterLeave(QWindow *window, QWindow *currentWindowUnderPointer, QPoint globalPos);
|
||||
|
||||
QTouchDevice *m_touchDevice = nullptr;
|
||||
QHash<int, QPointF> m_lastTouchPositions;
|
||||
QPointer<QWindow> m_windowUnderPointer;
|
||||
QPointer<QWindow> m_currentWindow;
|
||||
QWindow *m_previousCaptureWindow = nullptr;
|
||||
bool m_needsEnterOnPointerUpdate = false;
|
||||
DWORD m_lastPointerType = 0;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ void QXcbBasicConnection::initializeShm()
|
|||
logging->setEnabled(QtMsgType::QtWarningMsg, true);
|
||||
}
|
||||
|
||||
void QXcbBasicConnection::initializeXRandr()
|
||||
void QXcbBasicConnection::initializeXRender()
|
||||
{
|
||||
const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_render_id);
|
||||
if (!reply || !reply->present) {
|
||||
|
|
@ -303,7 +303,7 @@ void QXcbBasicConnection::initializeXRandr()
|
|||
return;
|
||||
}
|
||||
|
||||
m_hasXRandr = true;
|
||||
m_hasXRender = true;
|
||||
m_xrenderVersion.first = xrenderQuery->major_version;
|
||||
m_xrenderVersion.second = xrenderQuery->minor_version;
|
||||
}
|
||||
|
|
@ -337,7 +337,7 @@ void QXcbBasicConnection::initializeXFixes()
|
|||
m_xfixesFirstEvent = reply->first_event;
|
||||
}
|
||||
|
||||
void QXcbBasicConnection::initializeXRender()
|
||||
void QXcbBasicConnection::initializeXRandr()
|
||||
{
|
||||
const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_randr_id);
|
||||
if (!reply || !reply->present)
|
||||
|
|
@ -352,7 +352,7 @@ void QXcbBasicConnection::initializeXRender()
|
|||
return;
|
||||
}
|
||||
|
||||
m_hasXRender = true;
|
||||
m_hasXRandr = true;
|
||||
m_xrandrFirstEvent = reply->first_event;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,4 +112,8 @@ qtConfig(xkb) {
|
|||
|
||||
qtConfig(dlopen): QMAKE_USE += libdl
|
||||
|
||||
# qxcbkeyboard.cpp's KeyTbl has more than 256 levels of expansion and older
|
||||
# Clang uses that as a limit (it's 1024 in current versions).
|
||||
clang:!intel_icc: QMAKE_CXXFLAGS += -ftemplate-depth=1024
|
||||
|
||||
load(qt_module)
|
||||
|
|
|
|||
|
|
@ -31,8 +31,16 @@ depends += qtcore qtdoc qtwidgets qtgui qmake qtquick
|
|||
|
||||
headerdirs += ..
|
||||
|
||||
headers += ../../corelib/kernel/qtestsupport_core.h \
|
||||
../../gui/kernel/qtestsupport_gui.h \
|
||||
../../widgets/kernel/qtestsupport_widgets.h
|
||||
|
||||
sourcedirs += ..
|
||||
|
||||
sources += ../../corelib/kernel/qtestsupport_core.cpp \
|
||||
../../gui/kernel/qtestsupport_gui.cpp \
|
||||
../../widgets/kernel/qtestsupport_widgets.cpp
|
||||
|
||||
exampledirs += ../../../examples/qtestlib \
|
||||
../ \
|
||||
snippets
|
||||
|
|
|
|||
|
|
@ -2419,7 +2419,7 @@ bool QTest::currentTestFailed()
|
|||
Sleeps for \a ms milliseconds, blocking execution of the
|
||||
test. qSleep() will not do any event processing and leave your test
|
||||
unresponsive. Network communication might time out while
|
||||
sleeping. Use \l qWait() to do non-blocking sleeping.
|
||||
sleeping. Use \l {QTest::qWait()} to do non-blocking sleeping.
|
||||
|
||||
\a ms must be greater than 0.
|
||||
|
||||
|
|
@ -2430,7 +2430,7 @@ bool QTest::currentTestFailed()
|
|||
Example:
|
||||
\snippet code/src_qtestlib_qtestcase.cpp 23
|
||||
|
||||
\sa qWait()
|
||||
\sa {QTest::qWait()}
|
||||
*/
|
||||
void QTest::qSleep(int ms)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -994,6 +994,22 @@
|
|||
\sa QTest::toHexRepresentation()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn char *QTest::toString(const QCborError &c)
|
||||
\overload
|
||||
\since 5.12
|
||||
|
||||
Returns a textual representation of the given CBOR error \a c.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <class... Types> char *QTest::toString(const std::tuple<Types...> &tuple)
|
||||
\overload
|
||||
\since 5.12
|
||||
|
||||
Returns a textual representation of the given \a tuple.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn char *QTest::toString(const QTime &time)
|
||||
\overload
|
||||
|
|
@ -1112,6 +1128,12 @@
|
|||
Returns a textual representation of size policy \a sp.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename Tuple, int... I> char *QTest::toString(const Tuple &tuple, QtPrivate::IndexesList<I...> )
|
||||
\internal
|
||||
\since 5.12
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QTouchDevice *QTest::createTouchDevice(QTouchDevice::DeviceType devType = QTouchDevice::TouchScreen)
|
||||
\since 5.8
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@
|
|||
|
||||
Adds a \a msecs milliseconds delay.
|
||||
|
||||
\sa QTest::qWait()
|
||||
\sa {QTest::qWait()}
|
||||
*/
|
||||
|
||||
/*! \fn void QTestEventList::simulate(QWidget *w)
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ static const char docTypeHeader[] =
|
|||
|
||||
#define PROGRAMNAME "qdbuscpp2xml"
|
||||
#define PROGRAMVERSION "0.2"
|
||||
#define PROGRAMCOPYRIGHT "Copyright (C) 2018 The Qt Company Ltd."
|
||||
#define PROGRAMCOPYRIGHT "Copyright (C) 2019 The Qt Company Ltd."
|
||||
|
||||
static QString outputFile;
|
||||
static int flags;
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
|
||||
#define PROGRAMNAME "qdbusxml2cpp"
|
||||
#define PROGRAMVERSION "0.8"
|
||||
#define PROGRAMCOPYRIGHT "Copyright (C) 2018 The Qt Company Ltd."
|
||||
#define PROGRAMCOPYRIGHT "Copyright (C) 2019 The Qt Company Ltd."
|
||||
|
||||
#define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply"
|
||||
|
||||
|
|
|
|||
|
|
@ -1890,7 +1890,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title)
|
|||
"<p>Qt and the Qt logo are trademarks of The Qt Company Ltd.</p>"
|
||||
"<p>Qt is The Qt Company Ltd product developed as an open source "
|
||||
"project. See <a href=\"http://%3/\">%3</a> for more information.</p>"
|
||||
).arg(QStringLiteral("2018"),
|
||||
).arg(QStringLiteral("2019"),
|
||||
QStringLiteral("qt.io/licensing"),
|
||||
QStringLiteral("qt.io"));
|
||||
QMessageBox *msgBox = new QMessageBox(parent);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ exampledirs += ../../../examples/widgets \
|
|||
|
||||
excludedirs += snippets
|
||||
|
||||
# Included in qttestlib.qdocconf instead
|
||||
excludefiles += ../kernel/qtestsupport_widgets.cpp
|
||||
|
||||
imagedirs += images \
|
||||
../../../doc/src/images \
|
||||
../../../examples/widgets/doc/images \
|
||||
|
|
|
|||
|
|
@ -982,18 +982,9 @@ void QListView::paintEvent(QPaintEvent *e)
|
|||
? qMax(viewport()->size().width(), d->contentsSize().width()) - 2 * d->spacing()
|
||||
: qMax(viewport()->size().height(), d->contentsSize().height()) - 2 * d->spacing();
|
||||
|
||||
const int rowCount = d->commonListView->rowCount();
|
||||
QVector<QModelIndex>::const_iterator end = toBeRendered.constEnd();
|
||||
for (QVector<QModelIndex>::const_iterator it = toBeRendered.constBegin(); it != end; ++it) {
|
||||
Q_ASSERT((*it).isValid());
|
||||
if (rowCount == 1)
|
||||
option.viewItemPosition = QStyleOptionViewItem::OnlyOne;
|
||||
else if ((*it).row() == 0)
|
||||
option.viewItemPosition = QStyleOptionViewItem::Beginning;
|
||||
else if ((*it).row() == rowCount - 1)
|
||||
option.viewItemPosition = QStyleOptionViewItem::End;
|
||||
else
|
||||
option.viewItemPosition = QStyleOptionViewItem::Middle;
|
||||
option.rect = visualRect(*it);
|
||||
|
||||
if (flow() == TopToBottom)
|
||||
|
|
|
|||
|
|
@ -46,15 +46,14 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*! \fn bool qWaitForWindowActive(QWidget *widget, int timeout)
|
||||
\relates QTest
|
||||
/*!
|
||||
\since 5.0
|
||||
|
||||
Waits for \a timeout milliseconds or until the \a widget's window is active.
|
||||
|
||||
Returns \c true if \c widget's window is active within \a timeout milliseconds, otherwise returns \c false.
|
||||
|
||||
\sa QTest::qWaitForWindowExposed(), QWidget::isActiveWindow()
|
||||
\sa qWaitForWindowExposed(), QWidget::isActiveWindow()
|
||||
*/
|
||||
Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowActive(QWidget *widget, int timeout)
|
||||
{
|
||||
|
|
@ -63,8 +62,7 @@ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowActive(QWidget *wid
|
|||
return false;
|
||||
}
|
||||
|
||||
/*! \fn bool qWaitForWindowExposed(QWidget *widget, int timeout)
|
||||
\relates QTest
|
||||
/*!
|
||||
\since 5.0
|
||||
|
||||
Waits for \a timeout milliseconds or until the \a widget's window is exposed.
|
||||
|
|
@ -80,7 +78,7 @@ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowActive(QWidget *wid
|
|||
A specific configuration where this happens is when using QGLWidget as a viewport widget on macOS:
|
||||
The viewport widget gets the expose event, not the parent widget.
|
||||
|
||||
\sa QTest::qWaitForWindowActive()
|
||||
\sa qWaitForWindowActive()
|
||||
*/
|
||||
Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowExposed(QWidget *widget, int timeout)
|
||||
{
|
||||
|
|
@ -89,11 +87,12 @@ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowExposed(QWidget *wi
|
|||
return false;
|
||||
}
|
||||
|
||||
/*! \fn bool qWaitForWindowShown(QWidget *widget, int timeout)
|
||||
\relates QTest
|
||||
/*! \fn bool QTest::qWaitForWindowShown(QWidget *widget, int timeout)
|
||||
\since 5.0
|
||||
\deprecated
|
||||
|
||||
Use qWaitForWindowExposed() instead.
|
||||
|
||||
Waits for \a timeout milliseconds or until the \a widget's window is exposed.
|
||||
Returns \c true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns \c false.
|
||||
|
||||
|
|
@ -107,7 +106,7 @@ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowExposed(QWidget *wi
|
|||
QTest::qWaitForWindowShown(&widget);
|
||||
\endcode
|
||||
|
||||
\sa QTest::qWaitForWindowActive(), QTest::qWaitForWindowExposed()
|
||||
\sa qWaitForWindowActive(), qWaitForWindowExposed()
|
||||
*/
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -216,7 +216,6 @@ void QTipLabel::reuseTip(const QString &text, int msecDisplayTime, const QPoint
|
|||
}
|
||||
#endif
|
||||
|
||||
setWordWrap(true);
|
||||
setText(text);
|
||||
updateSize(pos);
|
||||
restartExpireTimer(msecDisplayTime);
|
||||
|
|
@ -235,20 +234,17 @@ void QTipLabel::updateSize(const QPoint &pos)
|
|||
// Make it look good with the default ToolTip font on Mac, which has a small descent.
|
||||
if (fm.descent() == 2 && fm.ascent() >= 11)
|
||||
++extra.rheight();
|
||||
setWordWrap(Qt::mightBeRichText(text()));
|
||||
QSize sh = sizeHint();
|
||||
if (wordWrap()) {
|
||||
// ### When the above WinRT code is fixed, windowhandle should be used to find the screen.
|
||||
QScreen *screen = QGuiApplication::screenAt(pos);
|
||||
if (!screen)
|
||||
screen = QGuiApplication::primaryScreen();
|
||||
if (screen) {
|
||||
const qreal screenWidth = screen->geometry().width();
|
||||
if (sh.width() > screenWidth) {
|
||||
// Try to use widely accepted 75chars max length or 80% of the screen width else.
|
||||
// See https://en.wikipedia.org/wiki/Line_length
|
||||
sh.setWidth(qMin(fm.averageCharWidth() * 75, static_cast<int>(screenWidth * .8)));
|
||||
sh.setHeight(heightForWidth(sh.width()));
|
||||
}
|
||||
// ### When the above WinRT code is fixed, windowhandle should be used to find the screen.
|
||||
QScreen *screen = QGuiApplication::screenAt(pos);
|
||||
if (!screen)
|
||||
screen = QGuiApplication::primaryScreen();
|
||||
if (screen) {
|
||||
const qreal screenWidth = screen->geometry().width();
|
||||
if (!wordWrap() && sh.width() > screenWidth) {
|
||||
setWordWrap(true);
|
||||
sh = sizeHint();
|
||||
}
|
||||
}
|
||||
resize(sh + extra);
|
||||
|
|
|
|||
|
|
@ -4517,7 +4517,7 @@ void QWidget::setForegroundRole(QPalette::ColorRole role)
|
|||
the "color", "background-color", "selection-color",
|
||||
"selection-background-color" and "alternate-background-color".
|
||||
|
||||
\sa QApplication::palette(), QWidget::font(), \l {Qt Style Sheets}
|
||||
\sa QApplication::palette(), QWidget::font(), {Qt Style Sheets}
|
||||
*/
|
||||
const QPalette &QWidget::palette() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -899,10 +899,10 @@ void QWidgetWindow::handleDragMoveEvent(QDragMoveEvent *event)
|
|||
const QPoint mapped = widget->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
|
||||
QDragMoveEvent translated(mapped, event->possibleActions(), event->mimeData(),
|
||||
event->mouseButtons(), event->keyboardModifiers());
|
||||
translated.setDropAction(event->dropAction());
|
||||
translated.setAccepted(event->isAccepted());
|
||||
|
||||
if (widget == m_dragTarget) { // Target widget unchanged: Send DragMove
|
||||
translated.setDropAction(event->dropAction());
|
||||
translated.setAccepted(event->isAccepted());
|
||||
QGuiApplication::forwardEvent(m_dragTarget, &translated, event);
|
||||
} else {
|
||||
if (m_dragTarget) { // Send DragLeave to previous
|
||||
|
|
@ -912,6 +912,9 @@ void QWidgetWindow::handleDragMoveEvent(QDragMoveEvent *event)
|
|||
}
|
||||
// Send DragEnter to new widget.
|
||||
handleDragEnterEvent(static_cast<QDragEnterEvent*>(event), widget);
|
||||
// Handling 'DragEnter' should suffice for the application.
|
||||
translated.setDropAction(event->dropAction());
|
||||
translated.setAccepted(event->isAccepted());
|
||||
// The drag enter event is always immediately followed by a drag move event,
|
||||
// see QDragEnterEvent documentation.
|
||||
QGuiApplication::forwardEvent(m_dragTarget, &translated, event);
|
||||
|
|
|
|||
|
|
@ -1681,6 +1681,7 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
|
|||
|
||||
/*!
|
||||
\fn void QLineEdit::inputRejected()
|
||||
\since 5.12
|
||||
|
||||
This signal is emitted when the user presses a key that is not
|
||||
considered to be acceptable input. For example, if a key press
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>Created by Qt/QMake</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>${ASSETCATALOG_COMPILER_APPICON_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${QMAKE_SHORT_VERSION}</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>${QMAKE_PKGINFO_TYPEINFO}</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${QMAKE_FULL_VERSION}</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>${IPHONEOS_DEPLOYMENT_TARGET}</string>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>Enables use of assets file engine</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -3,6 +3,7 @@ TARGET = tst_qdir
|
|||
QT = core core-private testlib
|
||||
SOURCES = tst_qdir.cpp
|
||||
RESOURCES += qdir.qrc
|
||||
ios: QMAKE_INFO_PLIST = Info.plist
|
||||
|
||||
TESTDATA += testdir testData searchdir resources entrylist types tst_qdir.cpp
|
||||
|
||||
|
|
|
|||
|
|
@ -62,12 +62,7 @@
|
|||
#endif
|
||||
|
||||
#ifdef QT_BUILD_INTERNAL
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
extern Q_AUTOTEST_EXPORT QString
|
||||
qt_normalizePathSegments(const QString &path, bool allowUncPaths, bool *ok = nullptr);
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "private/qdir_p.h"
|
||||
#endif
|
||||
|
||||
static QByteArray msgDoesNotExist(const QString &name)
|
||||
|
|
@ -1376,7 +1371,7 @@ void tst_QDir::normalizePathSegments()
|
|||
QFETCH(QString, path);
|
||||
QFETCH(UncHandling, uncHandling);
|
||||
QFETCH(QString, expected);
|
||||
QString cleaned = qt_normalizePathSegments(path, uncHandling == HandleUnc);
|
||||
QString cleaned = qt_normalizePathSegments(path, uncHandling == HandleUnc ? QDirPrivate::AllowUncPaths : QDirPrivate::DefaultNormalization);
|
||||
QCOMPARE(cleaned, expected);
|
||||
if (path == expected)
|
||||
QVERIFY2(path.isSharedWith(cleaned), "Strings are same but data is not shared");
|
||||
|
|
@ -1528,6 +1523,11 @@ void tst_QDir::filePath_data()
|
|||
QTest::newRow("rel-rel") << "relative" << "path" << "relative/path";
|
||||
QTest::newRow("empty-empty") << "" << "" << ".";
|
||||
QTest::newRow("resource") << ":/prefix" << "foo.bar" << ":/prefix/foo.bar";
|
||||
#ifdef Q_OS_IOS
|
||||
QTest::newRow("assets-rel") << "assets-library:/" << "foo/bar.baz" << "assets-library:/foo/bar.baz";
|
||||
QTest::newRow("assets-abs") << "assets-library:/" << "/foo/bar.baz" << "/foo/bar.baz";
|
||||
QTest::newRow("abs-assets") << "/some/path" << "assets-library:/foo/bar.baz" << "assets-library:/foo/bar.baz";
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
QTest::newRow("abs-LTUNC") << "Q:/path" << "\\/leaning\\tooth/pick" << "\\/leaning\\tooth/pick";
|
||||
QTest::newRow("LTUNC-slash") << "\\/leaning\\tooth/pick" << "/path" << "//leaning/tooth/path";
|
||||
|
|
|
|||
|
|
@ -182,6 +182,8 @@ private slots:
|
|||
void matches();
|
||||
void ipv6_zoneId_data();
|
||||
void ipv6_zoneId();
|
||||
void normalizeRemotePaths_data();
|
||||
void normalizeRemotePaths();
|
||||
|
||||
private:
|
||||
void testThreadingHelper();
|
||||
|
|
@ -323,7 +325,7 @@ void tst_QUrl::comparison()
|
|||
|
||||
QUrl url3bis = QUrl::fromEncoded("example://a/b/c/%7Bfoo%7D/");
|
||||
QUrl url3bisNoSlash = QUrl::fromEncoded("example://a/b/c/%7Bfoo%7D");
|
||||
QUrl url4bis = QUrl::fromEncoded("example://a/.//b/../b/c//%7Bfoo%7D/");
|
||||
QUrl url4bis = QUrl::fromEncoded("example://a/./b/../b/c/%7Bfoo%7D/");
|
||||
QCOMPARE(url4bis.adjusted(QUrl::NormalizePathSegments), url3bis);
|
||||
QCOMPARE(url4bis.adjusted(QUrl::NormalizePathSegments | QUrl::StripTrailingSlash), url3bisNoSlash);
|
||||
QVERIFY(url3bis.matches(url4bis, QUrl::NormalizePathSegments));
|
||||
|
|
@ -335,7 +337,7 @@ void tst_QUrl::comparison()
|
|||
QCOMPARE(url4EncodedDots.path(QUrl::FullyDecoded), QString("/.//b/..//b/c/"));
|
||||
QCOMPARE(QString::fromLatin1(url4EncodedDots.toEncoded()), QString::fromLatin1("example://a/.//b/..%2F/b/c/"));
|
||||
QCOMPARE(url4EncodedDots.toString(), QString("example://a/.//b/..%2F/b/c/"));
|
||||
QCOMPARE(url4EncodedDots.adjusted(QUrl::NormalizePathSegments).toString(), QString("example://a/b/..%2F/b/c/"));
|
||||
QCOMPARE(url4EncodedDots.adjusted(QUrl::NormalizePathSegments).toString(), QString("example://a//b/..%2F/b/c/"));
|
||||
|
||||
// 6.2.2.1 Make sure hexdecimal characters in percent encoding are
|
||||
// treated case-insensitively
|
||||
|
|
@ -4201,6 +4203,36 @@ void tst_QUrl::ipv6_zoneId()
|
|||
QCOMPARE(url.toString(QUrl::FullyEncoded), "x://[" + encodedHost + "]");
|
||||
}
|
||||
|
||||
void tst_QUrl::normalizeRemotePaths_data()
|
||||
{
|
||||
QTest::addColumn<QUrl>("url");
|
||||
QTest::addColumn<QString>("expected");
|
||||
|
||||
QTest::newRow("dotdot-slashslash") << QUrl("http://qt-project.org/some/long/..//path") << "http://qt-project.org/some//path";
|
||||
QTest::newRow("slashslash-dotdot") << QUrl("http://qt-project.org/some//../path") << "http://qt-project.org/some/path";
|
||||
QTest::newRow("slashslash-dotdot2") << QUrl("http://qt-project.org/some//path/../") << "http://qt-project.org/some//";
|
||||
QTest::newRow("dot-slash") << QUrl("http://qt-project.org/some/./path") << "http://qt-project.org/some/path";
|
||||
QTest::newRow("slashslash-dot-slashslash") << QUrl("http://qt-project.org/some//.//path") << "http://qt-project.org/some///path";
|
||||
QTest::newRow("dot-slashslash") << QUrl("http://qt-project.org/some/.//path") << "http://qt-project.org/some//path";
|
||||
QTest::newRow("multiple-slashes") << QUrl("http://qt-project.org/some//path") << "http://qt-project.org/some//path";
|
||||
QTest::newRow("multiple-slashes4") << QUrl("http://qt-project.org/some////path") << "http://qt-project.org/some////path";
|
||||
QTest::newRow("slashes-at-end") << QUrl("http://qt-project.org/some//") << "http://qt-project.org/some//";
|
||||
QTest::newRow("dot-dotdot") << QUrl("http://qt-project.org/path/./../") << "http://qt-project.org/";
|
||||
QTest::newRow("slash-dot-slash-dot-slash") << QUrl("http://qt-project.org/path//.//.//") << "http://qt-project.org/path////";
|
||||
QTest::newRow("dotdot") << QUrl("http://qt-project.org/../") << "http://qt-project.org/";
|
||||
QTest::newRow("dotdot-dotdot") << QUrl("http://qt-project.org/path/../../") << "http://qt-project.org/";
|
||||
QTest::newRow("dot-dotdot-tail") << QUrl("http://qt-project.org/stem/path/./../tail") << "http://qt-project.org/stem/tail";
|
||||
QTest::newRow("slash-dotdot-slash-tail") << QUrl("http://qt-project.org/stem/path//..//tail") << "http://qt-project.org/stem/path//tail";
|
||||
}
|
||||
|
||||
void tst_QUrl::normalizeRemotePaths()
|
||||
{
|
||||
QFETCH(QUrl, url);
|
||||
QFETCH(QString, expected);
|
||||
|
||||
QCOMPARE(url.adjusted(QUrl::NormalizePathSegments).toString(), expected);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QUrl)
|
||||
|
||||
#include "tst_qurl.moc"
|
||||
|
|
|
|||
|
|
@ -727,6 +727,16 @@ void tst_QItemDelegate::dateTimeEditor_data()
|
|||
<< QDate(2006, 10, 31);
|
||||
}
|
||||
|
||||
static QDateTimeEdit *findDateTimeEdit(const QWidget *widget)
|
||||
{
|
||||
const auto dateTimeEditors = widget->findChildren<QDateTimeEdit *>();
|
||||
for (auto dateTimeEditor : dateTimeEditors) {
|
||||
if (qstrcmp(dateTimeEditor->metaObject()->className(), "QDateTimeEdit") == 0)
|
||||
return dateTimeEditor;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void tst_QItemDelegate::dateTimeEditor()
|
||||
{
|
||||
QFETCH(QTime, time);
|
||||
|
|
@ -742,17 +752,24 @@ void tst_QItemDelegate::dateTimeEditor()
|
|||
item3->setData(Qt::DisplayRole, QDateTime(date, time));
|
||||
|
||||
QTableWidget widget(1, 3);
|
||||
widget.setWindowTitle(QLatin1String(QTest::currentTestFunction())
|
||||
+ QLatin1String("::")
|
||||
+ QLatin1String(QTest::currentDataTag()));
|
||||
widget.setItem(0, 0, item1);
|
||||
widget.setItem(0, 1, item2);
|
||||
widget.setItem(0, 2, item3);
|
||||
widget.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
QApplication::setActiveWindow(&widget);
|
||||
|
||||
widget.editItem(item1);
|
||||
|
||||
QTestEventLoop::instance().enterLoop(1);
|
||||
|
||||
QTimeEdit *timeEditor = widget.viewport()->findChild<QTimeEdit *>();
|
||||
QVERIFY(timeEditor);
|
||||
|
||||
QTimeEdit *timeEditor = nullptr;
|
||||
auto viewport = widget.viewport();
|
||||
QTRY_VERIFY( (timeEditor = viewport->findChild<QTimeEdit *>()) );
|
||||
QCOMPARE(timeEditor->time(), time);
|
||||
// The data must actually be different in order for the model
|
||||
// to be updated.
|
||||
|
|
@ -763,8 +780,8 @@ void tst_QItemDelegate::dateTimeEditor()
|
|||
widget.setFocus();
|
||||
widget.editItem(item2);
|
||||
|
||||
QTRY_VERIFY(widget.viewport()->findChild<QDateEdit *>());
|
||||
QDateEdit *dateEditor = widget.viewport()->findChild<QDateEdit *>();
|
||||
QDateEdit *dateEditor = nullptr;
|
||||
QTRY_VERIFY( (dateEditor = viewport->findChild<QDateEdit *>()) );
|
||||
QCOMPARE(dateEditor->date(), date);
|
||||
dateEditor->setDate(date.addDays(60));
|
||||
|
||||
|
|
@ -774,12 +791,8 @@ void tst_QItemDelegate::dateTimeEditor()
|
|||
|
||||
QTestEventLoop::instance().enterLoop(1);
|
||||
|
||||
QList<QDateTimeEdit *> dateTimeEditors = widget.findChildren<QDateTimeEdit *>();
|
||||
QDateTimeEdit *dateTimeEditor = 0;
|
||||
foreach(dateTimeEditor, dateTimeEditors)
|
||||
if (dateTimeEditor->metaObject()->className() == QLatin1String("QDateTimeEdit"))
|
||||
break;
|
||||
QVERIFY(dateTimeEditor);
|
||||
QDateTimeEdit *dateTimeEditor = nullptr;
|
||||
QTRY_VERIFY( (dateTimeEditor = findDateTimeEdit(viewport)) );
|
||||
QCOMPARE(dateTimeEditor->date(), date);
|
||||
QCOMPARE(dateTimeEditor->time(), time);
|
||||
dateTimeEditor->setTime(time.addSecs(600));
|
||||
|
|
|
|||
|
|
@ -470,6 +470,10 @@ static const char *expectedLogC[] = {
|
|||
"Event at 11,241 accepted",
|
||||
"acceptingDropsWidget2::dropEvent at 1,51 action=1 MIME_DATA_ADDRESS 'testmimetext'",
|
||||
"Event at 11,261 accepted",
|
||||
"acceptingDropsWidget3::dragEnterEvent at 1,21 action=1 MIME_DATA_ADDRESS 'testmimetext'",
|
||||
"Event at 11,281 accepted",
|
||||
"acceptingDropsWidget3::dragLeaveEvent QDragLeaveEvent",
|
||||
"Event at 11,301 ignored",
|
||||
"acceptingDropsWidget1::dragEnterEvent at 10,10 action=1 MIME_DATA_ADDRESS 'testmimetext'",
|
||||
"Event at 0,0 accepted",
|
||||
"acceptingDropsWidget1::dragMoveEvent at 11,11 action=1 MIME_DATA_ADDRESS 'testmimetext'",
|
||||
|
|
@ -482,8 +486,9 @@ static const char *expectedLogC[] = {
|
|||
class DnDEventLoggerWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
DnDEventLoggerWidget(QStringList *log, QWidget *w = 0) : QWidget(w), m_log(log) {}
|
||||
|
||||
DnDEventLoggerWidget(QStringList *log, QWidget *w = nullptr, bool ignoreDragMove = false)
|
||||
: QWidget(w), m_log(log), m_ignoreDragMove(ignoreDragMove)
|
||||
{}
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent *);
|
||||
void dragMoveEvent(QDragMoveEvent *);
|
||||
|
|
@ -493,6 +498,7 @@ protected:
|
|||
private:
|
||||
void formatDropEvent(const char *function, const QDropEvent *e, QTextStream &str) const;
|
||||
QStringList *m_log;
|
||||
bool m_ignoreDragMove;
|
||||
};
|
||||
|
||||
void DnDEventLoggerWidget::formatDropEvent(const char *function, const QDropEvent *e, QTextStream &str) const
|
||||
|
|
@ -513,6 +519,8 @@ void DnDEventLoggerWidget::dragEnterEvent(QDragEnterEvent *e)
|
|||
|
||||
void DnDEventLoggerWidget::dragMoveEvent(QDragMoveEvent *e)
|
||||
{
|
||||
if (m_ignoreDragMove)
|
||||
return;
|
||||
e->accept();
|
||||
QString message;
|
||||
QTextStream str(&message);
|
||||
|
|
@ -580,7 +588,17 @@ void tst_QWidget_window::tst_dnd()
|
|||
dropsRefusingWidget2->resize(160, 60);
|
||||
dropsRefusingWidget2->move(10, 10);
|
||||
|
||||
QWidget *dropsAcceptingWidget3 = new DnDEventLoggerWidget(&log, &dndTestWidget, true);
|
||||
dropsAcceptingWidget3->setAcceptDrops(true);
|
||||
dropsAcceptingWidget3->setObjectName(QLatin1String("acceptingDropsWidget3"));
|
||||
// 260 + 40 = 300 = widget size, must not be more than that.
|
||||
// otherwise it will break WinRT because there the tlw is maximized every time
|
||||
// and this window will receive one more event
|
||||
dropsAcceptingWidget3->resize(180, 40);
|
||||
dropsAcceptingWidget3->move(10, 260);
|
||||
|
||||
dndTestWidget.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dndTestWidget));
|
||||
qApp->setActiveWindow(&dndTestWidget);
|
||||
QVERIFY(QTest::qWaitForWindowActive(&dndTestWidget));
|
||||
|
||||
|
|
@ -595,16 +613,17 @@ void tst_QWidget_window::tst_dnd()
|
|||
log.push_back(msgEventAccepted(e));
|
||||
while (true) {
|
||||
position.ry() += 20;
|
||||
if (position.y() >= 250) {
|
||||
if (position.y() >= 250 && position.y() < 270) {
|
||||
QDropEvent e(position, Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier);
|
||||
qApp->sendEvent(window, &e);
|
||||
log.push_back(msgEventAccepted(e));
|
||||
break;
|
||||
} else {
|
||||
QDragMoveEvent e(position, Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier);
|
||||
qApp->sendEvent(window, &e);
|
||||
log.push_back(msgEventAccepted(e));
|
||||
}
|
||||
if (position.y() > 290)
|
||||
break;
|
||||
}
|
||||
|
||||
window = nativeWidget->windowHandle();
|
||||
|
|
@ -628,6 +647,15 @@ void tst_QWidget_window::tst_dnd()
|
|||
for (int i= 0; i < expectedLogSize; ++i)
|
||||
expectedLog.push_back(QString::fromLatin1(expectedLogC[i]).replace(mimeDataAddressPlaceHolder, mimeDataAddress));
|
||||
|
||||
if (log.size() != expectedLog.size()) {
|
||||
for (int i = 0; i < log.size() && i < expectedLog.size(); ++i)
|
||||
QCOMPARE(log.at(i), expectedLog.at(i));
|
||||
const int iMin = std::min(log.size(), expectedLog.size());
|
||||
for (int i = iMin; i < log.size(); ++i)
|
||||
qDebug() << "log[" << i << "]:" << log.at(i);
|
||||
for (int i = iMin; i < expectedLog.size(); ++i)
|
||||
qDebug() << "exp[" << i << "]:" << log.at(i);
|
||||
}
|
||||
QCOMPARE(log, expectedLog);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue