Merge remote-tracking branch 'origin/5.14' into 5.15
Change-Id: Ie69d40d2efc5559b31e28ba71f88e3cda741e051bb10
commit
dc4ecf0641
|
|
@ -0,0 +1,109 @@
|
|||
Qt 5.12.5 is a bug-fix release. It maintains both forward and backward
|
||||
compatibility (source and binary) with Qt 5.12.0 through 5.12.4.
|
||||
|
||||
For more details, refer to the online documentation included in this
|
||||
distribution. The documentation is also available online:
|
||||
|
||||
https://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.
|
||||
|
||||
****************************************************************************
|
||||
* QtCore *
|
||||
****************************************************************************
|
||||
|
||||
- QBitArray:
|
||||
* Fixed two bugs that caused QBitArrays created using fromBits() not to
|
||||
compare equal to the equivalent QBitArray created using other methods
|
||||
if the size was zero or not a multiple of 4. If the size modulus 8 was
|
||||
5, 6, or 7, the data was actually incorrect.
|
||||
|
||||
- QCborStreamReader:
|
||||
* Fixed a bug that caused the QIODevice that the data was being read
|
||||
from not to show the entire CBOR message as consumed. This allows the
|
||||
user to consume data that may follow the CBOR payload.
|
||||
|
||||
- QCryptographicHash:
|
||||
* Fixed a bug that caused the SHA-3 and Keccak algorithms to crash if
|
||||
passed 256 MB of data or more.
|
||||
|
||||
- QObject:
|
||||
* Fixed a resource leak caused by a race condition if multiple QObjects
|
||||
were created at the same time, for the first time in an application,
|
||||
from multiple threads (implies threads not started with QThread).
|
||||
|
||||
- QStorageInfo:
|
||||
* Fixed a bug that caused QStorageInfo to be unable to report all
|
||||
filesystems if the options to mounted filesystems were too long (over
|
||||
900 characters, roughly), such as those found in Docker overlay
|
||||
mounts.
|
||||
|
||||
- QTimeZone:
|
||||
* The IANA timezone database backend now properly follows symlinks even
|
||||
when they point to variable locations like /run or /var (useful when
|
||||
/etc is mounted read-only).
|
||||
|
||||
****************************************************************************
|
||||
* QtGui *
|
||||
****************************************************************************
|
||||
|
||||
- QImage:
|
||||
* Improve loading time when loading png files that have the same size as
|
||||
the target.
|
||||
|
||||
- QPixmapCache:
|
||||
* [QTBUG-76694][QTBUG-72523] Ignore unsafe access from non-main threads
|
||||
|
||||
- Text:
|
||||
* [QTBUG-76219] Fixed a bug which could cause the font cache to grow
|
||||
larger than it was supposed to.
|
||||
* [QTBUG-55096][QTBUG-74761] Fixed bug where regular text rendered with
|
||||
a color font would always display in black.
|
||||
* [QTBUG-69546] Fixed a crash bug in
|
||||
QTextDocument::clearUndoRedoStacks(QTextDocument::UndoStack).
|
||||
|
||||
****************************************************************************
|
||||
* QtNetwork *
|
||||
****************************************************************************
|
||||
|
||||
- QHostInfo:
|
||||
* Functors used in the lookupHost overloads are now called correctly in
|
||||
the thread of the context object. When used without context object,
|
||||
the thread that initiates the lookup will run the functor, and is
|
||||
required to run an event loop.
|
||||
|
||||
- Windows:
|
||||
* Correctly emit errors when trying to reach unreachable hosts or
|
||||
services
|
||||
|
||||
****************************************************************************
|
||||
* QtWidgets *
|
||||
****************************************************************************
|
||||
|
||||
- QGraphicsView:
|
||||
* Ignore disabled items when setting the mouse cursor.
|
||||
|
||||
- QSplashScreen:
|
||||
* On macOS, lower the splash screen when a modal dialog is shown to make
|
||||
sure the user sees the dialog.
|
||||
|
||||
- QSystemTrayIcon:
|
||||
* On macOS, show the icon passed into showMessage in the notification
|
||||
popup
|
||||
|
||||
****************************************************************************
|
||||
* Android *
|
||||
****************************************************************************
|
||||
|
||||
- [QTBUG-76293] Fix NDK r20 linking.
|
||||
- [QTBUG-76036] Fixed an issue where menus would not work on 64 bit
|
||||
builds.
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
Qt 5.13.1 is a bug-fix release. It maintains both forward and backward
|
||||
compatibility (source and binary) with Qt 5.13.0.
|
||||
|
||||
For more details, refer to the online documentation included in this
|
||||
distribution. The documentation is also available online:
|
||||
|
||||
https://doc.qt.io/qt-5/index.html
|
||||
|
||||
The Qt version 5.13 series is binary compatible with the 5.12.x series.
|
||||
Applications compiled for 5.12 will continue to run with 5.13.
|
||||
|
||||
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 *
|
||||
****************************************************************************
|
||||
|
||||
- [QTBUG-76521] RCC's default compression algorithm was changed back to
|
||||
Zlib, as it was in all previous releases until 5.13.0. The default will
|
||||
remain Zlib for all Qt 5.x releases but will change in Qt 6.0. To
|
||||
activate Zstd compression for your resources, either pass the
|
||||
--compress-algo=zstd option to the rcc tool or add the XML attribute
|
||||
compression-algorithm="zstd" to the <file> tags in the .qrc file.
|
||||
|
||||
****************************************************************************
|
||||
* Android *
|
||||
****************************************************************************
|
||||
|
||||
- [QTBUG-76293] Fix NDK r20 linking.
|
||||
|
||||
****************************************************************************
|
||||
* QtCore *
|
||||
****************************************************************************
|
||||
|
||||
- Global:
|
||||
* [QTBUG-72073] Added the QT_NO_FLOAT16_OPERATORS macro in order to work
|
||||
around a Microsoft <= VS2017 compiler bug that is exposed when using
|
||||
std::bitset along with any Qt header that includes <qfloat16.h>.
|
||||
|
||||
- QCborStreamReader:
|
||||
* Fixed a bug that caused the QIODevice that the data was being read
|
||||
from not to show the entire CBOR message as consumed. This allows the
|
||||
user to consume data that may follow the CBOR payload.
|
||||
|
||||
- QDeadlineTimer:
|
||||
* [QTBUG-69750] Fixed integer overflows leading to immediate timeouts.
|
||||
|
||||
- QStorageInfo:
|
||||
* Fixed a bug that caused QStorageInfo to be unable to report all
|
||||
filesystems if the options to mounted filesystems were too long (over
|
||||
900 characters, roughly), such as those found in Docker overlay
|
||||
mounts.
|
||||
|
||||
- QTextBoundaryFinder:
|
||||
* Sentence breaking now no longer breaks between uppercase letters and
|
||||
comma. This is a deviation from the Unicode specification, but
|
||||
produces less surprising behavior.
|
||||
|
||||
- QTimeZone:
|
||||
* The IANA timezone database backend now properly follows symlinks even
|
||||
when they point to variable locations like /run or /var (useful when
|
||||
/etc is mounted read-only).
|
||||
|
||||
- QVector:
|
||||
* Fixed a regression that caused fill() not to detach, corrupting shared
|
||||
copies.
|
||||
|
||||
****************************************************************************
|
||||
* QtNetwork *
|
||||
****************************************************************************
|
||||
|
||||
- Windows:
|
||||
* Correctly emit errors when trying to reach unreachable hosts or
|
||||
services
|
||||
|
||||
- QNetworkAccessManager:
|
||||
* Fixed QNetworkAccessManager::sendCustomRequest for Qt For WebAssembly.
|
||||
|
||||
****************************************************************************
|
||||
* QtGui *
|
||||
****************************************************************************
|
||||
|
||||
- [QTBUG-73231] QWindow::mapToGlobal()/mapFromGlobal() now handle windows
|
||||
spanning screens correctly.
|
||||
|
||||
- QImage:
|
||||
* Improve loading time when loading png files that have the same size as
|
||||
the target.
|
||||
|
||||
- QPixmapCache:
|
||||
* [QTBUG-76694][QTBUG-72523] Ignore unsafe access from non-main threads
|
||||
|
||||
- Text:
|
||||
* [QTBUG-76219] Fixed a bug which could cause the font cache to grow
|
||||
larger than it was supposed to.
|
||||
* [QTBUG-55096][QTBUG-74761] Fixed bug where regular text rendered with
|
||||
a color font would always display in black.
|
||||
|
||||
****************************************************************************
|
||||
* QtWidgets *
|
||||
****************************************************************************
|
||||
|
||||
- QSystemTrayIcon:
|
||||
* On macOS, show the icon passed into showMessage in the notification
|
||||
popup
|
||||
|
||||
- QDateTimeEdit:
|
||||
* Use the information provided by the locale to determine the AM/PM
|
||||
strings, unless they are already translated.
|
||||
|
||||
- QGraphicsView:
|
||||
* Ignore disabled items when setting the mouse cursor.
|
||||
|
||||
- QMenu:
|
||||
* Shortcuts are again shown by default in context menus, except on
|
||||
macOS. They can be forced off by setting
|
||||
AA_DontShowShortcutsInContextMenus to true.
|
||||
|
||||
- QSplashScreen:
|
||||
* On macOS, lower the splash screen when a modal dialog is shown to make
|
||||
sure the user sees the dialog.
|
||||
|
||||
****************************************************************************
|
||||
* Third-Party Code *
|
||||
****************************************************************************
|
||||
|
||||
- Updated bundled SQLite to version 3.28.0
|
||||
- Updated QLocale's data to CLDR v35.1
|
||||
|
||||
****************************************************************************
|
||||
* qmake *
|
||||
****************************************************************************
|
||||
|
||||
- [QTBUG-75653] The CONFIG value c++latest was added to select the latest
|
||||
C++ standard the currently used toolchain supports.
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
TEMPLATE = aux
|
||||
|
||||
global_docs.files = $$PWD/global
|
||||
global_docs.files = \
|
||||
$$PWD/global \
|
||||
$$PWD/config
|
||||
global_docs.path = $$[QT_INSTALL_DOCS]
|
||||
INSTALLS += global_docs
|
||||
!prefix_build:!equals(OUT_PWD, $$PWD): \
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
|
|
@ -61,6 +61,18 @@
|
|||
\externalpage http://doc.qt.io/qtcreator/creator-quick-tour.html
|
||||
\title Qt Creator: User Interface
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-modes.html
|
||||
\title Qt Creator: Selecting Modes
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-sidebar-views.html
|
||||
\title Qt Creator: Browsing Project Contents
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-output-panes.html
|
||||
\title Qt Creator: Viewing Output
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-cli.html
|
||||
\title Qt Creator: Using Command Line Options
|
||||
|
|
@ -125,7 +137,7 @@
|
|||
\externalpage http://doc.qt.io/qtcreator/quick-signals.html
|
||||
\title Qt Creator: Connecting Objects to Signals
|
||||
*/
|
||||
* /*!
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/quick-dynamic-properties.html
|
||||
\title Qt Creator: Specifying Dynamic Properties
|
||||
*/
|
||||
|
|
@ -153,6 +165,10 @@
|
|||
\externalpage http://doc.qt.io/qtcreator/creator-qml-modules-with-plugins.html
|
||||
\title Qt Creator: Using QML Modules with Plugins
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/quick-converting-ui-projects.html
|
||||
\title Qt Creator: Converting UI Projects to Applications
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-visual-editor.html
|
||||
\title Qt Creator: Developing Qt Quick Applications
|
||||
|
|
@ -553,6 +569,10 @@
|
|||
\externalpage http://doc.qt.io/qtcreator/creator-cpu-usage-analyzer.html
|
||||
\title Qt Creator: Analyzing CPU Usage
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-cppcheck.html
|
||||
\title Qt Creator: Analyzing Code with Cppcheck
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-autotest.html
|
||||
\title Qt Creator: Running Autotests
|
||||
|
|
@ -581,3 +601,27 @@
|
|||
\externalpage http://doc.qt.io/qtcreator/creator-scxml.html
|
||||
\title Qt Creator: Editing State Charts
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/studio-timeline.html
|
||||
\title Qt Creator: Creating Animations
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-language-servers.html
|
||||
\title Qt Creator: Using Language Servers
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/qtcreator-toc.html
|
||||
\title Qt Creator: All Topics
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-live-preview.html
|
||||
\title Qt Creator: Previewing
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-live-preview-desktop.html
|
||||
\title Qt Creator: Previewing on Desktop
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-live-preview-devices.html
|
||||
\title Qt Creator: Previewing on Devices
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ QMAKE_MAC_SDK = macosx
|
|||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.12
|
||||
QMAKE_APPLE_DEVICE_ARCHS = x86_64
|
||||
QT_MAC_SDK_VERSION_MIN = 10.13
|
||||
QT_MAC_SDK_VERSION_MAX = 10.14
|
||||
QT_MAC_SDK_VERSION_MAX = 10.15
|
||||
|
||||
device.sdk = macosx
|
||||
device.target = device
|
||||
|
|
|
|||
|
|
@ -53,7 +53,11 @@ function(_qt5_$${CMAKE_MODULE_NAME}_process_prl_file prl_file_location Configura
|
|||
set(_lib_deps)
|
||||
set(_link_flags)
|
||||
|
||||
get_filename_component(_qt5_install_libs \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/lib\" ABSOLUTE)
|
||||
!!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE)
|
||||
set(_qt5_install_libs \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}\")
|
||||
!!ELSE
|
||||
set(_qt5_install_libs \"$${CMAKE_LIB_DIR}\")
|
||||
!!ENDIF
|
||||
|
||||
if(EXISTS \"${prl_file_location}\")
|
||||
file(STRINGS \"${prl_file_location}\" _prl_strings REGEX \"QMAKE_PRL_LIBS_FOR_CMAKE[ \\t]*=\")
|
||||
|
|
|
|||
|
|
@ -509,6 +509,56 @@ static QList<QVariantMap> provisioningTeams()
|
|||
return flatTeams;
|
||||
}
|
||||
|
||||
bool ProjectBuilderMakefileGenerator::replaceLibrarySuffix(const QString &lib_file,
|
||||
const ProString &opt,
|
||||
QString &name, QString &library)
|
||||
{
|
||||
/* This isn't real nice, but it is real useful. This looks in a prl
|
||||
for what the library will ultimately be called so we can stick it
|
||||
in the ProjectFile. If the prl format ever changes (not likely) then
|
||||
this will not really work. However, more concerning is that it will
|
||||
encode the version number in the Project file which might be a bad
|
||||
things in days to come? --Sam
|
||||
*/
|
||||
if (lib_file.isEmpty())
|
||||
return false;
|
||||
|
||||
QMakeMetaInfo libinfo;
|
||||
if (!libinfo.readLib(lib_file) || libinfo.isEmpty("QMAKE_PRL_TARGET"))
|
||||
return false;
|
||||
|
||||
const QString libDir = fileInfo(lib_file).absolutePath();
|
||||
library = libDir + Option::dir_sep + libinfo.first("QMAKE_PRL_TARGET");
|
||||
|
||||
debug_msg(1, "pbuilder: Found library (%s) via PRL %s (%s)",
|
||||
opt.toLatin1().constData(), lib_file.toLatin1().constData(), library.toLatin1().constData());
|
||||
|
||||
if (project->isActiveConfig("xcode_dynamic_library_suffix")) {
|
||||
QString suffixSetting = project->first("QMAKE_XCODE_LIBRARY_SUFFIX_SETTING").toQString();
|
||||
if (!suffixSetting.isEmpty()) {
|
||||
QString librarySuffix = project->first("QMAKE_XCODE_LIBRARY_SUFFIX").toQString();
|
||||
suffixSetting = "$(" + suffixSetting + ")";
|
||||
if (!librarySuffix.isEmpty()) {
|
||||
int pos = library.lastIndexOf(librarySuffix + '.');
|
||||
if (pos == -1) {
|
||||
warn_msg(WarnLogic, "Failed to find expected suffix '%s' for library '%s'.",
|
||||
qPrintable(librarySuffix), qPrintable(library));
|
||||
} else {
|
||||
library.replace(pos, librarySuffix.length(), suffixSetting);
|
||||
if (name.endsWith(librarySuffix))
|
||||
name.chop(librarySuffix.length());
|
||||
}
|
||||
} else {
|
||||
int pos = library.lastIndexOf(name);
|
||||
if (pos != -1)
|
||||
library.insert(pos + name.length(), suffixSetting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
{
|
||||
|
|
@ -820,6 +870,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
}
|
||||
|
||||
if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES
|
||||
const ProStringList defaultLibDirs = project->values("QMAKE_DEFAULT_LIBDIRS");
|
||||
ProStringList &libdirs = project->values("QMAKE_PBX_LIBPATHS"),
|
||||
&frameworkdirs = project->values("QMAKE_FRAMEWORKPATH");
|
||||
static const char * const libs[] = { "LIBS", "LIBS_PRIVATE",
|
||||
|
|
@ -827,6 +878,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
for (int i = 0; libs[i]; i++) {
|
||||
tmp = project->values(libs[i]);
|
||||
for(int x = 0; x < tmp.count();) {
|
||||
bool libSuffixReplaced = false;
|
||||
bool remove = false;
|
||||
QString library, name;
|
||||
ProString opt = tmp[x];
|
||||
|
|
@ -839,49 +891,12 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
QString lib("lib" + name);
|
||||
for (ProStringList::Iterator lit = libdirs.begin(); lit != libdirs.end(); ++lit) {
|
||||
if(project->isActiveConfig("link_prl")) {
|
||||
/* This isn't real nice, but it is real useful. This looks in a prl
|
||||
for what the library will ultimately be called so we can stick it
|
||||
in the ProjectFile. If the prl format ever changes (not likely) then
|
||||
this will not really work. However, more concerning is that it will
|
||||
encode the version number in the Project file which might be a bad
|
||||
things in days to come? --Sam
|
||||
*/
|
||||
QString lib_file = QMakeMetaInfo::checkLib(Option::normalizePath(
|
||||
(*lit) + Option::dir_sep + lib + Option::prl_ext));
|
||||
if (!lib_file.isEmpty()) {
|
||||
QMakeMetaInfo libinfo;
|
||||
if(libinfo.readLib(lib_file)) {
|
||||
if(!libinfo.isEmpty("QMAKE_PRL_TARGET")) {
|
||||
library = (*lit) + Option::dir_sep + libinfo.first("QMAKE_PRL_TARGET");
|
||||
debug_msg(1, "pbuilder: Found library (%s) via PRL %s (%s)",
|
||||
opt.toLatin1().constData(), lib_file.toLatin1().constData(), library.toLatin1().constData());
|
||||
remove = true;
|
||||
|
||||
if (project->isActiveConfig("xcode_dynamic_library_suffix")) {
|
||||
QString suffixSetting = project->first("QMAKE_XCODE_LIBRARY_SUFFIX_SETTING").toQString();
|
||||
if (!suffixSetting.isEmpty()) {
|
||||
QString librarySuffix = project->first("QMAKE_XCODE_LIBRARY_SUFFIX").toQString();
|
||||
suffixSetting = "$(" + suffixSetting + ")";
|
||||
if (!librarySuffix.isEmpty()) {
|
||||
int pos = library.lastIndexOf(librarySuffix + '.');
|
||||
if (pos == -1) {
|
||||
warn_msg(WarnLogic, "Failed to find expected suffix '%s' for library '%s'.",
|
||||
qPrintable(librarySuffix), qPrintable(library));
|
||||
} else {
|
||||
library.replace(pos, librarySuffix.length(), suffixSetting);
|
||||
if (name.endsWith(librarySuffix))
|
||||
name.chop(librarySuffix.length());
|
||||
}
|
||||
} else {
|
||||
int pos = library.lastIndexOf(name);
|
||||
if (pos != -1)
|
||||
library.insert(pos + name.length(), suffixSetting);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const QString prlFilePath = QMakeMetaInfo::checkLib(
|
||||
Option::normalizePath((*lit) + Option::dir_sep + lib
|
||||
+ Option::prl_ext));
|
||||
if (replaceLibrarySuffix(prlFilePath, opt, name, library))
|
||||
remove = true;
|
||||
libSuffixReplaced = true;
|
||||
}
|
||||
if(!remove) {
|
||||
QString extns[] = { ".dylib", ".so", ".a", QString() };
|
||||
|
|
@ -931,6 +946,16 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
}
|
||||
}
|
||||
if(!library.isEmpty()) {
|
||||
if (!libSuffixReplaced) {
|
||||
const QFileInfo fi = fileInfo(library);
|
||||
const QString prlFilePath = QMakeMetaInfo::checkLib(
|
||||
Option::normalizePath(fi.absolutePath() + '/' + fi.completeBaseName()
|
||||
+ Option::prl_ext));
|
||||
if (!prlFilePath.isEmpty()) {
|
||||
name = fi.completeBaseName().mid(3);
|
||||
replaceLibrarySuffix(prlFilePath, opt, name, library);
|
||||
}
|
||||
}
|
||||
const int slsh = library.lastIndexOf(Option::dir_sep);
|
||||
if(name.isEmpty()) {
|
||||
if(slsh != -1)
|
||||
|
|
@ -938,8 +963,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
}
|
||||
if(slsh != -1) {
|
||||
const QString path = QFileInfo(library.left(slsh)).absoluteFilePath();
|
||||
if(!path.isEmpty() && !libdirs.contains(path))
|
||||
if (!path.isEmpty() && !libdirs.contains(path)
|
||||
&& !defaultLibDirs.contains(path)) {
|
||||
libdirs += path;
|
||||
}
|
||||
}
|
||||
library = fileFixify(library, FileFixifyFromOutdir | FileFixifyAbsolute);
|
||||
QString key = keyFor(library);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ class ProjectBuilderMakefileGenerator : public UnixMakefileGenerator
|
|||
bool writeSubDirs(QTextStream &);
|
||||
bool writeMakeParts(QTextStream &);
|
||||
bool writeMakefile(QTextStream &) override;
|
||||
bool replaceLibrarySuffix(const QString &lib_file, const ProString &opt, QString &name,
|
||||
QString &library);
|
||||
|
||||
QString pbxbuild();
|
||||
QHash<QString, QString> keys;
|
||||
|
|
|
|||
|
|
@ -1199,8 +1199,10 @@ void UnixMakefileGenerator::init2()
|
|||
project->values("QMAKE_FRAMEWORK_VERSION").append(project->first("VER_MAJ"));
|
||||
|
||||
if (project->first("TEMPLATE") == "aux") {
|
||||
project->values("PRL_TARGET") =
|
||||
project->values("TARGET").first().prepend(project->first("QMAKE_PREFIX_STATICLIB"));
|
||||
project->values("PRL_TARGET") = {
|
||||
project->first("QMAKE_PREFIX_STATICLIB") +
|
||||
project->first("TARGET")
|
||||
};
|
||||
} else if (!project->values("QMAKE_APP_FLAG").isEmpty()) {
|
||||
if(!project->isEmpty("QMAKE_BUNDLE")) {
|
||||
ProString bundle_loc = project->first("QMAKE_BUNDLE_LOCATION");
|
||||
|
|
|
|||
|
|
@ -1803,8 +1803,8 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex
|
|||
#ifndef QT_BOOTSTRAPPED
|
||||
Q_TRACE(qt_message_print, msgType, context.category, context.function, context.file, context.line, message);
|
||||
|
||||
// qDebug, qWarning, ... macros do not check whether category is enabled
|
||||
if (isDefaultCategory(context.category)) {
|
||||
// qDebug, qWarning, ... macros do not check whether category is enabledgc
|
||||
if (msgType != QtFatalMsg && isDefaultCategory(context.category)) {
|
||||
if (QLoggingCategory *defaultCategory = QLoggingCategory::defaultCategory()) {
|
||||
if (!defaultCategory->isEnabled(msgType))
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -3287,7 +3287,7 @@
|
|||
the application object is created, or by setting the QT_SCALE_FACTOR_ROUNDING_POLICY
|
||||
environment variable.
|
||||
|
||||
\sa QGuiApplication::setHighDdpiScaleFactorRoundingPolicy()
|
||||
\sa QGuiApplication::setHighDpiScaleFactorRoundingPolicy()
|
||||
\sa AA_EnableHighDpiScaling.
|
||||
|
||||
\omitvalue Unset
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 Intel Corporation.
|
||||
** Copyright (C) 2019 Intel Corporation.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
|
|
@ -103,17 +103,22 @@ static QT_FUNCTION_TARGET(RDRND) qsizetype qt_random_cpu(void *buffer, qsizetype
|
|||
{
|
||||
unsigned *ptr = reinterpret_cast<unsigned *>(buffer);
|
||||
unsigned *end = ptr + count;
|
||||
int retries = 10;
|
||||
|
||||
while (ptr + sizeof(qregisteruint)/sizeof(*ptr) <= end) {
|
||||
if (_rdrandXX_step(reinterpret_cast<qregisteruint *>(ptr)) == 0)
|
||||
if (_rdrandXX_step(reinterpret_cast<qregisteruint *>(ptr)))
|
||||
ptr += sizeof(qregisteruint)/sizeof(*ptr);
|
||||
else if (--retries == 0)
|
||||
goto out;
|
||||
ptr += sizeof(qregisteruint)/sizeof(*ptr);
|
||||
}
|
||||
|
||||
if (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) {
|
||||
if (_rdrand32_step(ptr))
|
||||
goto out;
|
||||
++ptr;
|
||||
while (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) {
|
||||
bool ok = _rdrand32_step(ptr);
|
||||
if (!ok && --retries)
|
||||
continue;
|
||||
if (ok)
|
||||
++ptr;
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE
|
|||
# define QLIBRARY_AS_DEBUG true
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_UNIX) || defined(Q_CC_MINGW)
|
||||
#if defined(Q_OS_UNIX)
|
||||
// We don't use separate debug and release libs on UNIX, so we want
|
||||
// to allow loading plugins, regardless of how they were built.
|
||||
# define QT_NO_DEBUG_PLUGIN_CHECK
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
/*!
|
||||
\since 5.14
|
||||
\internal
|
||||
|
||||
\class QHijriCalendar
|
||||
\inmodule QtCore
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ using namespace QRoundingDown;
|
|||
|
||||
/*!
|
||||
\since 5.14
|
||||
\internal
|
||||
|
||||
\class QIslamicCivilCalendar
|
||||
\inmodule QtCore
|
||||
|
|
@ -67,7 +68,7 @@ using namespace QRoundingDown;
|
|||
long. Its determination of leap years follows a 30-year cycle, in each of
|
||||
which the years 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 and 29 are leap years.
|
||||
|
||||
\sa QJijriCalendar, QCalendar
|
||||
\sa QHijriCalendar, QCalendar
|
||||
*/
|
||||
|
||||
QIslamicCivilCalendar::QIslamicCivilCalendar()
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ static quint32 icon_name_hash(const char *p)
|
|||
QVector<const char *> QIconCacheGtkReader::lookup(const QStringRef &name)
|
||||
{
|
||||
QVector<const char *> ret;
|
||||
if (!isValid())
|
||||
if (!isValid() || name.isEmpty())
|
||||
return ret;
|
||||
|
||||
QByteArray nameUtf8 = name.toUtf8();
|
||||
|
|
|
|||
|
|
@ -2762,7 +2762,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
|
|||
QWindow *window = e->window.data();
|
||||
typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
|
||||
QHash<QWindow *, StatesAndTouchPoints> windowsNeedingEvents;
|
||||
bool stationaryTouchPointChangedVelocity = false;
|
||||
bool stationaryTouchPointChangedProperty = false;
|
||||
|
||||
for (int i = 0; i < e->points.count(); ++i) {
|
||||
QTouchEvent::TouchPoint touchPoint = e->points.at(i);
|
||||
|
|
@ -2842,7 +2842,11 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
|
|||
if (touchPoint.state() == Qt::TouchPointStationary) {
|
||||
if (touchInfo.touchPoint.velocity() != touchPoint.velocity()) {
|
||||
touchInfo.touchPoint.setVelocity(touchPoint.velocity());
|
||||
stationaryTouchPointChangedVelocity = true;
|
||||
stationaryTouchPointChangedProperty = true;
|
||||
}
|
||||
if (!qFuzzyCompare(touchInfo.touchPoint.pressure(), touchPoint.pressure())) {
|
||||
touchInfo.touchPoint.setPressure(touchPoint.pressure());
|
||||
stationaryTouchPointChangedProperty = true;
|
||||
}
|
||||
} else {
|
||||
touchInfo.touchPoint = touchPoint;
|
||||
|
|
@ -2883,7 +2887,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
|
|||
break;
|
||||
case Qt::TouchPointStationary:
|
||||
// don't send the event if nothing changed
|
||||
if (!stationaryTouchPointChangedVelocity)
|
||||
if (!stationaryTouchPointChangedProperty)
|
||||
continue;
|
||||
Q_FALLTHROUGH();
|
||||
default:
|
||||
|
|
@ -3501,7 +3505,7 @@ Qt::ApplicationState QGuiApplication::applicationState()
|
|||
\since 5.14
|
||||
|
||||
Sets the high-DPI scale factor rounding policy for the application. The
|
||||
policy decides how non-integer scale factors (such as Windows 150%) are
|
||||
\a policy decides how non-integer scale factors (such as Windows 150%) are
|
||||
handled, for applications that have AA_EnableHighDpiScaling enabled.
|
||||
|
||||
The two principal options are whether fractional scale factors should
|
||||
|
|
|
|||
|
|
@ -538,7 +538,7 @@ void QHighDpiScaling::updateHighDpiScaling()
|
|||
++i;
|
||||
}
|
||||
}
|
||||
m_active = m_globalScalingActive || m_usePixelDensity;
|
||||
m_active = m_globalScalingActive || m_screenFactorSet || m_usePixelDensity;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -5019,6 +5019,23 @@ QRhiProfiler *QRhi::profiler()
|
|||
return &d->profiler;
|
||||
}
|
||||
|
||||
/*!
|
||||
Attempts to release resources in the backend's caches. This can include both
|
||||
CPU and GPU resources. Only memory and resources that can be recreated
|
||||
automatically are in scope. As an example, if the backend's
|
||||
QRhiGraphicsPipeline implementation maintains a cache of shader compilation
|
||||
results, calling this function leads to emptying that cache, thus
|
||||
potentially freeing up memory and graphics resources.
|
||||
|
||||
Calling this function makes sense in resource constrained environments,
|
||||
where at a certain point there is a need to ensure minimal resource usage,
|
||||
at the expense of performance.
|
||||
*/
|
||||
void QRhi::releaseCachedResources()
|
||||
{
|
||||
d->releaseCachedResources();
|
||||
}
|
||||
|
||||
/*!
|
||||
\return a new graphics pipeline resource.
|
||||
|
||||
|
|
|
|||
|
|
@ -1420,6 +1420,8 @@ public:
|
|||
static const int MAX_LAYERS = 6; // cubemaps only
|
||||
static const int MAX_LEVELS = 16; // a width and/or height of 65536 should be enough for everyone
|
||||
|
||||
void releaseCachedResources();
|
||||
|
||||
protected:
|
||||
QRhi();
|
||||
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ public:
|
|||
virtual const QRhiNativeHandles *nativeHandles() = 0;
|
||||
virtual void sendVMemStatsToProfiler() = 0;
|
||||
virtual void makeThreadLocalNativeContextCurrent() = 0;
|
||||
virtual void releaseCachedResources() = 0;
|
||||
|
||||
bool isCompressedFormat(QRhiTexture::Format format) const;
|
||||
void compressedFormatInfo(QRhiTexture::Format format, const QSize &size,
|
||||
|
|
@ -205,6 +206,8 @@ public:
|
|||
|
||||
QRhi *q;
|
||||
|
||||
static const int MAX_SHADER_CACHE_ENTRIES = 128;
|
||||
|
||||
protected:
|
||||
bool debugMarkers = false;
|
||||
int currentFrameSlot = 0; // for vk, mtl, and similar. unused by gl and d3d11.
|
||||
|
|
|
|||
|
|
@ -267,10 +267,20 @@ bool QRhiD3D11::create(QRhi::Flags flags)
|
|||
return true;
|
||||
}
|
||||
|
||||
void QRhiD3D11::clearShaderCache()
|
||||
{
|
||||
for (Shader &s : m_shaderCache)
|
||||
s.s->Release();
|
||||
|
||||
m_shaderCache.clear();
|
||||
}
|
||||
|
||||
void QRhiD3D11::destroy()
|
||||
{
|
||||
finishActiveReadbacks();
|
||||
|
||||
clearShaderCache();
|
||||
|
||||
if (annotations) {
|
||||
annotations->Release();
|
||||
annotations = nullptr;
|
||||
|
|
@ -461,6 +471,11 @@ void QRhiD3D11::makeThreadLocalNativeContextCurrent()
|
|||
// nothing to do here
|
||||
}
|
||||
|
||||
void QRhiD3D11::releaseCachedResources()
|
||||
{
|
||||
clearShaderCache();
|
||||
}
|
||||
|
||||
QRhiRenderBuffer *QRhiD3D11::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||
{
|
||||
|
|
@ -3408,30 +3423,57 @@ bool QD3D11GraphicsPipeline::build()
|
|||
|
||||
QByteArray vsByteCode;
|
||||
for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) {
|
||||
QString error;
|
||||
QByteArray bytecode = compileHlslShaderSource(shaderStage.shader(), shaderStage.shaderVariant(), &error);
|
||||
if (bytecode.isEmpty()) {
|
||||
qWarning("HLSL shader compilation failed: %s", qPrintable(error));
|
||||
return false;
|
||||
}
|
||||
switch (shaderStage.type()) {
|
||||
case QRhiShaderStage::Vertex:
|
||||
hr = rhiD->dev->CreateVertexShader(bytecode.constData(), bytecode.size(), nullptr, &vs);
|
||||
if (FAILED(hr)) {
|
||||
qWarning("Failed to create vertex shader: %s", qPrintable(comErrorMessage(hr)));
|
||||
auto cacheIt = rhiD->m_shaderCache.constFind(shaderStage);
|
||||
if (cacheIt != rhiD->m_shaderCache.constEnd()) {
|
||||
switch (shaderStage.type()) {
|
||||
case QRhiShaderStage::Vertex:
|
||||
vs = static_cast<ID3D11VertexShader *>(cacheIt->s);
|
||||
vs->AddRef();
|
||||
vsByteCode = cacheIt->bytecode;
|
||||
break;
|
||||
case QRhiShaderStage::Fragment:
|
||||
fs = static_cast<ID3D11PixelShader *>(cacheIt->s);
|
||||
fs->AddRef();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
QString error;
|
||||
const QByteArray bytecode = compileHlslShaderSource(shaderStage.shader(), shaderStage.shaderVariant(), &error);
|
||||
if (bytecode.isEmpty()) {
|
||||
qWarning("HLSL shader compilation failed: %s", qPrintable(error));
|
||||
return false;
|
||||
}
|
||||
vsByteCode = bytecode;
|
||||
break;
|
||||
case QRhiShaderStage::Fragment:
|
||||
hr = rhiD->dev->CreatePixelShader(bytecode.constData(), bytecode.size(), nullptr, &fs);
|
||||
if (FAILED(hr)) {
|
||||
qWarning("Failed to create pixel shader: %s", qPrintable(comErrorMessage(hr)));
|
||||
return false;
|
||||
|
||||
if (rhiD->m_shaderCache.count() >= QRhiD3D11::MAX_SHADER_CACHE_ENTRIES) {
|
||||
// Use the simplest strategy: too many cached shaders -> drop them all.
|
||||
rhiD->clearShaderCache();
|
||||
}
|
||||
|
||||
switch (shaderStage.type()) {
|
||||
case QRhiShaderStage::Vertex:
|
||||
hr = rhiD->dev->CreateVertexShader(bytecode.constData(), bytecode.size(), nullptr, &vs);
|
||||
if (FAILED(hr)) {
|
||||
qWarning("Failed to create vertex shader: %s", qPrintable(comErrorMessage(hr)));
|
||||
return false;
|
||||
}
|
||||
vsByteCode = bytecode;
|
||||
rhiD->m_shaderCache.insert(shaderStage, QRhiD3D11::Shader(vs, bytecode));
|
||||
vs->AddRef();
|
||||
break;
|
||||
case QRhiShaderStage::Fragment:
|
||||
hr = rhiD->dev->CreatePixelShader(bytecode.constData(), bytecode.size(), nullptr, &fs);
|
||||
if (FAILED(hr)) {
|
||||
qWarning("Failed to create pixel shader: %s", qPrintable(comErrorMessage(hr)));
|
||||
return false;
|
||||
}
|
||||
rhiD->m_shaderCache.insert(shaderStage, QRhiD3D11::Shader(fs, bytecode));
|
||||
fs->AddRef();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3501,18 +3543,30 @@ bool QD3D11ComputePipeline::build()
|
|||
|
||||
QRHI_RES_RHI(QRhiD3D11);
|
||||
|
||||
QString error;
|
||||
QByteArray bytecode = compileHlslShaderSource(m_shaderStage.shader(), m_shaderStage.shaderVariant(), &error);
|
||||
if (bytecode.isEmpty()) {
|
||||
qWarning("HLSL compute shader compilation failed: %s", qPrintable(error));
|
||||
return false;
|
||||
auto cacheIt = rhiD->m_shaderCache.constFind(m_shaderStage);
|
||||
if (cacheIt != rhiD->m_shaderCache.constEnd()) {
|
||||
cs = static_cast<ID3D11ComputeShader *>(cacheIt->s);
|
||||
} else {
|
||||
QString error;
|
||||
const QByteArray bytecode = compileHlslShaderSource(m_shaderStage.shader(), m_shaderStage.shaderVariant(), &error);
|
||||
if (bytecode.isEmpty()) {
|
||||
qWarning("HLSL compute shader compilation failed: %s", qPrintable(error));
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT hr = rhiD->dev->CreateComputeShader(bytecode.constData(), bytecode.size(), nullptr, &cs);
|
||||
if (FAILED(hr)) {
|
||||
qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rhiD->m_shaderCache.count() >= QRhiD3D11::MAX_SHADER_CACHE_ENTRIES)
|
||||
rhiD->clearShaderCache();
|
||||
|
||||
rhiD->m_shaderCache.insert(m_shaderStage, QRhiD3D11::Shader(cs, bytecode));
|
||||
}
|
||||
|
||||
HRESULT hr = rhiD->dev->CreateComputeShader(bytecode.constData(), bytecode.size(), nullptr, &cs);
|
||||
if (FAILED(hr)) {
|
||||
qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
|
||||
return false;
|
||||
}
|
||||
cs->AddRef();
|
||||
|
||||
generation += 1;
|
||||
rhiD->registerResource(this);
|
||||
|
|
|
|||
|
|
@ -632,6 +632,7 @@ public:
|
|||
const QRhiNativeHandles *nativeHandles() override;
|
||||
void sendVMemStatsToProfiler() override;
|
||||
void makeThreadLocalNativeContextCurrent() override;
|
||||
void releaseCachedResources() override;
|
||||
|
||||
void enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
|
||||
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc);
|
||||
|
|
@ -646,6 +647,7 @@ public:
|
|||
DXGI_SAMPLE_DESC effectiveSampleCount(int sampleCount) const;
|
||||
void finishActiveReadbacks();
|
||||
void reportLiveObjects(ID3D11Device *device);
|
||||
void clearShaderCache();
|
||||
|
||||
bool debugLayer = false;
|
||||
bool importedDevice = false;
|
||||
|
|
@ -684,6 +686,14 @@ public:
|
|||
QRhiTexture::Format format;
|
||||
};
|
||||
QVector<ActiveReadback> activeReadbacks;
|
||||
|
||||
struct Shader {
|
||||
Shader() = default;
|
||||
Shader(IUnknown *s, const QByteArray &bytecode) : s(s), bytecode(bytecode) { }
|
||||
IUnknown *s;
|
||||
QByteArray bytecode;
|
||||
};
|
||||
QHash<QRhiShaderStage, Shader> m_shaderCache;
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(QRhiD3D11::ActiveReadback, Q_MOVABLE_TYPE);
|
||||
|
|
|
|||
|
|
@ -502,6 +502,10 @@ void QRhiGles2::destroy()
|
|||
ensureContext();
|
||||
executeDeferredReleases();
|
||||
|
||||
for (uint shader : m_shaderCache)
|
||||
f->glDeleteShader(shader);
|
||||
m_shaderCache.clear();
|
||||
|
||||
if (!importedContext) {
|
||||
delete ctx;
|
||||
ctx = nullptr;
|
||||
|
|
@ -757,6 +761,17 @@ void QRhiGles2::makeThreadLocalNativeContextCurrent()
|
|||
ensureContext();
|
||||
}
|
||||
|
||||
void QRhiGles2::releaseCachedResources()
|
||||
{
|
||||
if (!ensureContext())
|
||||
return;
|
||||
|
||||
for (uint shader : m_shaderCache)
|
||||
f->glDeleteShader(shader);
|
||||
|
||||
m_shaderCache.clear();
|
||||
}
|
||||
|
||||
QRhiRenderBuffer *QRhiGles2::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||
{
|
||||
|
|
@ -2673,7 +2688,6 @@ static inline GLenum toGlShaderType(QRhiShaderStage::Type type)
|
|||
bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage,
|
||||
QShaderDescription *desc, int *glslVersionUsed)
|
||||
{
|
||||
GLuint shader = f->glCreateShader(toGlShaderType(shaderStage.type()));
|
||||
const QShader bakedShader = shaderStage.shader();
|
||||
QVector<int> versionsToTry;
|
||||
QByteArray source;
|
||||
|
|
@ -2733,27 +2747,40 @@ bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage
|
|||
return false;
|
||||
}
|
||||
|
||||
const char *srcStr = source.constData();
|
||||
const GLint srcLength = source.count();
|
||||
f->glShaderSource(shader, 1, &srcStr, &srcLength);
|
||||
f->glCompileShader(shader);
|
||||
GLint compiled = 0;
|
||||
f->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
|
||||
if (!compiled) {
|
||||
GLint infoLogLength = 0;
|
||||
f->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
QByteArray log;
|
||||
if (infoLogLength > 1) {
|
||||
GLsizei length = 0;
|
||||
log.resize(infoLogLength);
|
||||
f->glGetShaderInfoLog(shader, infoLogLength, &length, log.data());
|
||||
GLuint shader;
|
||||
auto cacheIt = m_shaderCache.constFind(shaderStage);
|
||||
if (cacheIt != m_shaderCache.constEnd()) {
|
||||
shader = *cacheIt;
|
||||
} else {
|
||||
shader = f->glCreateShader(toGlShaderType(shaderStage.type()));
|
||||
const char *srcStr = source.constData();
|
||||
const GLint srcLength = source.count();
|
||||
f->glShaderSource(shader, 1, &srcStr, &srcLength);
|
||||
f->glCompileShader(shader);
|
||||
GLint compiled = 0;
|
||||
f->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
|
||||
if (!compiled) {
|
||||
GLint infoLogLength = 0;
|
||||
f->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
QByteArray log;
|
||||
if (infoLogLength > 1) {
|
||||
GLsizei length = 0;
|
||||
log.resize(infoLogLength);
|
||||
f->glGetShaderInfoLog(shader, infoLogLength, &length, log.data());
|
||||
}
|
||||
qWarning("Failed to compile shader: %s\nSource was:\n%s", log.constData(), source.constData());
|
||||
return false;
|
||||
}
|
||||
qWarning("Failed to compile shader: %s\nSource was:\n%s", log.constData(), source.constData());
|
||||
return false;
|
||||
if (m_shaderCache.count() >= MAX_SHADER_CACHE_ENTRIES) {
|
||||
// Use the simplest strategy: too many cached shaders -> drop them all.
|
||||
for (uint shader : m_shaderCache)
|
||||
f->glDeleteShader(shader); // does not actually get released yet when attached to a not-yet-released program
|
||||
m_shaderCache.clear();
|
||||
}
|
||||
m_shaderCache.insert(shaderStage, shader);
|
||||
}
|
||||
|
||||
f->glAttachShader(program, shader);
|
||||
f->glDeleteShader(shader);
|
||||
|
||||
*desc = bakedShader.description();
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -665,6 +665,7 @@ public:
|
|||
const QRhiNativeHandles *nativeHandles() override;
|
||||
void sendVMemStatsToProfiler() override;
|
||||
void makeThreadLocalNativeContextCurrent() override;
|
||||
void releaseCachedResources() override;
|
||||
|
||||
bool ensureContext(QSurface *surface = nullptr) const;
|
||||
void executeDeferredReleases();
|
||||
|
|
@ -804,6 +805,8 @@ public:
|
|||
bool active = false;
|
||||
QGles2CommandBuffer cbWrapper;
|
||||
} ofr;
|
||||
|
||||
QHash<QRhiShaderStage, uint> m_shaderCache;
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(QRhiGles2::DeferredReleaseEntry, Q_MOVABLE_TYPE);
|
||||
|
|
|
|||
|
|
@ -138,6 +138,20 @@ QT_BEGIN_NAMESPACE
|
|||
\l{QRhiCommandBuffer::endPass()}.
|
||||
*/
|
||||
|
||||
struct QMetalShader
|
||||
{
|
||||
id<MTLLibrary> lib = nil;
|
||||
id<MTLFunction> func = nil;
|
||||
std::array<uint, 3> localSize;
|
||||
|
||||
void release() {
|
||||
[lib release];
|
||||
lib = nil;
|
||||
[func release];
|
||||
func = nil;
|
||||
}
|
||||
};
|
||||
|
||||
struct QRhiMetalData
|
||||
{
|
||||
QRhiMetalData(QRhiImplementation *rhi) : ofr(rhi) { }
|
||||
|
|
@ -206,6 +220,8 @@ struct QRhiMetalData
|
|||
API_AVAILABLE(macos(10.13), ios(11.0)) id<MTLCaptureScope> captureScope = nil;
|
||||
|
||||
static const int TEXBUF_ALIGN = 256; // probably not accurate
|
||||
|
||||
QHash<QRhiShaderStage, QMetalShader> shaderCache;
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(QRhiMetalData::DeferredReleaseEntry, Q_MOVABLE_TYPE);
|
||||
|
|
@ -289,17 +305,14 @@ struct QMetalGraphicsPipelineData
|
|||
MTLPrimitiveType primitiveType;
|
||||
MTLWinding winding;
|
||||
MTLCullMode cullMode;
|
||||
id<MTLLibrary> vsLib = nil;
|
||||
id<MTLFunction> vsFunc = nil;
|
||||
id<MTLLibrary> fsLib = nil;
|
||||
id<MTLFunction> fsFunc = nil;
|
||||
QMetalShader vs;
|
||||
QMetalShader fs;
|
||||
};
|
||||
|
||||
struct QMetalComputePipelineData
|
||||
{
|
||||
id<MTLComputePipelineState> ps = nil;
|
||||
id<MTLLibrary> csLib = nil;
|
||||
id<MTLFunction> csFunc = nil;
|
||||
QMetalShader cs;
|
||||
MTLSize localSize;
|
||||
};
|
||||
|
||||
|
|
@ -404,6 +417,10 @@ void QRhiMetal::destroy()
|
|||
executeDeferredReleases(true);
|
||||
finishActiveReadbacks(true);
|
||||
|
||||
for (QMetalShader &s : d->shaderCache)
|
||||
s.release();
|
||||
d->shaderCache.clear();
|
||||
|
||||
if (@available(macOS 10.13, iOS 11.0, *)) {
|
||||
[d->captureScope release];
|
||||
d->captureScope = nil;
|
||||
|
|
@ -570,6 +587,14 @@ void QRhiMetal::makeThreadLocalNativeContextCurrent()
|
|||
// nothing to do here
|
||||
}
|
||||
|
||||
void QRhiMetal::releaseCachedResources()
|
||||
{
|
||||
for (QMetalShader &s : d->shaderCache)
|
||||
s.release();
|
||||
|
||||
d->shaderCache.clear();
|
||||
}
|
||||
|
||||
QRhiRenderBuffer *QRhiMetal::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||
{
|
||||
|
|
@ -2843,36 +2868,17 @@ void QMetalGraphicsPipeline::release()
|
|||
{
|
||||
QRHI_RES_RHI(QRhiMetal);
|
||||
|
||||
d->vs.release();
|
||||
d->fs.release();
|
||||
|
||||
[d->ds release];
|
||||
d->ds = nil;
|
||||
|
||||
if (!d->ps)
|
||||
return;
|
||||
|
||||
if (d->ps) {
|
||||
[d->ps release];
|
||||
d->ps = nil;
|
||||
}
|
||||
|
||||
if (d->ds) {
|
||||
[d->ds release];
|
||||
d->ds = nil;
|
||||
}
|
||||
|
||||
if (d->vsFunc) {
|
||||
[d->vsFunc release];
|
||||
d->vsFunc = nil;
|
||||
}
|
||||
if (d->vsLib) {
|
||||
[d->vsLib release];
|
||||
d->vsLib = nil;
|
||||
}
|
||||
|
||||
if (d->fsFunc) {
|
||||
[d->fsFunc release];
|
||||
d->fsFunc = nil;
|
||||
}
|
||||
if (d->fsLib) {
|
||||
[d->fsLib release];
|
||||
d->fsLib = nil;
|
||||
}
|
||||
[d->ps release];
|
||||
d->ps = nil;
|
||||
|
||||
rhiD->unregisterResource(this);
|
||||
}
|
||||
|
|
@ -3159,34 +3165,66 @@ bool QMetalGraphicsPipeline::build()
|
|||
// buffers not just the resource binding layout) so leave it at the default
|
||||
|
||||
for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) {
|
||||
QString error;
|
||||
QByteArray entryPoint;
|
||||
id<MTLLibrary> lib = rhiD->d->createMetalLib(shaderStage.shader(), shaderStage.shaderVariant(), &error, &entryPoint);
|
||||
if (!lib) {
|
||||
qWarning("MSL shader compilation failed: %s", qPrintable(error));
|
||||
return false;
|
||||
}
|
||||
id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
|
||||
if (!func) {
|
||||
qWarning("MSL function for entry point %s not found", entryPoint.constData());
|
||||
[lib release];
|
||||
return false;
|
||||
}
|
||||
switch (shaderStage.type()) {
|
||||
case QRhiShaderStage::Vertex:
|
||||
rpDesc.vertexFunction = func;
|
||||
d->vsLib = lib;
|
||||
d->vsFunc = func;
|
||||
break;
|
||||
case QRhiShaderStage::Fragment:
|
||||
rpDesc.fragmentFunction = func;
|
||||
d->fsLib = lib;
|
||||
d->fsFunc = func;
|
||||
break;
|
||||
default:
|
||||
[func release];
|
||||
[lib release];
|
||||
break;
|
||||
auto cacheIt = rhiD->d->shaderCache.constFind(shaderStage);
|
||||
if (cacheIt != rhiD->d->shaderCache.constEnd()) {
|
||||
switch (shaderStage.type()) {
|
||||
case QRhiShaderStage::Vertex:
|
||||
d->vs = *cacheIt;
|
||||
[d->vs.lib retain];
|
||||
[d->vs.func retain];
|
||||
rpDesc.vertexFunction = d->vs.func;
|
||||
break;
|
||||
case QRhiShaderStage::Fragment:
|
||||
d->fs = *cacheIt;
|
||||
[d->fs.lib retain];
|
||||
[d->fs.func retain];
|
||||
rpDesc.fragmentFunction = d->fs.func;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
QString error;
|
||||
QByteArray entryPoint;
|
||||
id<MTLLibrary> lib = rhiD->d->createMetalLib(shaderStage.shader(), shaderStage.shaderVariant(), &error, &entryPoint);
|
||||
if (!lib) {
|
||||
qWarning("MSL shader compilation failed: %s", qPrintable(error));
|
||||
return false;
|
||||
}
|
||||
id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
|
||||
if (!func) {
|
||||
qWarning("MSL function for entry point %s not found", entryPoint.constData());
|
||||
[lib release];
|
||||
return false;
|
||||
}
|
||||
if (rhiD->d->shaderCache.count() >= QRhiMetal::MAX_SHADER_CACHE_ENTRIES) {
|
||||
// Use the simplest strategy: too many cached shaders -> drop them all.
|
||||
for (QMetalShader &s : rhiD->d->shaderCache)
|
||||
s.release();
|
||||
rhiD->d->shaderCache.clear();
|
||||
}
|
||||
switch (shaderStage.type()) {
|
||||
case QRhiShaderStage::Vertex:
|
||||
d->vs.lib = lib;
|
||||
d->vs.func = func;
|
||||
rhiD->d->shaderCache.insert(shaderStage, d->vs);
|
||||
[d->vs.lib retain];
|
||||
[d->vs.func retain];
|
||||
rpDesc.vertexFunction = func;
|
||||
break;
|
||||
case QRhiShaderStage::Fragment:
|
||||
d->fs.lib = lib;
|
||||
d->fs.func = func;
|
||||
rhiD->d->shaderCache.insert(shaderStage, d->fs);
|
||||
[d->fs.lib retain];
|
||||
[d->fs.func retain];
|
||||
rpDesc.fragmentFunction = func;
|
||||
break;
|
||||
default:
|
||||
[func release];
|
||||
[lib release];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3286,22 +3324,13 @@ void QMetalComputePipeline::release()
|
|||
{
|
||||
QRHI_RES_RHI(QRhiMetal);
|
||||
|
||||
if (d->csFunc) {
|
||||
[d->csFunc release];
|
||||
d->csFunc = nil;
|
||||
}
|
||||
if (d->csLib) {
|
||||
[d->csLib release];
|
||||
d->csLib = nil;
|
||||
}
|
||||
d->cs.release();
|
||||
|
||||
if (!d->ps)
|
||||
return;
|
||||
|
||||
if (d->ps) {
|
||||
[d->ps release];
|
||||
d->ps = nil;
|
||||
}
|
||||
[d->ps release];
|
||||
d->ps = nil;
|
||||
|
||||
rhiD->unregisterResource(this);
|
||||
}
|
||||
|
|
@ -3313,28 +3342,44 @@ bool QMetalComputePipeline::build()
|
|||
|
||||
QRHI_RES_RHI(QRhiMetal);
|
||||
|
||||
const QShader shader = m_shaderStage.shader();
|
||||
QString error;
|
||||
QByteArray entryPoint;
|
||||
id<MTLLibrary> lib = rhiD->d->createMetalLib(shader, m_shaderStage.shaderVariant(),
|
||||
&error, &entryPoint);
|
||||
if (!lib) {
|
||||
qWarning("MSL shader compilation failed: %s", qPrintable(error));
|
||||
return false;
|
||||
auto cacheIt = rhiD->d->shaderCache.constFind(m_shaderStage);
|
||||
if (cacheIt != rhiD->d->shaderCache.constEnd()) {
|
||||
d->cs = *cacheIt;
|
||||
} else {
|
||||
const QShader shader = m_shaderStage.shader();
|
||||
QString error;
|
||||
QByteArray entryPoint;
|
||||
id<MTLLibrary> lib = rhiD->d->createMetalLib(shader, m_shaderStage.shaderVariant(),
|
||||
&error, &entryPoint);
|
||||
if (!lib) {
|
||||
qWarning("MSL shader compilation failed: %s", qPrintable(error));
|
||||
return false;
|
||||
}
|
||||
id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
|
||||
if (!func) {
|
||||
qWarning("MSL function for entry point %s not found", entryPoint.constData());
|
||||
[lib release];
|
||||
return false;
|
||||
}
|
||||
d->cs.lib = lib;
|
||||
d->cs.func = func;
|
||||
d->cs.localSize = shader.description().computeShaderLocalSize();
|
||||
|
||||
if (rhiD->d->shaderCache.count() >= QRhiMetal::MAX_SHADER_CACHE_ENTRIES) {
|
||||
for (QMetalShader &s : rhiD->d->shaderCache)
|
||||
s.release();
|
||||
rhiD->d->shaderCache.clear();
|
||||
}
|
||||
rhiD->d->shaderCache.insert(m_shaderStage, d->cs);
|
||||
}
|
||||
id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
|
||||
if (!func) {
|
||||
qWarning("MSL function for entry point %s not found", entryPoint.constData());
|
||||
[lib release];
|
||||
return false;
|
||||
}
|
||||
d->csLib = lib;
|
||||
d->csFunc = func;
|
||||
std::array<uint, 3> localSize = shader.description().computeShaderLocalSize();
|
||||
d->localSize = MTLSizeMake(localSize[0], localSize[1], localSize[2]);
|
||||
|
||||
[d->cs.lib retain];
|
||||
[d->cs.func retain];
|
||||
|
||||
d->localSize = MTLSizeMake(d->cs.localSize[0], d->cs.localSize[1], d->cs.localSize[2]);
|
||||
|
||||
NSError *err = nil;
|
||||
d->ps = [rhiD->d->dev newComputePipelineStateWithFunction: d->csFunc error: &err];
|
||||
d->ps = [rhiD->d->dev newComputePipelineStateWithFunction: d->cs.func error: &err];
|
||||
if (!d->ps) {
|
||||
const QString msg = QString::fromNSString(err.localizedDescription);
|
||||
qWarning("Failed to create render pipeline state: %s", qPrintable(msg));
|
||||
|
|
|
|||
|
|
@ -417,6 +417,7 @@ public:
|
|||
const QRhiNativeHandles *nativeHandles() override;
|
||||
void sendVMemStatsToProfiler() override;
|
||||
void makeThreadLocalNativeContextCurrent() override;
|
||||
void releaseCachedResources() override;
|
||||
|
||||
void executeDeferredReleases(bool forced = false);
|
||||
void finishActiveReadbacks(bool forced = false);
|
||||
|
|
|
|||
|
|
@ -174,6 +174,11 @@ void QRhiNull::makeThreadLocalNativeContextCurrent()
|
|||
// nothing to do here
|
||||
}
|
||||
|
||||
void QRhiNull::releaseCachedResources()
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
QRhiRenderBuffer *QRhiNull::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@ public:
|
|||
const QRhiNativeHandles *nativeHandles() override;
|
||||
void sendVMemStatsToProfiler() override;
|
||||
void makeThreadLocalNativeContextCurrent() override;
|
||||
void releaseCachedResources() override;
|
||||
|
||||
QRhiNullNativeHandles nativeHandlesStruct;
|
||||
QRhiSwapChain *currentSwapChain = nullptr;
|
||||
|
|
|
|||
|
|
@ -3744,6 +3744,11 @@ void QRhiVulkan::makeThreadLocalNativeContextCurrent()
|
|||
// nothing to do here
|
||||
}
|
||||
|
||||
void QRhiVulkan::releaseCachedResources()
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
QRhiRenderBuffer *QRhiVulkan::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -712,6 +712,7 @@ public:
|
|||
const QRhiNativeHandles *nativeHandles() override;
|
||||
void sendVMemStatsToProfiler() override;
|
||||
void makeThreadLocalNativeContextCurrent() override;
|
||||
void releaseCachedResources() override;
|
||||
|
||||
VkResult createDescriptorPool(VkDescriptorPool *pool);
|
||||
bool allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, VkDescriptorSet *result, int *resultPoolIndex);
|
||||
|
|
|
|||
|
|
@ -2067,8 +2067,9 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
|
|||
\enum QTextDocument::ResourceType
|
||||
|
||||
This enum describes the types of resources that can be loaded by
|
||||
QTextDocument's loadResource() function.
|
||||
QTextDocument's loadResource() function or by QTextBrowser::setSource().
|
||||
|
||||
\value UnknownResource No resource is loaded, or the resource type is not known.
|
||||
\value HtmlResource The resource contains HTML.
|
||||
\value ImageResource The resource contains image data.
|
||||
Currently supported data types are QVariant::Pixmap and
|
||||
|
|
@ -2082,7 +2083,7 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
|
|||
\value UserResource The first available value for user defined
|
||||
resource types.
|
||||
|
||||
\sa loadResource()
|
||||
\sa loadResource(), QTextBrowser::sourceType()
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -399,6 +399,7 @@ struct QBidiAlgorithm {
|
|||
analysis[i].bidiDirection = (level & 1) ? QChar::DirR : QChar::DirL;
|
||||
runHasContent = true;
|
||||
lastRunWithContent = -1;
|
||||
++isolatePairPosition;
|
||||
}
|
||||
int runBeforeIsolate = runs.size();
|
||||
ushort newLevel = isRtl ? ((stack.top().level + 1) | 1) : ((stack.top().level + 2) & ~1);
|
||||
|
|
@ -440,21 +441,19 @@ struct QBidiAlgorithm {
|
|||
doEmbed(true, true, false);
|
||||
break;
|
||||
case QChar::DirLRI:
|
||||
Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
|
||||
doEmbed(false, false, true);
|
||||
++isolatePairPosition;
|
||||
break;
|
||||
case QChar::DirRLI:
|
||||
Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
|
||||
doEmbed(true, false, true);
|
||||
++isolatePairPosition;
|
||||
break;
|
||||
case QChar::DirFSI: {
|
||||
const auto &pair = isolatePairs.at(isolatePairPosition);
|
||||
Q_ASSERT(pair.start == i);
|
||||
bool isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft();
|
||||
bool isRtl = false;
|
||||
if (isolatePairPosition < isolatePairs.size()) {
|
||||
const auto &pair = isolatePairs.at(isolatePairPosition);
|
||||
Q_ASSERT(pair.start == i);
|
||||
isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft();
|
||||
}
|
||||
doEmbed(isRtl, false, true);
|
||||
++isolatePairPosition;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -650,6 +650,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
|
|||
\value TableColumns
|
||||
\value TableColumnWidthConstraints
|
||||
\value TableHeaderRowCount
|
||||
\value TableBorderCollapse Specifies the \l QTextTableFormat::borderCollapse property.
|
||||
|
||||
Table cell properties
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
/*!
|
||||
\class QHttp2Configuration
|
||||
\brief The QHttp2Configuration class controls HTTP/2 parameters and settings
|
||||
\brief The QHttp2Configuration class controls HTTP/2 parameters and settings.
|
||||
\since 5.14
|
||||
|
||||
\reentrant
|
||||
|
|
|
|||
|
|
@ -854,8 +854,11 @@ void QHttpNetworkConnectionChannel::_q_disconnected()
|
|||
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
|
||||
}
|
||||
state = QHttpNetworkConnectionChannel::IdleState;
|
||||
|
||||
requeueCurrentlyPipelinedRequests();
|
||||
if (alreadyPipelinedRequests.length()) {
|
||||
// If nothing was in a pipeline, no need in calling
|
||||
// _q_startNextRequest (which it does):
|
||||
requeueCurrentlyPipelinedRequests();
|
||||
}
|
||||
|
||||
pendingEncrypt = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1512,7 +1512,7 @@ bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFor
|
|||
SSL socket's CA certificate database is initialized to the default
|
||||
CA certificate database.
|
||||
|
||||
\sa QSslConfiguration::defaultCaCertificates(), addCaCertificates()
|
||||
\sa QSslConfiguration::caCertificates(), addCaCertificates()
|
||||
*/
|
||||
void QSslSocket::addDefaultCaCertificate(const QSslCertificate &certificate)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1360,6 +1360,18 @@ void QSslSocketBackendPrivate::transmit()
|
|||
#endif
|
||||
schannelState = SchannelState::Renegotiate;
|
||||
renegotiating = true;
|
||||
|
||||
if (dataBuffer[3].BufferType == SECBUFFER_EXTRA) {
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel
|
||||
// dataBuffer[3].cbBuffer indicates the amount of bytes _NOT_ processed,
|
||||
// the rest need to be stored.
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl) << "We've got excess data, moving it to the intermediate buffer:"
|
||||
<< dataBuffer[3].cbBuffer << "bytes";
|
||||
#endif
|
||||
intermediateBuffer = ciphertext.right(int(dataBuffer[3].cbBuffer));
|
||||
}
|
||||
|
||||
// We need to call 'continueHandshake' or else there's no guarantee it ever gets called
|
||||
continueHandshake();
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -535,7 +535,7 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
|
|||
m_currentData.state = Qt::TouchPointReleased;
|
||||
if (m_typeB)
|
||||
m_contacts[m_currentSlot].maj = m_currentData.maj;
|
||||
} else if (data->code == ABS_PRESSURE) {
|
||||
} else if (data->code == ABS_PRESSURE || data->code == ABS_MT_PRESSURE) {
|
||||
m_currentData.pressure = qBound(hw_pressure_min, data->value, hw_pressure_max);
|
||||
if (m_typeB || m_singleTouch)
|
||||
m_contacts[m_currentSlot].pressure = m_currentData.pressure;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "qwindowswindow.h"
|
||||
#include "qwindowsintegration.h"
|
||||
#include "qwindowscursor.h"
|
||||
#include "qwindowstheme.h"
|
||||
|
||||
#include <QtCore/qt_windows.h>
|
||||
|
||||
|
|
@ -543,10 +544,13 @@ bool QWindowsScreenManager::handleScreenChanges()
|
|||
// Look for changed monitors, add new ones
|
||||
const WindowsScreenDataList newDataList = monitorData();
|
||||
const bool lockScreen = newDataList.size() == 1 && (newDataList.front().flags & QWindowsScreenData::LockScreen);
|
||||
bool primaryScreenChanged = false;
|
||||
for (const QWindowsScreenData &newData : newDataList) {
|
||||
const int existingIndex = indexOfMonitor(m_screens, newData.name);
|
||||
if (existingIndex != -1) {
|
||||
m_screens.at(existingIndex)->handleChanges(newData);
|
||||
if (existingIndex == 0)
|
||||
primaryScreenChanged = true;
|
||||
} else {
|
||||
auto *newScreen = new QWindowsScreen(newData);
|
||||
m_screens.push_back(newScreen);
|
||||
|
|
@ -563,6 +567,8 @@ bool QWindowsScreenManager::handleScreenChanges()
|
|||
removeScreen(i);
|
||||
} // for existing screens
|
||||
} // not lock screen
|
||||
if (primaryScreenChanged)
|
||||
QWindowsTheme::instance()->refreshFonts();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ public:
|
|||
|
||||
static bool useNativeMenus();
|
||||
|
||||
void refreshFonts();
|
||||
|
||||
static const char *name;
|
||||
|
||||
private:
|
||||
|
|
@ -92,7 +94,6 @@ private:
|
|||
void clearPalettes();
|
||||
void refreshPalettes();
|
||||
void clearFonts();
|
||||
void refreshFonts();
|
||||
void refreshIconPixmapSizes();
|
||||
|
||||
static QWindowsTheme *m_instance;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -105,19 +107,17 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_ContainingGrid(IIRawEle
|
|||
*value = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
|
||||
auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
|
||||
auto elementId = std::make_shared<QAccessible::Id>(0);
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
|
||||
if (QAccessibleInterface *table = tableCellInterface->table()) {
|
||||
**ptrElementId = idForAccessible(table);
|
||||
QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
|
||||
*elementId = idForAccessible(table);
|
||||
QWinRTUiaMetadataCache::instance()->load(*elementId);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementId;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -104,21 +106,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaGridProvider::GetItem(INT32 row, INT32 column
|
|||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
|
||||
auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
|
||||
auto elementId = std::make_shared<QAccessible::Id>(0);
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, row, column, ptrElementId]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, row, column, elementId]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
|
||||
if ((row >= 0) && (row < tableInterface->rowCount()) && (column >= 0) && (column < tableInterface->columnCount())) {
|
||||
if (QAccessibleInterface *cell = tableInterface->cellAt(row, column)) {
|
||||
**ptrElementId = idForAccessible(cell);
|
||||
QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
|
||||
*elementId = idForAccessible(cell);
|
||||
QWinRTUiaMetadataCache::instance()->load(*elementId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementId;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@
|
|||
#include <QtCore/qfunctions_winrt.h>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
|
|
@ -179,7 +181,7 @@ HRESULT QWinRTUiaMainProvider::rawProviderForAccessibleId(QAccessible::Id elemen
|
|||
}
|
||||
|
||||
// Returns an array of IIRawElementProviderSimple instances for a list of accessible interface ids.
|
||||
HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds,
|
||||
HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QVarLengthArray<QAccessible::Id> &elementIds,
|
||||
UINT32 *returnValueSize,
|
||||
IIRawElementProviderSimple ***returnValue)
|
||||
{
|
||||
|
|
@ -190,7 +192,7 @@ HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QList<Q
|
|||
|
||||
QList<IIRawElementProviderSimple *> rawProviderList;
|
||||
|
||||
for (auto elementId : qAsConst(elementIds)) {
|
||||
for (auto elementId : elementIds) {
|
||||
IIRawElementProviderSimple *rawProvider;
|
||||
if (SUCCEEDED(rawProviderForAccessibleId(elementId, &rawProvider)))
|
||||
rawProviderList.append(rawProvider);
|
||||
|
|
@ -515,10 +517,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
|
|||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto children = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
|
||||
auto ptrChildren = new QSharedPointer<QList<QAccessible::Id>>(children);
|
||||
auto children = std::make_shared<QVarLengthArray<QAccessible::Id>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrChildren]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, children]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
int childCount = accessible->childCount();
|
||||
for (int i = 0; i < childCount; ++i) {
|
||||
|
|
@ -526,11 +527,10 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
|
|||
QAccessible::Id childId = idForAccessible(childAcc);
|
||||
QWinRTUiaMetadataCache::instance()->load(childId);
|
||||
if (!childAcc->state().invisible)
|
||||
(*ptrChildren)->append(childId);
|
||||
children->append(childId);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrChildren;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
@ -538,7 +538,7 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
|
|||
|
||||
ComPtr<IVector<AutomationPeer *>> peerVector = Make<QWinRTUiaPeerVector>();
|
||||
|
||||
for (auto childId : qAsConst(*children)) {
|
||||
for (auto childId : *children) {
|
||||
if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(childId)) {
|
||||
IAutomationPeer *peer;
|
||||
if (SUCCEEDED(provider.CopyTo(&peer)))
|
||||
|
|
@ -750,10 +750,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPeerFromPointCore(ABI::Windo
|
|||
// Scale coordinates from High DPI screens?
|
||||
|
||||
auto accid = id();
|
||||
auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
|
||||
auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
|
||||
auto elementId = std::make_shared<QAccessible::Id>(0);
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId, point]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId, point]() {
|
||||
// Controls can be embedded within grouping elements. By default returns the innermost control.
|
||||
QAccessibleInterface *target = accessibleForId(accid);
|
||||
while (QAccessibleInterface *tmpacc = target->childAt(point.X, point.Y)) {
|
||||
|
|
@ -761,9 +760,8 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPeerFromPointCore(ABI::Windo
|
|||
// For accessibility tools it may be better to return the text element instead of its subcomponents.
|
||||
if (target->textInterface()) break;
|
||||
}
|
||||
**ptrElementId = idForAccessible(target);
|
||||
QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
|
||||
delete ptrElementId;
|
||||
*elementId = idForAccessible(target);
|
||||
QWinRTUiaMetadataCache::instance()->load(*elementId);
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public:
|
|||
virtual ~QWinRTUiaMainProvider();
|
||||
static QWinRTUiaMainProvider *providerForAccessibleId(QAccessible::Id id);
|
||||
static HRESULT rawProviderForAccessibleId(QAccessible::Id elementId, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **returnValue);
|
||||
static HRESULT rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds, UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue);
|
||||
static HRESULT rawProviderArrayForAccessibleIdList(const QVarLengthArray<QAccessible::Id> &elementIds, UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue);
|
||||
static void notifyFocusChange(QAccessibleEvent *event);
|
||||
static void notifyVisibilityChange(QAccessibleEvent *event);
|
||||
static void notifyStateChange(QAccessibleStateChangeEvent *event);
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -94,21 +96,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::get_SelectionContainer
|
|||
*value = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
|
||||
auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
|
||||
auto elementId = std::make_shared<QAccessible::Id>(0);
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
// Radio buttons do not require a container.
|
||||
if (accessible->role() == QAccessible::ListItem) {
|
||||
if (QAccessibleInterface *parent = accessible->parent()) {
|
||||
if (parent->role() == QAccessible::List) {
|
||||
**ptrElementId = idForAccessible(parent);
|
||||
*elementId = idForAccessible(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementId;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -89,10 +91,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_IsSelectionRequired(bo
|
|||
*value = false;
|
||||
|
||||
auto accid = id();
|
||||
auto selectionRequired = QSharedPointer<bool>(new bool(false));
|
||||
auto ptrSelectionRequired = new QSharedPointer<bool>(selectionRequired);
|
||||
auto selectionRequired = std::make_shared<bool>(false);
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelectionRequired]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, selectionRequired]() {
|
||||
// Initially returns false if none are selected. After the first selection, it may be required.
|
||||
bool anySelected = false;
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
|
|
@ -105,9 +106,8 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_IsSelectionRequired(bo
|
|||
}
|
||||
}
|
||||
}
|
||||
**ptrSelectionRequired = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
|
||||
*selectionRequired = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
|
||||
}
|
||||
delete ptrSelectionRequired;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
@ -128,10 +128,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::GetSelection(UINT32 *retur
|
|||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
|
||||
auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
|
||||
auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
int childCount = accessible->childCount();
|
||||
for (int i = 0; i < childCount; ++i) {
|
||||
|
|
@ -139,12 +138,11 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::GetSelection(UINT32 *retur
|
|||
if (childAcc->state().selected) {
|
||||
QAccessible::Id childId = idForAccessible(childAcc);
|
||||
QWinRTUiaMetadataCache::instance()->load(childId);
|
||||
(*ptrElementIds)->append(childId);
|
||||
elementIds->append(childId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementIds;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -79,21 +81,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetColumnHeaderItems(UINT3
|
|||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
|
||||
auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
|
||||
auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
|
||||
QList<QAccessibleInterface *> headers = tableCellInterface->columnHeaderCells();
|
||||
for (auto header : qAsConst(headers)) {
|
||||
QAccessible::Id headerId = idForAccessible(header);
|
||||
QWinRTUiaMetadataCache::instance()->load(headerId);
|
||||
(*ptrElementIds)->append(headerId);
|
||||
elementIds->append(headerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementIds;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
@ -113,21 +113,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetRowHeaderItems(UINT32 *
|
|||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
|
||||
auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
|
||||
auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
|
||||
QList<QAccessibleInterface *> headers = tableCellInterface->rowHeaderCells();
|
||||
for (auto header : qAsConst(headers)) {
|
||||
QAccessible::Id headerId = idForAccessible(header);
|
||||
QWinRTUiaMetadataCache::instance()->load(headerId);
|
||||
(*ptrElementIds)->append(headerId);
|
||||
elementIds->append(headerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementIds;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -91,10 +93,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetColumnHeaders(UINT32 *retur
|
|||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
|
||||
auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
|
||||
auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
|
||||
for (int i = 0; i < tableInterface->columnCount(); ++i) {
|
||||
|
|
@ -105,14 +106,13 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetColumnHeaders(UINT32 *retur
|
|||
for (auto header : qAsConst(headers)) {
|
||||
QAccessible::Id headerId = idForAccessible(header);
|
||||
QWinRTUiaMetadataCache::instance()->load(headerId);
|
||||
(*ptrElementIds)->append(headerId);
|
||||
elementIds->append(headerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementIds;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
@ -132,10 +132,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetRowHeaders(UINT32 *returnVa
|
|||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
|
||||
auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
|
||||
auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
|
||||
for (int i = 0; i < tableInterface->rowCount(); ++i) {
|
||||
|
|
@ -146,14 +145,13 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetRowHeaders(UINT32 *returnVa
|
|||
for (auto header : qAsConst(headers)) {
|
||||
QAccessible::Id headerId = idForAccessible(header);
|
||||
QWinRTUiaMetadataCache::instance()->load(headerId);
|
||||
(*ptrElementIds)->append(headerId);
|
||||
elementIds->append(headerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrElementIds;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -104,26 +106,26 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetSelection(UINT32 *returnValu
|
|||
*returnValueSize = 0;
|
||||
*returnValue = nullptr;
|
||||
|
||||
auto accid = id();
|
||||
auto selections = QSharedPointer<QList<QPair<int,int>>>(new QList<QPair<int,int>>);
|
||||
auto ptrSelections = new QSharedPointer<QList<QPair<int,int>>>(selections);
|
||||
struct Selection { int startOffset, endOffset; };
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelections]() {
|
||||
auto accid = id();
|
||||
auto selections = std::make_shared<QVarLengthArray<Selection>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, selections]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
|
||||
for (int i = 0; i < textInterface->selectionCount(); ++i) {
|
||||
QPair<int,int> sel;
|
||||
textInterface->selection(i, &sel.first, &sel.second);
|
||||
(*ptrSelections)->append(sel);
|
||||
int startOffset, endOffset;
|
||||
textInterface->selection(i, &startOffset, &endOffset);
|
||||
selections->append({startOffset, endOffset});
|
||||
}
|
||||
if ((*ptrSelections)->size() == 0) {
|
||||
if (selections->size() == 0) {
|
||||
// If there is no selection, we return an array with a single degenerate (empty) text range at the cursor position.
|
||||
QPair<int,int> sel(textInterface->cursorPosition(), textInterface->cursorPosition());
|
||||
(*ptrSelections)->append(sel);
|
||||
auto cur = textInterface->cursorPosition();
|
||||
selections->append({cur, cur});
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ptrSelections;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
@ -137,9 +139,11 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetSelection(UINT32 *returnValu
|
|||
if (!providerArray)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
for (int i = 0; i < selCount; ++i) {
|
||||
ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), (*selections)[i].first, (*selections)[i].second);
|
||||
textRangeProvider.CopyTo(&providerArray[i]);
|
||||
auto dst = providerArray;
|
||||
for (auto sel : *selections) {
|
||||
ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider
|
||||
= Make<QWinRTUiaTextRangeProvider>(id(), sel.startOffset, sel.endOffset);
|
||||
textRangeProvider.CopyTo(dst++);
|
||||
}
|
||||
*returnValueSize = selCount;
|
||||
*returnValue = providerArray;
|
||||
|
|
@ -184,14 +188,12 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::RangeFromPoint(ABI::Windows::Fo
|
|||
|
||||
const QPoint pt(screenLocation.X, screenLocation.Y);
|
||||
auto accid = id();
|
||||
auto offset = QSharedPointer<int>(new int);
|
||||
auto ptrOffset = new QSharedPointer<int>(offset);
|
||||
auto offset = std::make_shared<int>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, pt, ptrOffset]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, pt, offset]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid))
|
||||
if (QAccessibleTextInterface *textInterface = accessible->textInterface())
|
||||
**ptrOffset = qBound(0, textInterface->offsetAtPoint(pt), textInterface->characterCount() - 1);
|
||||
delete ptrOffset;
|
||||
*offset = qBound(0, textInterface->offsetAtPoint(pt), textInterface->characterCount() - 1);
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QWinRTUiAutomation;
|
||||
|
|
@ -212,10 +214,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
|
|||
auto accid = id();
|
||||
auto startOffset = m_startOffset;
|
||||
auto endOffset = m_endOffset;
|
||||
auto rects = QSharedPointer<QList<QRect>>(new QList<QRect>);
|
||||
auto ptrRects = new QSharedPointer<QList<QRect>>(rects);
|
||||
auto rects = std::make_shared<QVarLengthArray<QRect>>();
|
||||
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset, ptrRects]() {
|
||||
if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset, rects]() {
|
||||
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
|
||||
if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
|
||||
int len = textInterface->characterCount();
|
||||
|
|
@ -233,7 +234,7 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
|
|||
qMin(startRect.y(), endRect.y()),
|
||||
qMax(startRect.x() + startRect.width(), endRect.x() + endRect.width()) - qMin(startRect.x(), endRect.x()),
|
||||
qMax(startRect.y() + startRect.height(), endRect.y() + endRect.height()) - qMin(startRect.y(), endRect.y()));
|
||||
(*ptrRects)->append(lineRect);
|
||||
rects->append(lineRect);
|
||||
}
|
||||
if (end >= len) break;
|
||||
textInterface->textAfterOffset(end + 1, QAccessible::LineBoundary, &start, &end);
|
||||
|
|
@ -241,7 +242,6 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
|
|||
}
|
||||
}
|
||||
}
|
||||
delete ptrRects;
|
||||
return S_OK;
|
||||
}))) {
|
||||
return E_FAIL;
|
||||
|
|
@ -251,11 +251,12 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
|
|||
if (!doubleArray)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
for (int i = 0; i < rects->size(); ++i) {
|
||||
doubleArray[i*4] = (*rects)[i].left();
|
||||
doubleArray[i*4+1] = (*rects)[i].top();
|
||||
doubleArray[i*4+2] = (*rects)[i].width();
|
||||
doubleArray[i*4+3] = (*rects)[i].height();
|
||||
DOUBLE *dst = doubleArray;
|
||||
for (auto rect : *rects) {
|
||||
*dst++ = rect.left();
|
||||
*dst++ = rect.top();
|
||||
*dst++ = rect.width();
|
||||
*dst++ = rect.height();
|
||||
}
|
||||
*returnValue = doubleArray;
|
||||
*returnValueSize = 4 * rects->size();
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@
|
|||
#ifdef Q_OS_WIN
|
||||
# include <QtCore/QVarLengthArray>
|
||||
# include <qt_windows.h>
|
||||
# ifndef Q_OS_WINRT
|
||||
# include <shlobj.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
|
@ -837,8 +840,8 @@ QString QFileSystemModelPrivate::displayName(const QModelIndex &index) const
|
|||
{
|
||||
#if defined(Q_OS_WIN)
|
||||
QFileSystemNode *dirNode = node(index);
|
||||
if (!dirNode->volumeName.isNull())
|
||||
return dirNode->volumeName + QLatin1String(" (") + name(index) + QLatin1Char(')');
|
||||
if (!dirNode->volumeName.isEmpty())
|
||||
return dirNode->volumeName;
|
||||
#endif
|
||||
return name(index);
|
||||
}
|
||||
|
|
@ -1773,6 +1776,27 @@ void QFileSystemModelPrivate::_q_directoryChanged(const QString &directory, cons
|
|||
removeNode(parentNode, toRemove[i]);
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
||||
static QString volumeName(const QString &path)
|
||||
{
|
||||
IShellItem *item = nullptr;
|
||||
const QString native = QDir::toNativeSeparators(path);
|
||||
HRESULT hr = SHCreateItemFromParsingName(reinterpret_cast<const wchar_t *>(native.utf16()),
|
||||
nullptr, IID_IShellItem,
|
||||
reinterpret_cast<void **>(&item));
|
||||
if (FAILED(hr))
|
||||
return QString();
|
||||
LPWSTR name = nullptr;
|
||||
hr = item->GetDisplayName(SIGDN_NORMALDISPLAY, &name);
|
||||
if (FAILED(hr))
|
||||
return QString();
|
||||
QString result = QString::fromWCharArray(name);
|
||||
CoTaskMemFree(name);
|
||||
item->Release();
|
||||
return result;
|
||||
}
|
||||
#endif // Q_OS_WIN && !Q_OS_WINRT
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
|
|
@ -1791,15 +1815,8 @@ QFileSystemModelPrivate::QFileSystemNode* QFileSystemModelPrivate::addNode(QFile
|
|||
#endif
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
||||
//The parentNode is "" so we are listing the drives
|
||||
if (parentNode->fileName.isEmpty()) {
|
||||
wchar_t name[MAX_PATH + 1];
|
||||
//GetVolumeInformation requires to add trailing backslash
|
||||
const QString nodeName = fileName + QLatin1String("\\");
|
||||
BOOL success = ::GetVolumeInformation((wchar_t *)(nodeName.utf16()),
|
||||
name, MAX_PATH + 1, NULL, 0, NULL, NULL, 0);
|
||||
if (success && name[0])
|
||||
node->volumeName = QString::fromWCharArray(name);
|
||||
}
|
||||
if (parentNode->fileName.isEmpty())
|
||||
node->volumeName = volumeName(fileName);
|
||||
#endif
|
||||
Q_ASSERT(!parentNode->children.contains(fileName));
|
||||
parentNode->children.insert(fileName, node);
|
||||
|
|
|
|||
|
|
@ -659,24 +659,22 @@ int QShortcut::id() const
|
|||
bool QShortcut::event(QEvent *e)
|
||||
{
|
||||
Q_D(QShortcut);
|
||||
bool handled = false;
|
||||
if (d->sc_enabled && e->type() == QEvent::Shortcut) {
|
||||
auto se = static_cast<QShortcutEvent *>(e);
|
||||
if (se->shortcutId() == d->sc_id && se->key() == d->sc_sequence){
|
||||
#if QT_CONFIG(whatsthis)
|
||||
if (QWhatsThis::inWhatsThisMode()) {
|
||||
QWhatsThis::showText(QCursor::pos(), d->sc_whatsthis);
|
||||
handled = true;
|
||||
} else
|
||||
#endif
|
||||
if (se->isAmbiguous())
|
||||
emit activatedAmbiguously();
|
||||
else
|
||||
emit activated();
|
||||
handled = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return handled;
|
||||
return QObject::event(e);
|
||||
}
|
||||
#endif // QT_NO_SHORTCUT
|
||||
|
||||
|
|
|
|||
|
|
@ -1760,7 +1760,7 @@ QStyleOptionMenuItem::QStyleOptionMenuItem(int version)
|
|||
\value Exclusive The item is an exclusive check item (like a radio button).
|
||||
\value NonExclusive The item is a non-exclusive check item (like a check box).
|
||||
|
||||
\sa checkType, QAction::checkable, QAction::checked, QActionGroup::exclusive
|
||||
\sa checkType, QAction::checkable, QAction::checked, QActionGroup::exclusionPolicy
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -862,6 +862,16 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
|
|||
when the choice is not changed. If you need to know when the
|
||||
choice actually changes, use signal currentIndexChanged().
|
||||
|
||||
\obsolete Use QComboBox::textActivated() instead
|
||||
*/
|
||||
/*!
|
||||
\fn void QComboBox::textActivated(const QString &text)
|
||||
\since 5.14
|
||||
|
||||
This signal is sent when the user chooses an item in the combobox.
|
||||
The item's \a text is passed. Note that this signal is sent even
|
||||
when the choice is not changed. If you need to know when the
|
||||
choice actually changes, use signal currentIndexChanged().
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
@ -876,6 +886,15 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
|
|||
|
||||
This signal is sent when an item in the combobox popup list is
|
||||
highlighted by the user. The item's \a text is passed.
|
||||
|
||||
\obsolete Use textHighlighted() instead
|
||||
*/
|
||||
/*!
|
||||
\fn void QComboBox::textHighlighted(const QString &text)
|
||||
\since 5.14
|
||||
|
||||
This signal is sent when an item in the combobox popup list is
|
||||
highlighted by the user. The item's \a text is passed.
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
@ -888,7 +907,6 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
|
|||
currentIndex was reset.
|
||||
*/
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
/*!
|
||||
\fn void QComboBox::currentIndexChanged(const QString &text)
|
||||
\since 4.1
|
||||
|
|
@ -897,7 +915,6 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
|
|||
changes either through user interaction or programmatically. The
|
||||
item's \a text is passed.
|
||||
*/
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\fn void QComboBox::currentTextChanged(const QString &text)
|
||||
|
|
|
|||
|
|
@ -2332,14 +2332,17 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
|
|||
// However if the QMenu was constructed with a QDesktopScreenWidget as its parent,
|
||||
// then initialScreenIndex was set, so we should respect that for the lifetime of this menu.
|
||||
// Use d->popupScreen to remember, because initialScreenIndex will be reset after the first showing.
|
||||
const int screenIndex = d->topData()->initialScreenIndex;
|
||||
if (screenIndex >= 0)
|
||||
d->popupScreen = screenIndex;
|
||||
if (auto s = QGuiApplication::screens().value(d->popupScreen)) {
|
||||
if (d->setScreen(s))
|
||||
// However if eventLoop exists, then exec() already did this by calling createWinId(); so leave it alone. (QTBUG-76162)
|
||||
if (!d->eventLoop) {
|
||||
const int screenIndex = d->topData()->initialScreenIndex;
|
||||
if (screenIndex >= 0)
|
||||
d->popupScreen = screenIndex;
|
||||
if (auto s = QGuiApplication::screens().value(d->popupScreen)) {
|
||||
if (d->setScreen(s))
|
||||
d->itemsDirty = true;
|
||||
} else if (d->setScreenForPoint(p)) {
|
||||
d->itemsDirty = true;
|
||||
} else if (d->setScreenForPoint(p)) {
|
||||
d->itemsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
const bool contextMenu = d->isContextMenu();
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ private slots:
|
|||
void superscriptCrash_qtbug53911();
|
||||
void showLineAndParagraphSeparatorsCrash();
|
||||
void koreanWordWrap();
|
||||
void tooManyDirectionalCharctersCrash_qtbug77819();
|
||||
|
||||
private:
|
||||
QFont testFont;
|
||||
|
|
@ -2330,5 +2331,21 @@ void tst_QTextLayout::koreanWordWrap()
|
|||
QCOMPARE(layout.lineAt(1).textLength(), 4);
|
||||
}
|
||||
|
||||
void tst_QTextLayout::tooManyDirectionalCharctersCrash_qtbug77819()
|
||||
{
|
||||
QString data;
|
||||
data += QString::fromUtf8("\xe2\x81\xa8"); // U+2068 FSI character
|
||||
data += QString::fromUtf8("\xe2\x81\xa7"); // U+2067 RLI character
|
||||
|
||||
// duplicating the text
|
||||
for (int i = 0; i < 10; i++)
|
||||
data += data;
|
||||
|
||||
// Nothing to test. It must not crash in beginLayout().
|
||||
QTextLayout tl(data);
|
||||
tl.beginLayout();
|
||||
tl.endLayout();
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QTextLayout)
|
||||
#include "tst_qtextlayout.moc"
|
||||
|
|
|
|||
|
|
@ -477,6 +477,9 @@ void tst_Http2::goaway_data()
|
|||
// - server waits for some time (enough for ur to init several streams on a
|
||||
// client side); then suddenly it replies with GOAWAY, never processing any
|
||||
// request.
|
||||
if (clearTextHTTP2)
|
||||
QSKIP("This test requires TLS with ALPN to work");
|
||||
|
||||
QTest::addColumn<int>("responseTimeoutMS");
|
||||
QTest::newRow("ImmediateGOAWAY") << 0;
|
||||
QTest::newRow("DelayedGOAWAY") << 1000;
|
||||
|
|
|
|||
|
|
@ -1010,7 +1010,10 @@ void PaintCommands::command_drawPixmap(QRegularExpressionMatch re)
|
|||
qPrintable(re.captured(1)), pm.width(), pm.height(), pm.depth(),
|
||||
tx, ty, tw, th, sx, sy, sw, sh);
|
||||
|
||||
m_painter->drawPixmap(QRectF(tx, ty, tw, th), pm, QRectF(sx, sy, sw, sh));
|
||||
if (!re.capturedLength(4)) // at most two coordinates specified
|
||||
m_painter->drawPixmap(QPointF(tx, ty), pm);
|
||||
else
|
||||
m_painter->drawPixmap(QRectF(tx, ty, tw, th), pm, QRectF(sx, sy, sw, sh));
|
||||
}
|
||||
|
||||
/***************************************************************************************************/
|
||||
|
|
@ -1057,7 +1060,10 @@ void PaintCommands::command_drawImage(QRegularExpressionMatch re)
|
|||
printf(" -(lance) drawImage('%s' dim=(%d, %d), (%f, %f, %f, %f), (%f, %f, %f, %f)\n",
|
||||
qPrintable(re.captured(1)), im.width(), im.height(), tx, ty, tw, th, sx, sy, sw, sh);
|
||||
|
||||
m_painter->drawImage(QRectF(tx, ty, tw, th), im, QRectF(sx, sy, sw, sh), Qt::OrderedDither | Qt::OrderedAlphaDither);
|
||||
if (!re.capturedLength(4)) // at most two coordinates specified
|
||||
m_painter->drawImage(QPointF(tx, ty), im);
|
||||
else
|
||||
m_painter->drawImage(QRectF(tx, ty, tw, th), im, QRectF(sx, sy, sw, sh));
|
||||
}
|
||||
|
||||
/***************************************************************************************************/
|
||||
|
|
|
|||
|
|
@ -26,15 +26,12 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <qeventloop.h>
|
||||
#include <qlist.h>
|
||||
#include <qpair.h>
|
||||
#include <qheaderview.h>
|
||||
#include <qlineedit.h>
|
||||
|
||||
#include <qtablewidget.h>
|
||||
#include <QHeaderView>
|
||||
#include <QLineEdit>
|
||||
#include <QMimeData>
|
||||
#include <QSignalSpy>
|
||||
#include <QTableWidget>
|
||||
#include <QTest>
|
||||
|
||||
class QObjectTableItem : public QObject, public QTableWidgetItem
|
||||
{
|
||||
|
|
@ -46,11 +43,10 @@ class tst_QTableWidget : public QObject
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QTableWidget();
|
||||
using QObject::QObject;
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
void init();
|
||||
void getSetCheck();
|
||||
void clear();
|
||||
|
|
@ -97,12 +93,12 @@ private slots:
|
|||
#endif
|
||||
|
||||
private:
|
||||
QTableWidget *testWidget;
|
||||
std::unique_ptr<QTableWidget> testWidget;
|
||||
};
|
||||
|
||||
typedef QPair<int, int> IntPair;
|
||||
typedef QList<int> IntList;
|
||||
typedef QList<IntPair> IntIntList;
|
||||
using IntPair = QPair<int, int>;
|
||||
using IntList = QVector<int>;
|
||||
using IntIntList = QVector<IntPair>;
|
||||
|
||||
Q_DECLARE_METATYPE(QTableWidgetSelectionRange)
|
||||
|
||||
|
|
@ -143,45 +139,36 @@ void tst_QTableWidget::getSetCheck()
|
|||
obj1.setItem(3, 3, new QTableWidgetItem("3,3"));
|
||||
obj1.setCurrentItem(var3);
|
||||
QCOMPARE(var3, obj1.currentItem());
|
||||
obj1.setCurrentItem((QTableWidgetItem *)0);
|
||||
QCOMPARE((QTableWidgetItem *)0, obj1.currentItem());
|
||||
obj1.setItem(0, 0, 0);
|
||||
QCOMPARE((QTableWidgetItem *)0, obj1.item(0, 0));
|
||||
obj1.setCurrentItem(nullptr);
|
||||
QCOMPARE(obj1.currentItem(), nullptr);
|
||||
obj1.setItem(0, 0, nullptr);
|
||||
QCOMPARE(obj1.item(0, 0), nullptr);
|
||||
|
||||
// const QTableWidgetItem * QTableWidget::itemPrototype()
|
||||
// void QTableWidget::setItemPrototype(const QTableWidgetItem *)
|
||||
const QTableWidgetItem *var4 = new QTableWidgetItem;
|
||||
obj1.setItemPrototype(var4);
|
||||
QCOMPARE(var4, obj1.itemPrototype());
|
||||
obj1.setItemPrototype((QTableWidgetItem *)0);
|
||||
QCOMPARE((const QTableWidgetItem *)0, obj1.itemPrototype());
|
||||
}
|
||||
|
||||
tst_QTableWidget::tst_QTableWidget(): testWidget(0)
|
||||
{
|
||||
obj1.setItemPrototype(nullptr);
|
||||
QCOMPARE(obj1.itemPrototype(), nullptr);
|
||||
}
|
||||
|
||||
void tst_QTableWidget::initTestCase()
|
||||
{
|
||||
testWidget = new QTableWidget();
|
||||
testWidget.reset(new QTableWidget);
|
||||
testWidget->show();
|
||||
QApplication::setKeyboardInputInterval(100);
|
||||
}
|
||||
|
||||
void tst_QTableWidget::cleanupTestCase()
|
||||
{
|
||||
delete testWidget;
|
||||
}
|
||||
|
||||
void tst_QTableWidget::init()
|
||||
{
|
||||
testWidget->clear();
|
||||
testWidget->setRowCount(5);
|
||||
testWidget->setColumnCount(5);
|
||||
|
||||
for (int row=0; row < testWidget->rowCount(); ++row)
|
||||
for (int row = 0; row < testWidget->rowCount(); ++row)
|
||||
testWidget->showRow(row);
|
||||
for (int column=0; column < testWidget->columnCount(); ++column)
|
||||
for (int column = 0; column < testWidget->columnCount(); ++column)
|
||||
testWidget->showColumn(column);
|
||||
}
|
||||
|
||||
|
|
@ -319,13 +306,15 @@ void tst_QTableWidget::item()
|
|||
QCOMPARE(testWidget->rowCount(), rowCount);
|
||||
QCOMPARE(testWidget->columnCount(), columnCount);
|
||||
|
||||
for (int r = 0; r < testWidget->rowCount(); ++r)
|
||||
for (int r = 0; r < testWidget->rowCount(); ++r) {
|
||||
for (int c = 0; c < testWidget->columnCount(); ++c)
|
||||
testWidget->setItem(r, c, new QTableWidgetItem(QString::number(r * c + c)));
|
||||
}
|
||||
|
||||
for (int r = 0; r < testWidget->rowCount(); ++r)
|
||||
for (int r = 0; r < testWidget->rowCount(); ++r) {
|
||||
for (int c = 0; c < testWidget->columnCount(); ++c)
|
||||
QCOMPARE(testWidget->item(r, c)->text(), QString::number(r * c + c));
|
||||
}
|
||||
|
||||
QTableWidgetItem *item = testWidget->item(row, column);
|
||||
QCOMPARE(!!item, expectItem);
|
||||
|
|
@ -361,15 +350,17 @@ void tst_QTableWidget::takeItem()
|
|||
QCOMPARE(testWidget->rowCount(), rowCount);
|
||||
QCOMPARE(testWidget->columnCount(), columnCount);
|
||||
|
||||
for (int r = 0; r < testWidget->rowCount(); ++r)
|
||||
for (int r = 0; r < testWidget->rowCount(); ++r) {
|
||||
for (int c = 0; c < testWidget->columnCount(); ++c)
|
||||
testWidget->setItem(r, c, new QTableWidgetItem(QString::number(r * c + c)));
|
||||
}
|
||||
|
||||
for (int r = 0; r < testWidget->rowCount(); ++r)
|
||||
for (int r = 0; r < testWidget->rowCount(); ++r) {
|
||||
for (int c = 0; c < testWidget->columnCount(); ++c)
|
||||
QCOMPARE(testWidget->item(r, c)->text(), QString::number(r * c + c));
|
||||
}
|
||||
|
||||
QSignalSpy spy(testWidget, &QTableWidget::cellChanged);
|
||||
QSignalSpy spy(testWidget.get(), &QTableWidget::cellChanged);
|
||||
QTableWidgetItem *item = testWidget->takeItem(row, column);
|
||||
QCOMPARE(!!item, expectItem);
|
||||
if (expectItem) {
|
||||
|
|
@ -516,11 +507,11 @@ void tst_QTableWidget::selectedItems()
|
|||
{
|
||||
QFETCH(int, rowCount);
|
||||
QFETCH(int, columnCount);
|
||||
QFETCH(IntIntList, createItems);
|
||||
QFETCH(IntList, hiddenRows);
|
||||
QFETCH(IntList, hiddenColumns);
|
||||
QFETCH(QTableWidgetSelectionRange, selectionRange);
|
||||
QFETCH(IntIntList, expectedItems);
|
||||
QFETCH(const IntIntList, createItems);
|
||||
QFETCH(const IntList, hiddenRows);
|
||||
QFETCH(const IntList, hiddenColumns);
|
||||
QFETCH(const QTableWidgetSelectionRange, selectionRange);
|
||||
QFETCH(const IntIntList, expectedItems);
|
||||
|
||||
// set dimensions and test they are ok
|
||||
testWidget->setRowCount(rowCount);
|
||||
|
|
@ -529,15 +520,15 @@ void tst_QTableWidget::selectedItems()
|
|||
QCOMPARE(testWidget->columnCount(), columnCount);
|
||||
|
||||
// create and set items
|
||||
foreach (IntPair intPair, createItems) {
|
||||
for (const auto &intPair : createItems) {
|
||||
testWidget->setItem(intPair.first, intPair.second,
|
||||
new QTableWidgetItem(QString("Item %1 %2")
|
||||
.arg(intPair.first).arg(intPair.second)));
|
||||
}
|
||||
// hide rows/columns
|
||||
foreach (int row, hiddenRows)
|
||||
for (int row : hiddenRows)
|
||||
testWidget->setRowHidden(row, true);
|
||||
foreach (int column, hiddenColumns)
|
||||
for (int column : hiddenColumns)
|
||||
testWidget->setColumnHidden(column, true);
|
||||
|
||||
// make sure we don't have any previous selections hanging around
|
||||
|
|
@ -557,31 +548,18 @@ void tst_QTableWidget::selectedItems()
|
|||
}
|
||||
|
||||
// check that the correct number of items and the expected items are there
|
||||
QList<QTableWidgetItem *> selectedItems = testWidget->selectedItems();
|
||||
const QList<QTableWidgetItem *> selectedItems = testWidget->selectedItems();
|
||||
QCOMPARE(selectedItems.count(), expectedItems.count());
|
||||
foreach (IntPair intPair, expectedItems)
|
||||
for (const auto &intPair : expectedItems)
|
||||
QVERIFY(selectedItems.contains(testWidget->item(intPair.first, intPair.second)));
|
||||
|
||||
// check that setItemSelected agrees with selectedItems
|
||||
for (int row = 0; row<testWidget->rowCount(); ++row) {
|
||||
bool hidden = false;
|
||||
foreach (int hiddenRow, hiddenRows){
|
||||
if(hiddenRow == row){
|
||||
hidden = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hidden)
|
||||
for (int row = 0; row < testWidget->rowCount(); ++row) {
|
||||
if (hiddenRows.contains(row))
|
||||
continue;
|
||||
|
||||
for (int column = 0; column<testWidget->columnCount(); ++column) {
|
||||
foreach (int hiddenColumn, hiddenColumns){
|
||||
if(hiddenColumn == column){
|
||||
hidden = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hidden)
|
||||
for (int column = 0; column < testWidget->columnCount(); ++column) {
|
||||
if (hiddenColumns.contains(column))
|
||||
continue;
|
||||
|
||||
QTableWidgetItem *item = testWidget->item(row, column);
|
||||
|
|
@ -621,11 +599,13 @@ void tst_QTableWidget::removeRow()
|
|||
QCOMPARE(testWidget->columnCount(), columnCount);
|
||||
|
||||
// fill table with items
|
||||
for (int r = 0; r < rowCount; ++r)
|
||||
for (int c = 0; c < columnCount; ++c)
|
||||
for (int r = 0; r < rowCount; ++r) {
|
||||
const QString rRow = QString::number(r) + QLatin1Char(':');
|
||||
for (int c = 0; c < columnCount; ++c) {
|
||||
testWidget->setItem(r, c,
|
||||
new QTableWidgetItem(
|
||||
QString::number(r) + ":" + QString::number(c)));
|
||||
new QTableWidgetItem(rRow + QString::number(c)));
|
||||
}
|
||||
}
|
||||
|
||||
// remove and compare the results
|
||||
testWidget->removeRow(row);
|
||||
|
|
@ -633,14 +613,18 @@ void tst_QTableWidget::removeRow()
|
|||
QCOMPARE(testWidget->columnCount(), expectedColumnCount);
|
||||
|
||||
// check if the correct items were removed
|
||||
for (int r = 0; r < expectedRowCount; ++r)
|
||||
for (int c = 0; c < expectedColumnCount; ++c)
|
||||
for (int r = 0; r < expectedRowCount; ++r) {
|
||||
const QString rRow = QString::number(r < row ? r : r + 1) +
|
||||
QLatin1Char(':');
|
||||
for (int c = 0; c < expectedColumnCount; ++c) {
|
||||
if (r < row)
|
||||
QCOMPARE(testWidget->item(r, c)->text(),
|
||||
QString::number(r) + ":" + QString::number(c));
|
||||
rRow + QString::number(c));
|
||||
else
|
||||
QCOMPARE(testWidget->item(r, c)->text(),
|
||||
QString::number(r + 1) + ":" + QString::number(c));
|
||||
rRow + QString::number(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QTableWidget::removeColumn_data()
|
||||
|
|
@ -673,11 +657,14 @@ void tst_QTableWidget::removeColumn()
|
|||
QCOMPARE(testWidget->columnCount(), columnCount);
|
||||
|
||||
// fill table with items
|
||||
for (int r = 0; r < rowCount; ++r)
|
||||
for (int c = 0; c < columnCount; ++c)
|
||||
for (int r = 0; r < rowCount; ++r) {
|
||||
const QString rStr = QString::number(r) + QLatin1Char(':');
|
||||
for (int c = 0; c < columnCount; ++c) {
|
||||
testWidget->setItem(r, c,
|
||||
new QTableWidgetItem(
|
||||
QString::number(r) + ":" + QString::number(c)));
|
||||
rStr + QString::number(c)));
|
||||
}
|
||||
}
|
||||
|
||||
// remove and compare the results
|
||||
testWidget->removeColumn(column);
|
||||
|
|
@ -686,14 +673,17 @@ void tst_QTableWidget::removeColumn()
|
|||
|
||||
|
||||
// check if the correct items were removed
|
||||
for (int r = 0; r < expectedRowCount; ++r)
|
||||
for (int c = 0; c < expectedColumnCount; ++c)
|
||||
for (int r = 0; r < expectedRowCount; ++r) {
|
||||
const QString rStr = QString::number(r) + QLatin1Char(':');
|
||||
for (int c = 0; c < expectedColumnCount; ++c) {
|
||||
if (c < column)
|
||||
QCOMPARE(testWidget->item(r, c)->text(),
|
||||
QString::number(r) + ":" + QString::number(c));
|
||||
rStr + QString::number(c));
|
||||
else
|
||||
QCOMPARE(testWidget->item(r, c)->text(),
|
||||
QString::number(r) + ":" + QString::number(c + 1));
|
||||
rStr + QString::number(c + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QTableWidget::insertRow_data()
|
||||
|
|
@ -819,7 +809,7 @@ void tst_QTableWidget::itemOwnership()
|
|||
item = new QObjectTableItem();
|
||||
testWidget->setItem(0, 0, item);
|
||||
delete item;
|
||||
QCOMPARE(testWidget->item(0, 0), (QTableWidgetItem *)0);
|
||||
QCOMPARE(testWidget->item(0, 0), nullptr);
|
||||
|
||||
//delete vertical headeritem from outside
|
||||
headerItem = new QObjectTableItem();
|
||||
|
|
@ -887,7 +877,7 @@ void tst_QTableWidget::sortItems_data()
|
|||
{
|
||||
QTest::addColumn<int>("rowCount");
|
||||
QTest::addColumn<int>("columnCount");
|
||||
QTest::addColumn<int>("sortOrder");
|
||||
QTest::addColumn<Qt::SortOrder>("sortOrder");
|
||||
QTest::addColumn<int>("sortColumn");
|
||||
QTest::addColumn<QStringList>("initial");
|
||||
QTest::addColumn<QStringList>("expected");
|
||||
|
|
@ -897,7 +887,7 @@ void tst_QTableWidget::sortItems_data()
|
|||
|
||||
QTest::newRow("ascending")
|
||||
<< 4 << 5
|
||||
<< static_cast<int>(Qt::AscendingOrder)
|
||||
<< Qt::AscendingOrder
|
||||
<< 0
|
||||
<< (QStringList()
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
|
|
@ -915,7 +905,7 @@ void tst_QTableWidget::sortItems_data()
|
|||
|
||||
QTest::newRow("descending")
|
||||
<< 4 << 5
|
||||
<< static_cast<int>(Qt::DescendingOrder)
|
||||
<< Qt::DescendingOrder
|
||||
<< 0
|
||||
<< (QStringList()
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
|
|
@ -933,154 +923,151 @@ void tst_QTableWidget::sortItems_data()
|
|||
|
||||
QTest::newRow("empty table")
|
||||
<< 4 << 5
|
||||
<< static_cast<int>(Qt::AscendingOrder)
|
||||
<< Qt::AscendingOrder
|
||||
<< 0
|
||||
<< (QStringList()
|
||||
<< 0 << 0 << 0 << 0 << 0
|
||||
<< 0 << 0 << 0 << 0 << 0
|
||||
<< 0 << 0 << 0 << 0 << 0
|
||||
<< 0 << 0 << 0 << 0 << 0)
|
||||
<< QString() << QString() << QString() << QString() << QString()
|
||||
<< QString() << QString() << QString() << QString() << QString()
|
||||
<< QString() << QString() << QString() << QString() << QString()
|
||||
<< QString() << QString() << QString() << QString() << QString())
|
||||
<< (QStringList()
|
||||
<< 0 << 0 << 0 << 0 << 0
|
||||
<< 0 << 0 << 0 << 0 << 0
|
||||
<< 0 << 0 << 0 << 0 << 0
|
||||
<< 0 << 0 << 0 << 0 << 0)
|
||||
<< QString() << QString() << QString() << QString() << QString()
|
||||
<< QString() << QString() << QString() << QString() << QString()
|
||||
<< QString() << QString() << QString() << QString() << QString()
|
||||
<< QString() << QString() << QString() << QString() << QString())
|
||||
<< IntList()
|
||||
<< IntList()
|
||||
<< IntList();
|
||||
|
||||
|
||||
QTest::newRow("half-empty table")
|
||||
<< 4 << 5
|
||||
<< static_cast<int>(Qt::AscendingOrder)
|
||||
<< Qt::AscendingOrder
|
||||
<< 0
|
||||
<< (QStringList()
|
||||
<< "0" << 0 << 0 << 0 << 0
|
||||
<< "3" << "d" << 0 << 0 << 0
|
||||
<< "2" << "c" << 0 << 0 << 0
|
||||
<< 0 << 0 << 0 << 0 << 0)
|
||||
<< "0" << QString() << QString() << QString() << QString()
|
||||
<< "3" << "d" << QString() << QString() << QString()
|
||||
<< "2" << "c" << QString() << QString() << QString()
|
||||
<< QString() << QString() << QString() << QString() << QString())
|
||||
<< (QStringList()
|
||||
<< "0" << 0 << 0 << 0 << 0
|
||||
<< "2" << "c" << 0 << 0 << 0
|
||||
<< "3" << "d" << 0 << 0 << 0
|
||||
<< 0 << 0 << 0 << 0 << 0)
|
||||
<< "0" << QString() << QString() << QString() << QString()
|
||||
<< "2" << "c" << QString() << QString() << QString()
|
||||
<< "3" << "d" << QString() << QString() << QString()
|
||||
<< QString() << QString() << QString() << QString() << QString())
|
||||
<< (IntList() << 0 << 2 << 1)
|
||||
<< IntList()
|
||||
<< IntList();
|
||||
|
||||
QTest::newRow("empty column, should not sort.")
|
||||
<< 4 << 5
|
||||
<< static_cast<int>(Qt::AscendingOrder)
|
||||
<< Qt::AscendingOrder
|
||||
<< 3
|
||||
<< (QStringList()
|
||||
<< "0" << 0 << 0 << 0 << 0
|
||||
<< "3" << "d" << 0 << 0 << 0
|
||||
<< "2" << "c" << 0 << 0 << 0
|
||||
<< 0 << 0 << 0 << 0 << 0)
|
||||
<< "0" << QString() << QString() << QString() << QString()
|
||||
<< "3" << "d" << QString() << QString() << QString()
|
||||
<< "2" << "c" << QString() << QString() << QString()
|
||||
<< QString() << QString() << QString() << QString() << QString())
|
||||
<< (QStringList()
|
||||
<< "0" << 0 << 0 << 0 << 0
|
||||
<< "3" << "d" << 0 << 0 << 0
|
||||
<< "2" << "c" << 0 << 0 << 0
|
||||
<< 0 << 0 << 0 << 0 << 0)
|
||||
<< "0" << QString() << QString() << QString() << QString()
|
||||
<< "3" << "d" << QString() << QString() << QString()
|
||||
<< "2" << "c" << QString() << QString() << QString()
|
||||
<< QString() << QString() << QString() << QString() << QString())
|
||||
<< IntList()
|
||||
<< IntList()
|
||||
<< IntList();
|
||||
|
||||
QTest::newRow("descending with null cell, the null cell should be placed at the bottom")
|
||||
<< 4 << 5
|
||||
<< static_cast<int>(Qt::DescendingOrder)
|
||||
<< Qt::DescendingOrder
|
||||
<< 0
|
||||
<< (QStringList()
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
<< "3" << "d" << "k" << "o" << "6"
|
||||
<< "2" << "c" << "9" << "y" << "8"
|
||||
<< 0 << "b" << "7" << "3" << "u")
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
<< "3" << "d" << "k" << "o" << "6"
|
||||
<< "2" << "c" << "9" << "y" << "8"
|
||||
<< QString() << "b" << "7" << "3" << "u")
|
||||
<< (QStringList()
|
||||
<< "3" << "d" << "k" << "o" << "6"
|
||||
<< "2" << "c" << "9" << "y" << "8"
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
<< 0 << "b" << "7" << "3" << "u")
|
||||
<< "3" << "d" << "k" << "o" << "6"
|
||||
<< "2" << "c" << "9" << "y" << "8"
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
<< QString() << "b" << "7" << "3" << "u")
|
||||
<< (IntList() << 2 << 0 << 1)
|
||||
<< IntList()
|
||||
<< IntList();
|
||||
|
||||
QTest::newRow("ascending with null cell, the null cell should be placed at the bottom")
|
||||
<< 4 << 5
|
||||
<< static_cast<int>(Qt::AscendingOrder)
|
||||
<< Qt::AscendingOrder
|
||||
<< 0
|
||||
<< (QStringList()
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
<< "3" << "d" << "k" << "o" << "6"
|
||||
<< "2" << "c" << "9" << "y" << "8"
|
||||
<< 0 << "b" << "7" << "3" << "u")
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
<< "3" << "d" << "k" << "o" << "6"
|
||||
<< "2" << "c" << "9" << "y" << "8"
|
||||
<< QString() << "b" << "7" << "3" << "u")
|
||||
<< (QStringList()
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
<< "2" << "c" << "9" << "y" << "8"
|
||||
<< "3" << "d" << "k" << "o" << "6"
|
||||
<< 0 << "b" << "7" << "3" << "u")
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
<< "2" << "c" << "9" << "y" << "8"
|
||||
<< "3" << "d" << "k" << "o" << "6"
|
||||
<< QString() << "b" << "7" << "3" << "u")
|
||||
<< (IntList() << 0 << 2 << 1)
|
||||
<< IntList()
|
||||
<< IntList();
|
||||
|
||||
QTest::newRow("ascending with null cells, the null cells should be placed at the bottom")
|
||||
<< 4 << 5
|
||||
<< static_cast<int>(Qt::AscendingOrder)
|
||||
<< Qt::AscendingOrder
|
||||
<< 0
|
||||
<< (QStringList()
|
||||
<< "3" << "d" << "k" << "o" << "6"
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
<< 0 << "c" << "9" << "y" << "8"
|
||||
<< 0 << "b" << "7" << "3" << "u")
|
||||
<< "3" << "d" << "k" << "o" << "6"
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
<< QString() << "c" << "9" << "y" << "8"
|
||||
<< QString() << "b" << "7" << "3" << "u")
|
||||
<< (QStringList()
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
<< "3" << "d" << "k" << "o" << "6"
|
||||
<< 0 << "c" << "9" << "y" << "8"
|
||||
<< 0 << "b" << "7" << "3" << "u")
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
<< "3" << "d" << "k" << "o" << "6"
|
||||
<< QString() << "c" << "9" << "y" << "8"
|
||||
<< QString() << "b" << "7" << "3" << "u")
|
||||
<< (IntList() << 1 << 0)
|
||||
<< IntList()
|
||||
<< IntList();
|
||||
|
||||
QTest::newRow("ascending... Check a bug in PersistentIndexes")
|
||||
<< 4 << 5
|
||||
<< static_cast<int>(Qt::AscendingOrder)
|
||||
<< Qt::AscendingOrder
|
||||
<< 0
|
||||
<< (QStringList()
|
||||
<< "3" << "c" << "9" << "y" << "8"
|
||||
<< "2" << "b" << "7" << "3" << "u"
|
||||
<< "4" << "d" << "k" << "o" << "6"
|
||||
<< "1" << "a" << "o" << "8" << "k"
|
||||
)
|
||||
<< "1" << "a" << "o" << "8" << "k")
|
||||
<< (QStringList()
|
||||
<< "1" << "a" << "o" << "8" << "k"
|
||||
<< "2" << "b" << "7" << "3" << "u"
|
||||
<< "3" << "c" << "9" << "y" << "8"
|
||||
<< "4" << "d" << "k" << "o" << "6"
|
||||
)
|
||||
<< "4" << "d" << "k" << "o" << "6")
|
||||
<< (IntList() << 2 << 1 << 3 << 0)
|
||||
<< IntList()
|
||||
<< IntList();
|
||||
|
||||
QTest::newRow("ascending with some null cells inbetween")
|
||||
<< 4 << 5
|
||||
<< static_cast<int>(Qt::AscendingOrder)
|
||||
<< Qt::AscendingOrder
|
||||
<< 0
|
||||
<< (QStringList()
|
||||
<< 0 << "a" << "o" << "8" << "k"
|
||||
<< "2" << "c" << "9" << "y" << "8"
|
||||
<< 0 << "d" << "k" << "o" << "6"
|
||||
<< "1" << "b" << "7" << "3" << "u")
|
||||
<< QString() << "a" << "o" << "8" << "k"
|
||||
<< "2" << "c" << "9" << "y" << "8"
|
||||
<< QString() << "d" << "k" << "o" << "6"
|
||||
<< "1" << "b" << "7" << "3" << "u")
|
||||
<< (QStringList()
|
||||
<< "1" << "b" << "7" << "3" << "u"
|
||||
<< "2" << "c" << "9" << "y" << "8"
|
||||
<< 0 << "a" << "o" << "8" << "k"
|
||||
<< 0 << "d" << "k" << "o" << "6")
|
||||
<< "1" << "b" << "7" << "3" << "u"
|
||||
<< "2" << "c" << "9" << "y" << "8"
|
||||
<< QString() << "a" << "o" << "8" << "k"
|
||||
<< QString() << "d" << "k" << "o" << "6")
|
||||
<< (IntList() << 1 << 0)
|
||||
<< IntList()
|
||||
<< IntList();
|
||||
|
||||
QTest::newRow("ascending hidden")
|
||||
<< 4 << 5
|
||||
<< static_cast<int>(Qt::AscendingOrder)
|
||||
<< Qt::AscendingOrder
|
||||
<< 0
|
||||
<< (QStringList()
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
|
|
@ -1098,7 +1085,7 @@ void tst_QTableWidget::sortItems_data()
|
|||
|
||||
QTest::newRow("descending hidden")
|
||||
<< 4 << 5
|
||||
<< static_cast<int>(Qt::DescendingOrder)
|
||||
<< Qt::DescendingOrder
|
||||
<< 0
|
||||
<< (QStringList()
|
||||
<< "0" << "a" << "o" << "8" << "k"
|
||||
|
|
@ -1119,7 +1106,7 @@ void tst_QTableWidget::sortItems()
|
|||
{
|
||||
QFETCH(int, rowCount);
|
||||
QFETCH(int, columnCount);
|
||||
QFETCH(int, sortOrder);
|
||||
QFETCH(Qt::SortOrder, sortOrder);
|
||||
QFETCH(int, sortColumn);
|
||||
QFETCH(QStringList, initial);
|
||||
QFETCH(QStringList, expected);
|
||||
|
|
@ -1131,13 +1118,13 @@ void tst_QTableWidget::sortItems()
|
|||
testWidget->setColumnCount(columnCount);
|
||||
|
||||
QAbstractItemModel *model = testWidget->model();
|
||||
QList<QPersistentModelIndex> persistent;
|
||||
QVector<QPersistentModelIndex> persistent;
|
||||
|
||||
int ti = 0;
|
||||
for (int r = 0; r < rowCount; ++r) {
|
||||
for (int c = 0; c < columnCount; ++c) {
|
||||
QString str = initial.at(ti++);
|
||||
if (!str.isNull()) {
|
||||
QString str = initial.at(ti++);
|
||||
if (!str.isEmpty()) {
|
||||
testWidget->setItem(r, c, new QTableWidgetItem(str));
|
||||
}
|
||||
}
|
||||
|
|
@ -1150,7 +1137,7 @@ void tst_QTableWidget::sortItems()
|
|||
|
||||
QCOMPARE(testWidget->verticalHeader()->hiddenSectionCount(), initialHidden.count());
|
||||
|
||||
testWidget->sortItems(sortColumn, static_cast<Qt::SortOrder>(sortOrder));
|
||||
testWidget->sortItems(sortColumn, sortOrder);
|
||||
|
||||
int te = 0;
|
||||
for (int i = 0; i < rows.count(); ++i) {
|
||||
|
|
@ -1175,7 +1162,7 @@ void tst_QTableWidget::setItemWithSorting_data()
|
|||
{
|
||||
QTest::addColumn<int>("rowCount");
|
||||
QTest::addColumn<int>("columnCount");
|
||||
QTest::addColumn<int>("sortOrder");
|
||||
QTest::addColumn<Qt::SortOrder>("sortOrder");
|
||||
QTest::addColumn<int>("sortColumn");
|
||||
QTest::addColumn<QStringList>("initialValues");
|
||||
QTest::addColumn<int>("row");
|
||||
|
|
@ -1187,7 +1174,7 @@ void tst_QTableWidget::setItemWithSorting_data()
|
|||
|
||||
QTest::newRow("2x1 no change (ascending)")
|
||||
<< 2 << 1
|
||||
<< static_cast<int>(Qt::AscendingOrder) << 0
|
||||
<< Qt::AscendingOrder << 0
|
||||
<< (QStringList() << "0" << "1")
|
||||
<< 1 << 0 << "2"
|
||||
<< (QStringList() << "0" << "2")
|
||||
|
|
@ -1195,7 +1182,7 @@ void tst_QTableWidget::setItemWithSorting_data()
|
|||
<< false;
|
||||
QTest::newRow("2x1 no change (descending)")
|
||||
<< 2 << 1
|
||||
<< static_cast<int>(Qt::DescendingOrder) << 0
|
||||
<< Qt::DescendingOrder << 0
|
||||
<< (QStringList() << "1" << "0")
|
||||
<< 0 << 0 << "2"
|
||||
<< (QStringList() << "2" << "0")
|
||||
|
|
@ -1203,7 +1190,7 @@ void tst_QTableWidget::setItemWithSorting_data()
|
|||
<< false;
|
||||
QTest::newRow("2x1 reorder (ascending)")
|
||||
<< 2 << 1
|
||||
<< static_cast<int>(Qt::AscendingOrder) << 0
|
||||
<< Qt::AscendingOrder << 0
|
||||
<< (QStringList() << "0" << "1")
|
||||
<< 0 << 0 << "2"
|
||||
<< (QStringList() << "1" << "2")
|
||||
|
|
@ -1211,7 +1198,7 @@ void tst_QTableWidget::setItemWithSorting_data()
|
|||
<< true;
|
||||
QTest::newRow("2x1 reorder (descending)")
|
||||
<< 2 << 1
|
||||
<< static_cast<int>(Qt::DescendingOrder) << 0
|
||||
<< Qt::DescendingOrder << 0
|
||||
<< (QStringList() << "1" << "0")
|
||||
<< 1 << 0 << "2"
|
||||
<< (QStringList() << "2" << "1")
|
||||
|
|
@ -1219,7 +1206,7 @@ void tst_QTableWidget::setItemWithSorting_data()
|
|||
<< true;
|
||||
QTest::newRow("2x2 no change (ascending)")
|
||||
<< 2 << 2
|
||||
<< static_cast<int>(Qt::AscendingOrder) << 0
|
||||
<< Qt::AscendingOrder << 0
|
||||
<< (QStringList()
|
||||
<< "0" << "00"
|
||||
<< "1" << "11")
|
||||
|
|
@ -1231,7 +1218,7 @@ void tst_QTableWidget::setItemWithSorting_data()
|
|||
<< false;
|
||||
QTest::newRow("2x2 reorder (ascending)")
|
||||
<< 2 << 2
|
||||
<< static_cast<int>(Qt::AscendingOrder) << 0
|
||||
<< Qt::AscendingOrder << 0
|
||||
<< (QStringList()
|
||||
<< "0" << "00"
|
||||
<< "1" << "11")
|
||||
|
|
@ -1243,7 +1230,7 @@ void tst_QTableWidget::setItemWithSorting_data()
|
|||
<< true;
|
||||
QTest::newRow("2x2 reorder (ascending, sortColumn = 1)")
|
||||
<< 2 << 2
|
||||
<< static_cast<int>(Qt::AscendingOrder) << 1
|
||||
<< Qt::AscendingOrder << 1
|
||||
<< (QStringList()
|
||||
<< "00" << "0"
|
||||
<< "11" << "1")
|
||||
|
|
@ -1255,7 +1242,7 @@ void tst_QTableWidget::setItemWithSorting_data()
|
|||
<< true;
|
||||
QTest::newRow("2x2 no change (column != sortColumn)")
|
||||
<< 2 << 2
|
||||
<< static_cast<int>(Qt::AscendingOrder) << 1
|
||||
<< Qt::AscendingOrder << 1
|
||||
<< (QStringList()
|
||||
<< "00" << "0"
|
||||
<< "11" << "1")
|
||||
|
|
@ -1267,7 +1254,7 @@ void tst_QTableWidget::setItemWithSorting_data()
|
|||
<< false;
|
||||
QTest::newRow("8x4 reorder (ascending, sortColumn = 3)")
|
||||
<< 8 << 4
|
||||
<< static_cast<int>(Qt::AscendingOrder) << 3
|
||||
<< Qt::AscendingOrder << 3
|
||||
<< (QStringList()
|
||||
<< "q" << "v" << "u" << "0"
|
||||
<< "e" << "j" << "i" << "10"
|
||||
|
|
@ -1293,9 +1280,13 @@ void tst_QTableWidget::setItemWithSorting_data()
|
|||
|
||||
void tst_QTableWidget::setItemWithSorting()
|
||||
{
|
||||
static int dummy1 = qRegisterMetaType<QList<QPersistentModelIndex>>();
|
||||
static int dummy2 = qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>();
|
||||
Q_UNUSED(dummy1);
|
||||
Q_UNUSED(dummy2);
|
||||
QFETCH(int, rowCount);
|
||||
QFETCH(int, columnCount);
|
||||
QFETCH(int, sortOrder);
|
||||
QFETCH(Qt::SortOrder, sortOrder);
|
||||
QFETCH(int, sortColumn);
|
||||
QFETCH(QStringList, initialValues);
|
||||
QFETCH(int, row);
|
||||
|
|
@ -1309,7 +1300,7 @@ void tst_QTableWidget::setItemWithSorting()
|
|||
QTableWidget w(rowCount, columnCount);
|
||||
|
||||
QAbstractItemModel *model = w.model();
|
||||
QList<QPersistentModelIndex> persistent;
|
||||
QVector<QPersistentModelIndex> persistent;
|
||||
|
||||
int ti = 0;
|
||||
for (int r = 0; r < rowCount; ++r) {
|
||||
|
|
@ -1320,11 +1311,11 @@ void tst_QTableWidget::setItemWithSorting()
|
|||
persistent << model->index(r, sortColumn);
|
||||
}
|
||||
|
||||
w.sortItems(sortColumn, static_cast<Qt::SortOrder>(sortOrder));
|
||||
w.sortItems(sortColumn, sortOrder);
|
||||
w.setSortingEnabled(true);
|
||||
|
||||
QSignalSpy dataChangedSpy(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
|
||||
QSignalSpy layoutChangedSpy(model, SIGNAL(layoutChanged()));
|
||||
QSignalSpy dataChangedSpy(model, &QAbstractItemModel::dataChanged);
|
||||
QSignalSpy layoutChangedSpy(model, &QAbstractItemModel::layoutChanged);
|
||||
|
||||
if (i == 0) {
|
||||
// set a new item
|
||||
|
|
@ -1376,7 +1367,7 @@ public:
|
|||
void tst_QTableWidget::itemData()
|
||||
{
|
||||
QTableWidgetDataChanged widget(2, 2);
|
||||
widget.setItem(0, 0, new QTableWidgetItem());
|
||||
widget.setItem(0, 0, new QTableWidgetItem);
|
||||
QTableWidgetItem *item = widget.item(0, 0);
|
||||
QVERIFY(item);
|
||||
item->setFlags(item->flags() | Qt::ItemIsEditable);
|
||||
|
|
@ -1399,7 +1390,7 @@ void tst_QTableWidget::setItemData()
|
|||
{
|
||||
QTableWidgetDataChanged table(10, 10);
|
||||
table.setSortingEnabled(false);
|
||||
QSignalSpy dataChangedSpy(table.model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)));
|
||||
QSignalSpy dataChangedSpy(table.model(), &QAbstractItemModel::dataChanged);
|
||||
|
||||
QTableWidgetItem *item = new QTableWidgetItem;
|
||||
table.setItem(0, 0, item);
|
||||
|
|
@ -1432,11 +1423,11 @@ void tst_QTableWidget::cellWidget()
|
|||
QTableWidget table(10, 10);
|
||||
QWidget widget;
|
||||
|
||||
QCOMPARE(table.cellWidget(5, 5), static_cast<QWidget*>(0));
|
||||
QCOMPARE(table.cellWidget(5, 5), nullptr);
|
||||
table.setCellWidget(5, 5, &widget);
|
||||
QCOMPARE(table.cellWidget(5, 5), &widget);
|
||||
table.removeCellWidget(5, 5);
|
||||
QCOMPARE(table.cellWidget(5, 5), static_cast<QWidget*>(0));
|
||||
QCOMPARE(table.cellWidget(5, 5), nullptr);
|
||||
}
|
||||
|
||||
void tst_QTableWidget::cellWidgetGeometry()
|
||||
|
|
@ -1463,27 +1454,29 @@ void tst_QTableWidget::cellWidgetGeometry()
|
|||
|
||||
void tst_QTableWidget::sizeHint_data()
|
||||
{
|
||||
QTest::addColumn<int>("scrollBarPolicy");
|
||||
QTest::addColumn<Qt::ScrollBarPolicy>("scrollBarPolicy");
|
||||
QTest::addColumn<QSize>("viewSize");
|
||||
QTest::newRow("ScrollBarAlwaysOn") << static_cast<int>(Qt::ScrollBarAlwaysOn) << QSize();
|
||||
QTest::newRow("ScrollBarAlwaysOff") << static_cast<int>(Qt::ScrollBarAlwaysOff) << QSize();
|
||||
QTest::newRow("ScrollBarAlwaysOn") << Qt::ScrollBarAlwaysOn << QSize();
|
||||
QTest::newRow("ScrollBarAlwaysOff") << Qt::ScrollBarAlwaysOff << QSize();
|
||||
// make sure the scrollbars are shown by resizing the view to 40x40
|
||||
QTest::newRow("ScrollBarAsNeeded (40x40)") << static_cast<int>(Qt::ScrollBarAsNeeded) << QSize(40, 40);
|
||||
QTest::newRow("ScrollBarAsNeeded (1000x1000)") << static_cast<int>(Qt::ScrollBarAsNeeded) << QSize(1000, 1000);
|
||||
QTest::newRow("ScrollBarAsNeeded (40x40)") << Qt::ScrollBarAsNeeded << QSize(40, 40);
|
||||
QTest::newRow("ScrollBarAsNeeded (1000x1000)") << Qt::ScrollBarAsNeeded << QSize(1000, 1000);
|
||||
}
|
||||
|
||||
void tst_QTableWidget::sizeHint()
|
||||
{
|
||||
QFETCH(int, scrollBarPolicy);
|
||||
QFETCH(Qt::ScrollBarPolicy, scrollBarPolicy);
|
||||
QFETCH(QSize, viewSize);
|
||||
|
||||
QTableWidget view(2, 2);
|
||||
view.setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
|
||||
view.setVerticalScrollBarPolicy(static_cast<Qt::ScrollBarPolicy>(scrollBarPolicy));
|
||||
view.setHorizontalScrollBarPolicy(static_cast<Qt::ScrollBarPolicy>(scrollBarPolicy));
|
||||
for (int r = 0 ; r < view.rowCount(); ++r)
|
||||
view.setVerticalScrollBarPolicy(scrollBarPolicy);
|
||||
view.setHorizontalScrollBarPolicy(scrollBarPolicy);
|
||||
for (int r = 0 ; r < view.rowCount(); ++r) {
|
||||
const QString rStr = QString::number(r) + QLatin1Char('/');
|
||||
for (int c = 0 ; c < view.columnCount(); ++c)
|
||||
view.setItem(r, c, new QTableWidgetItem(QString("%1/%2").arg(r).arg(c)));
|
||||
view.setItem(r, c, new QTableWidgetItem(rStr + QString::number(c)));
|
||||
}
|
||||
|
||||
view.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&view));
|
||||
|
|
@ -1520,7 +1513,7 @@ void tst_QTableWidget::task231094()
|
|||
if (y == 1)
|
||||
twi->setFlags(Qt::ItemIsEnabled);
|
||||
else
|
||||
twi->setFlags(0);
|
||||
twi->setFlags({});
|
||||
tw.setItem(y, x, twi);
|
||||
}
|
||||
}
|
||||
|
|
@ -1558,15 +1551,15 @@ void tst_QTableWidget::task262056_sortDuplicate()
|
|||
testWidget->setColumnCount(2);
|
||||
testWidget->setRowCount(8);
|
||||
testWidget->setSortingEnabled(true);
|
||||
QStringList items = (QStringList() << "AAA" << "BBB" << "CCC" << "CCC" << "DDD"\
|
||||
<< "EEE" << "FFF" << "GGG");
|
||||
for (int i = 0; i<8; i++ ) {
|
||||
const QStringList items({"AAA", "BBB", "CCC", "CCC", "DDD",
|
||||
"EEE", "FFF", "GGG"});
|
||||
for (int i = 0; i < 8; i++ ) {
|
||||
QTableWidgetItem *twi = new QTableWidgetItem(items.at(i));
|
||||
testWidget->setItem(i,0,twi);
|
||||
testWidget->setItem(i,1,new QTableWidgetItem(QLatin1String("item ") + QString::number(i)));
|
||||
testWidget->setItem(i, 0, twi);
|
||||
testWidget->setItem(i, 1, new QTableWidgetItem(QLatin1String("item ") + QString::number(i)));
|
||||
}
|
||||
testWidget->sortItems(0, Qt::AscendingOrder);
|
||||
QSignalSpy layoutChangedSpy(testWidget->model(), SIGNAL(layoutChanged()));
|
||||
QSignalSpy layoutChangedSpy(testWidget->model(), &QAbstractItemModel::layoutChanged);
|
||||
testWidget->item(3,0)->setBackground(Qt::red);
|
||||
|
||||
QCOMPARE(layoutChangedSpy.count(),0);
|
||||
|
|
@ -1586,18 +1579,14 @@ void tst_QTableWidget::itemWithHeaderItems()
|
|||
QTableWidgetItem *item1_0 = new QTableWidgetItem(QTableWidgetItem::UserType);
|
||||
table.setItem(1, 0, item1_0);
|
||||
|
||||
QCOMPARE(table.item(0, 1), static_cast<QTableWidgetItem *>(0));
|
||||
QCOMPARE(table.item(0, 1), nullptr);
|
||||
}
|
||||
|
||||
class TestTableWidget : public QTableWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TestTableWidget(int rows, int columns, QWidget *parent = 0)
|
||||
: QTableWidget(rows, columns, parent)
|
||||
{
|
||||
}
|
||||
|
||||
using QTableWidget::QTableWidget;
|
||||
using QTableWidget::mimeData;
|
||||
using QTableWidget::indexFromItem;
|
||||
using QTableWidget::keyPressEvent;
|
||||
|
|
@ -1661,18 +1650,19 @@ void tst_QTableWidget::selectedRowAfterSorting()
|
|||
{
|
||||
TestTableWidget table(3,3);
|
||||
table.setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
for (int r = 0; r < 3; r++)
|
||||
for (int r = 0; r < 3; r++) {
|
||||
for (int c = 0; c < 3; c++)
|
||||
table.setItem(r,c,new QTableWidgetItem(QStringLiteral("0")));
|
||||
table.setItem(r, c, new QTableWidgetItem(QStringLiteral("0")));
|
||||
}
|
||||
QHeaderView *localHorizontalHeader = table.horizontalHeader();
|
||||
localHorizontalHeader->setSortIndicator(1,Qt::DescendingOrder);
|
||||
table.setProperty("sortingEnabled",true);
|
||||
table.selectRow(1);
|
||||
table.item(1,1)->setText("9");
|
||||
QCOMPARE(table.selectedItems().count(),3);
|
||||
foreach (QTableWidgetItem *item, table.selectedItems()) {
|
||||
QCOMPARE(item->row(),0);
|
||||
}
|
||||
const auto selectedItems = table.selectedItems();
|
||||
for (QTableWidgetItem *item : selectedItems)
|
||||
QCOMPARE(item->row(), 0);
|
||||
}
|
||||
|
||||
void tst_QTableWidget::search()
|
||||
|
|
@ -1717,10 +1707,11 @@ void tst_QTableWidget::search()
|
|||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
void tst_QTableWidget::clearItemData()
|
||||
{
|
||||
QTableWidget table(3,3);
|
||||
for (int r = 0; r < 3; r++)
|
||||
QTableWidget table(3, 3);
|
||||
for (int r = 0; r < 3; r++) {
|
||||
for (int c = 0; c < 3; c++)
|
||||
table.setItem(r,c,new QTableWidgetItem(QStringLiteral("0")));
|
||||
table.setItem(r, c, new QTableWidgetItem(QStringLiteral("0")));
|
||||
}
|
||||
QSignalSpy dataChangeSpy(table.model(), &QAbstractItemModel::dataChanged);
|
||||
QVERIFY(dataChangeSpy.isValid());
|
||||
QVERIFY(!table.model()->clearItemData(QModelIndex()));
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ private slots:
|
|||
void context();
|
||||
void duplicatedShortcutOverride();
|
||||
void shortcutToFocusProxy();
|
||||
void deleteLater();
|
||||
|
||||
protected:
|
||||
static Qt::KeyboardModifiers toButtons( int key );
|
||||
|
|
@ -1263,5 +1264,14 @@ void tst_QShortcut::shortcutToFocusProxy()
|
|||
QCOMPARE(le.text(), QString());
|
||||
}
|
||||
|
||||
void tst_QShortcut::deleteLater()
|
||||
{
|
||||
QWidget w;
|
||||
QPointer<QShortcut> sc(new QShortcut(QKeySequence(Qt::Key_1), &w));
|
||||
sc->deleteLater();
|
||||
QTRY_VERIFY(!sc);
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(tst_QShortcut)
|
||||
#include "tst_qshortcut.moc"
|
||||
|
|
|
|||
|
|
@ -28,10 +28,8 @@
|
|||
|
||||
#include "qbaselinetest.h"
|
||||
#include "baselineprotocol.h"
|
||||
#if QT_CONFIG(process)
|
||||
# include <QtCore/QProcess>
|
||||
#endif
|
||||
#include <QtCore/QDir>
|
||||
#include <QFile>
|
||||
|
||||
#define MAXCMDLINEARGS 128
|
||||
|
||||
|
|
@ -146,20 +144,15 @@ void addClientProperty(const QString& key, const QString& value)
|
|||
*/
|
||||
void fetchCustomClientProperties()
|
||||
{
|
||||
#if !QT_CONFIG(process)
|
||||
QSKIP("This test requires QProcess support");
|
||||
#else
|
||||
QString script = "hostinfo.sh"; //### TBD: Windows implementation (hostinfo.bat)
|
||||
QFile file("hostinfo.txt");
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
return;
|
||||
QTextStream in(&file);
|
||||
|
||||
QProcess runScript;
|
||||
runScript.setWorkingDirectory(QCoreApplication::applicationDirPath());
|
||||
runScript.start("sh", QStringList() << script, QIODevice::ReadOnly);
|
||||
if (!runScript.waitForFinished(5000) || runScript.error() != QProcess::UnknownError) {
|
||||
qWarning() << "QBaselineTest: Error running script" << runScript.workingDirectory() + QDir::separator() + script << ":" << runScript.errorString();
|
||||
qDebug() << " stderr:" << runScript.readAllStandardError().trimmed();
|
||||
}
|
||||
while (!runScript.atEnd()) {
|
||||
QByteArray line = runScript.readLine().trimmed(); // ###local8bit? utf8?
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine().trimmed(); // ###local8bit? utf8?
|
||||
if (line.startsWith(QLatin1Char('#'))) // Ignore comments in file
|
||||
continue;
|
||||
QString key, val;
|
||||
int colonPos = line.indexOf(':');
|
||||
if (colonPos > 0) {
|
||||
|
|
@ -171,7 +164,6 @@ void fetchCustomClientProperties()
|
|||
else
|
||||
qDebug() << "Unparseable script output ignored:" << line;
|
||||
}
|
||||
#endif // QT_CONFIG(process)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue