Merge remote-tracking branch 'origin/5.14' into 5.15
Change-Id: Ib4df563fc7b1f7c40f425e0e71180d9517a672be
This commit is contained in:
commit
a317bff298
@ -734,7 +734,13 @@ defineTest(qtConfOutput_preparePaths) {
|
||||
}
|
||||
have_prefix = false
|
||||
} else {
|
||||
config.input.prefix = $$absolute_path($$config.input.prefix, $$OUT_PWD)
|
||||
equals(XSPEC, $$[QMAKE_SPEC]) {
|
||||
# Only make the user-specified prefix absolute if we're not cross-compiling.
|
||||
config.input.prefix = $$absolute_path($$config.input.prefix, $$OUT_PWD)
|
||||
} else {
|
||||
# But we still must normalize path separators.
|
||||
config.input.prefix = $$replace(config.input.prefix, \\\\, /)
|
||||
}
|
||||
have_prefix = true
|
||||
}
|
||||
|
||||
|
@ -25,14 +25,16 @@ defineTest(addInstallFiles) {
|
||||
export($$1)
|
||||
}
|
||||
|
||||
probase = $$relative_path($$_PRO_FILE_PWD_, $$dirname(_QMAKE_CONF_)/examples)
|
||||
moduleRoot = $$dirname(_QMAKE_CONF_)
|
||||
probase = $$relative_path($$_PRO_FILE_PWD_, $$moduleRoot/examples)
|
||||
isEmpty(probase)|contains(probase, ^\\..*): \
|
||||
return()
|
||||
|
||||
isEmpty(_QMAKE_CACHE_) {
|
||||
!equals(OUT_PWD, $$_PRO_FILE_PWD_): \
|
||||
return()
|
||||
error("You cannot build examples inside the Qt source tree, except as part of a proper Qt build.")
|
||||
moduleRootRelativeToBuildDir = $$relative_path($$moduleRoot, $$OUT_PWD)
|
||||
# Check if OUT_PWD is inside module root
|
||||
equals(moduleRootRelativeToBuildDir, .)|contains(moduleRootRelativeToBuildDir, \(\.\./\)+\(\.\.\)?): \
|
||||
error("You cannot build examples inside the Qt source tree, except as part of a proper Qt build.")
|
||||
}
|
||||
|
||||
contains(TEMPLATE, "vc.*"): \
|
||||
|
@ -1,42 +0,0 @@
|
||||
From 3442a3ce9c2bd366eb0bd1c18d37a6ce732a888d Mon Sep 17 00:00:00 2001
|
||||
From: Andy Shaw <andy.shaw@qt.io>
|
||||
Date: Wed, 25 Sep 2019 09:17:01 +0200
|
||||
Subject: [PATCH] Fix CVE-2019-16168 in SQLite
|
||||
|
||||
v3.29.0 is the latest and there is no indication as to when the next
|
||||
release is so we will apply this separately for now and it can be
|
||||
reverted once it is in a release that we ship with.
|
||||
|
||||
This patch is taken from https://www.sqlite.org/src/info/98357d8c1263920b
|
||||
|
||||
Change-Id: I82d398b093b67842a4369e3220c01e7eea30763a
|
||||
---
|
||||
src/3rdparty/sqlite/sqlite3.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
|
||||
index 61bfdeb766..b3e6ae27b6 100644
|
||||
--- a/src/3rdparty/sqlite/sqlite3.c
|
||||
+++ b/src/3rdparty/sqlite/sqlite3.c
|
||||
@@ -105933,7 +105933,9 @@ static void decodeIntArray(
|
||||
if( sqlite3_strglob("unordered*", z)==0 ){
|
||||
pIndex->bUnordered = 1;
|
||||
}else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
|
||||
- pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
|
||||
+ int sz = sqlite3Atoi(z+3);
|
||||
+ if( sz<2 ) sz = 2;
|
||||
+ pIndex->szIdxRow = sqlite3LogEst(sz);
|
||||
}else if( sqlite3_strglob("noskipscan*", z)==0 ){
|
||||
pIndex->noSkipScan = 1;
|
||||
}
|
||||
@@ -143260,6 +143262,7 @@ static int whereLoopAddBtreeIndex(
|
||||
** it to pNew->rRun, which is currently set to the cost of the index
|
||||
** seek only. Then, if this is a non-covering index, add the cost of
|
||||
** visiting the rows in the main table. */
|
||||
+ assert( pSrc->pTab->szTabRow>0 );
|
||||
rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
|
||||
pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx);
|
||||
if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
|
||||
--
|
||||
2.20.1 (Apple Git-117)
|
||||
|
4
src/3rdparty/sqlite/qt_attribution.json
vendored
4
src/3rdparty/sqlite/qt_attribution.json
vendored
@ -6,8 +6,8 @@
|
||||
|
||||
"Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.",
|
||||
"Homepage": "https://www.sqlite.org/",
|
||||
"Version": "3.29.0",
|
||||
"DownloadLocation": "https://www.sqlite.org/2019/sqlite-amalgamation-3290000.zip",
|
||||
"Version": "3.30.1",
|
||||
"DownloadLocation": "https://www.sqlite.org/2019/sqlite-amalgamation-3300100.zip",
|
||||
"License": "Public Domain",
|
||||
"Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed."
|
||||
}
|
||||
|
9188
src/3rdparty/sqlite/sqlite3.c
vendored
9188
src/3rdparty/sqlite/sqlite3.c
vendored
File diff suppressed because it is too large
Load Diff
81
src/3rdparty/sqlite/sqlite3.h
vendored
81
src/3rdparty/sqlite/sqlite3.h
vendored
@ -123,9 +123,9 @@ extern "C" {
|
||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.29.0"
|
||||
#define SQLITE_VERSION_NUMBER 3029000
|
||||
#define SQLITE_SOURCE_ID "2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6"
|
||||
#define SQLITE_VERSION "3.30.1"
|
||||
#define SQLITE_VERSION_NUMBER 3030001
|
||||
#define SQLITE_SOURCE_ID "2019-10-10 20:19:45 18db032d058f1436ce3dea84081f4ee5a0f2259ad97301d43c426bc7f3df1b0b"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
@ -2093,6 +2093,17 @@ struct sqlite3_mem_methods {
|
||||
** following this call. The second parameter may be a NULL pointer, in
|
||||
** which case the trigger setting is not reported back. </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_ENABLE_VIEW]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt>
|
||||
** <dd> ^This option is used to enable or disable [CREATE VIEW | views].
|
||||
** There should be two additional arguments.
|
||||
** The first argument is an integer which is 0 to disable views,
|
||||
** positive to enable views or negative to leave the setting unchanged.
|
||||
** The second parameter is a pointer to an integer into which
|
||||
** is written 0 or 1 to indicate whether views are disabled or enabled
|
||||
** following this call. The second parameter may be a NULL pointer, in
|
||||
** which case the view setting is not reported back. </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
|
||||
** <dd> ^This option is used to enable or disable the
|
||||
@ -2265,7 +2276,8 @@ struct sqlite3_mem_methods {
|
||||
#define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012 /* int int* */
|
||||
#define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */
|
||||
#define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1014 /* Largest DBCONFIG */
|
||||
#define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1015 /* Largest DBCONFIG */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Enable Or Disable Extended Result Codes
|
||||
@ -3814,7 +3826,7 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
|
||||
** ^The specific value of WHERE-clause [parameter] might influence the
|
||||
** choice of query plan if the parameter is the left-hand side of a [LIKE]
|
||||
** or [GLOB] operator or if the parameter is compared to an indexed column
|
||||
** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
|
||||
** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled.
|
||||
** </li>
|
||||
** </ol>
|
||||
**
|
||||
@ -4849,6 +4861,12 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
|
||||
** perform additional optimizations on deterministic functions, so use
|
||||
** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
|
||||
**
|
||||
** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY]
|
||||
** flag, which if present prevents the function from being invoked from
|
||||
** within VIEWs or TRIGGERs. For security reasons, the [SQLITE_DIRECTONLY]
|
||||
** flag is recommended for any application-defined SQL function that has
|
||||
** side-effects.
|
||||
**
|
||||
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
|
||||
** function can gain access to this pointer using [sqlite3_user_data()].)^
|
||||
**
|
||||
@ -4965,8 +4983,30 @@ SQLITE_API int sqlite3_create_window_function(
|
||||
** [SQLITE_UTF8 | preferred text encoding] as the fourth argument
|
||||
** to [sqlite3_create_function()], [sqlite3_create_function16()], or
|
||||
** [sqlite3_create_function_v2()].
|
||||
**
|
||||
** The SQLITE_DETERMINISTIC flag means that the new function will always
|
||||
** maps the same inputs into the same output. The abs() function is
|
||||
** deterministic, for example, but randomblob() is not.
|
||||
**
|
||||
** The SQLITE_DIRECTONLY flag means that the function may only be invoked
|
||||
** from top-level SQL, and cannot be used in VIEWs or TRIGGERs. This is
|
||||
** a security feature which is recommended for all
|
||||
** [application-defined SQL functions] that have side-effects. This flag
|
||||
** prevents an attacker from adding triggers and views to a schema then
|
||||
** tricking a high-privilege application into causing unintended side-effects
|
||||
** while performing ordinary queries.
|
||||
**
|
||||
** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call
|
||||
** [sqlite3_value_subtype()] to inspect the sub-types of its arguments.
|
||||
** Specifying this flag makes no difference for scalar or aggregate user
|
||||
** functions. However, if it is not specified for a user-defined window
|
||||
** function, then any sub-types belonging to arguments passed to the window
|
||||
** function may be discarded before the window function is called (i.e.
|
||||
** sqlite3_value_subtype() will always return 0).
|
||||
*/
|
||||
#define SQLITE_DETERMINISTIC 0x800
|
||||
#define SQLITE_DETERMINISTIC 0x000000800
|
||||
#define SQLITE_DIRECTONLY 0x000080000
|
||||
#define SQLITE_SUBTYPE 0x000100000
|
||||
|
||||
/*
|
||||
** CAPI3REF: Deprecated Functions
|
||||
@ -6612,6 +6652,12 @@ struct sqlite3_index_info {
|
||||
** ^The sqlite3_create_module()
|
||||
** interface is equivalent to sqlite3_create_module_v2() with a NULL
|
||||
** destructor.
|
||||
**
|
||||
** ^If the third parameter (the pointer to the sqlite3_module object) is
|
||||
** NULL then no new module is create and any existing modules with the
|
||||
** same name are dropped.
|
||||
**
|
||||
** See also: [sqlite3_drop_modules()]
|
||||
*/
|
||||
SQLITE_API int sqlite3_create_module(
|
||||
sqlite3 *db, /* SQLite connection to register module with */
|
||||
@ -6627,6 +6673,23 @@ SQLITE_API int sqlite3_create_module_v2(
|
||||
void(*xDestroy)(void*) /* Module destructor function */
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Remove Unnecessary Virtual Table Implementations
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The sqlite3_drop_modules(D,L) interface removes all virtual
|
||||
** table modules from database connection D except those named on list L.
|
||||
** The L parameter must be either NULL or a pointer to an array of pointers
|
||||
** to strings where the array is terminated by a single NULL pointer.
|
||||
** ^If the L parameter is NULL, then all virtual table modules are removed.
|
||||
**
|
||||
** See also: [sqlite3_create_module()]
|
||||
*/
|
||||
SQLITE_API int sqlite3_drop_modules(
|
||||
sqlite3 *db, /* Remove modules from this connection */
|
||||
const char **azKeep /* Except, do not remove the ones named here */
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Virtual Table Instance Object
|
||||
** KEYWORDS: sqlite3_vtab
|
||||
@ -7335,7 +7398,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
|
||||
#define SQLITE_TESTCTRL_FIRST 5
|
||||
#define SQLITE_TESTCTRL_PRNG_SAVE 5
|
||||
#define SQLITE_TESTCTRL_PRNG_RESTORE 6
|
||||
#define SQLITE_TESTCTRL_PRNG_RESET 7
|
||||
#define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */
|
||||
#define SQLITE_TESTCTRL_BITVEC_TEST 8
|
||||
#define SQLITE_TESTCTRL_FAULT_INSTALL 9
|
||||
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
|
||||
@ -7358,7 +7421,9 @@ SQLITE_API int sqlite3_test_control(int op, ...);
|
||||
#define SQLITE_TESTCTRL_IMPOSTER 25
|
||||
#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
|
||||
#define SQLITE_TESTCTRL_RESULT_INTREAL 27
|
||||
#define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */
|
||||
#define SQLITE_TESTCTRL_PRNG_SEED 28
|
||||
#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
|
||||
#define SQLITE_TESTCTRL_LAST 29 /* Largest TESTCTRL */
|
||||
|
||||
/*
|
||||
** CAPI3REF: SQL Keyword Checking
|
||||
|
@ -168,6 +168,9 @@ if (NOT ${PROJECT_NAME}-MultiAbiBuild)
|
||||
-D CMAKE_FIND_ROOT_PATH_MODE_INCLUDE=${CMAKE_FIND_ROOT_PATH_MODE_INCLUDE}
|
||||
-D CMAKE_FIND_ROOT_PATH_MODE_PACKAGE=${CMAKE_FIND_ROOT_PATH_MODE_PACKAGE}
|
||||
-D CMAKE_SHARED_LIBRARY_SUFFIX_CXX=_${android_abi}.so
|
||||
-D CMAKE_SHARED_MODULE_SUFFIX_CXX=_${android_abi}.so
|
||||
-D CMAKE_SHARED_LIBRARY_SUFFIX_C=_${android_abi}.so
|
||||
-D CMAKE_SHARED_MODULE_SUFFIX_C=_${android_abi}.so
|
||||
-D CMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_BINARY_DIR}/android-build/libs/${android_abi}
|
||||
-D ${PROJECT_NAME}-MultiAbiBuild=ON
|
||||
)
|
||||
@ -181,7 +184,10 @@ if (NOT ${PROJECT_NAME}-MultiAbiBuild)
|
||||
else()
|
||||
# For the default abi just use the regular cmake run, to have
|
||||
# nice IDE integration and so on
|
||||
set(CMAKE_SHARED_MODULE_SUFFIX_CXX "_${ANDROID_ABI}.so")
|
||||
set(CMAKE_SHARED_LIBRARY_SUFFIX_CXX "_${ANDROID_ABI}.so")
|
||||
set(CMAKE_SHARED_MODULE_SUFFIX_C "_${ANDROID_ABI}.so")
|
||||
set(CMAKE_SHARED_LIBRARY_SUFFIX_C "_${ANDROID_ABI}.so")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/android-build/libs/${ANDROID_ABI})
|
||||
endif()
|
||||
endforeach()
|
||||
|
@ -919,6 +919,16 @@ QThreadPrivate::~QThreadPrivate()
|
||||
delete data;
|
||||
}
|
||||
|
||||
void QThread::setStackSize(uint stackSize)
|
||||
{
|
||||
Q_UNUSED(stackSize);
|
||||
}
|
||||
|
||||
uint QThread::stackSize() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // QT_CONFIG(thread)
|
||||
|
||||
/*!
|
||||
|
@ -113,11 +113,12 @@ Qt::DropAction QDragManager::drag(QDrag *o)
|
||||
|
||||
m_object->d_func()->target = 0;
|
||||
|
||||
QGuiApplicationPrivate::instance()->notifyDragStarted(o);
|
||||
QGuiApplicationPrivate::instance()->notifyDragStarted(m_object.data());
|
||||
const Qt::DropAction result = m_platformDrag->drag(m_object);
|
||||
m_object = 0;
|
||||
if (!m_platformDrag->ownsDragObject())
|
||||
o->deleteLater();
|
||||
if (!m_object.isNull() && !m_platformDrag->ownsDragObject())
|
||||
m_object->deleteLater();
|
||||
|
||||
m_object.clear();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -101,13 +101,13 @@ public:
|
||||
void setCurrentTarget(QObject *target, bool dropped = false);
|
||||
QObject *currentTarget() const;
|
||||
|
||||
QDrag *object() const { return m_object; }
|
||||
QPointer<QDrag> object() const { return m_object; }
|
||||
QObject *source() const;
|
||||
|
||||
private:
|
||||
QObject *m_currentDropTarget;
|
||||
QPlatformDrag *m_platformDrag;
|
||||
QDrag *m_object;
|
||||
QPointer<QDrag> m_object;
|
||||
|
||||
static QDragManager *m_instance;
|
||||
Q_DISABLE_COPY_MOVE(QDragManager)
|
||||
|
@ -279,8 +279,11 @@ Qt::DropAction QDrag::exec(Qt::DropActions supportedActions, Qt::DropAction defa
|
||||
}
|
||||
d->supported_actions = supportedActions;
|
||||
d->default_action = transformedDefaultDropAction;
|
||||
d->executed_action = QDragManager::self()->drag(this);
|
||||
|
||||
QPointer<QDrag> self = this;
|
||||
auto executed_action = QDragManager::self()->drag(self.data());
|
||||
if (self.isNull())
|
||||
return Qt::IgnoreAction;
|
||||
d->executed_action = executed_action;
|
||||
return d->executed_action;
|
||||
}
|
||||
|
||||
|
@ -828,7 +828,8 @@ void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *ps, bool isPrima
|
||||
*/
|
||||
void QWindowSystemInterface::handleScreenRemoved(QPlatformScreen *platformScreen)
|
||||
{
|
||||
// Important to keep this order since the QSceen doesn't own the platform screen
|
||||
// Important to keep this order since the QSceen doesn't own the platform screen.
|
||||
// The QScreen destructor will take care changing the primary screen, so no need here.
|
||||
delete platformScreen->screen();
|
||||
delete platformScreen;
|
||||
}
|
||||
|
@ -1512,17 +1512,6 @@ bool QCocoaWindow::updatesWithDisplayLink() const
|
||||
|
||||
void QCocoaWindow::deliverUpdateRequest()
|
||||
{
|
||||
// Don't send update requests for views that need display, as the update
|
||||
// request doesn't carry any information about dirty rects, so the app
|
||||
// may end up painting a smaller region than required. (For some reason
|
||||
// the layer and view's needsDisplay status isn't always in sync, even if
|
||||
// the view is layer-backed, not layer-hosted, so we check both).
|
||||
if (m_view.layer.needsDisplay || m_view.needsDisplay) {
|
||||
qCDebug(lcQpaDrawing) << "View needs display, deferring update request for" << window();
|
||||
requestUpdate();
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(lcQpaDrawing) << "Delivering update request to" << window();
|
||||
QPlatformWindow::deliverUpdateRequest();
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
<body onload="init()">
|
||||
<figure style="overflow:visible;" id="qtspinner">
|
||||
<center style="margin-top:1.5em; line-height:150%">
|
||||
<img src="qtlogo.svg"; width=320; height=200; style="display:block"> </img>
|
||||
<img src="qtlogo.svg" width="320" height="200" style="display:block"></img>
|
||||
<strong>Qt for WebAssembly: @APPNAME@</strong>
|
||||
<div id="qtstatus"></div>
|
||||
<noscript>JavaScript is disabled. Please enable JavaScript to use this application.</noscript>
|
||||
|
@ -354,6 +354,11 @@ bool QXcbDrag::findXdndAwareTarget(const QPoint &globalPos, xcb_window_t *target
|
||||
|
||||
void QXcbDrag::move(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
|
||||
{
|
||||
// currentDrag() might be deleted while 'drag' is progressing
|
||||
if (!currentDrag()) {
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
// The source sends XdndEnter and XdndPosition to the target.
|
||||
if (source_sameanswer.contains(globalPos) && source_sameanswer.isValid())
|
||||
return;
|
||||
@ -1076,7 +1081,8 @@ void QXcbDrag::cancel()
|
||||
send_leave();
|
||||
|
||||
// remove canceled object
|
||||
currentDrag()->deleteLater();
|
||||
if (currentDrag())
|
||||
currentDrag()->deleteLater();
|
||||
|
||||
canceled = true;
|
||||
}
|
||||
|
@ -1528,7 +1528,7 @@ void TestMethods::invokeTests(QObject *testObject) const
|
||||
QTestResult::setCurrentTestFunction(nullptr);
|
||||
}
|
||||
|
||||
#if defined(Q_OS_UNIX)
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_WASM)
|
||||
class FatalSignalHandler
|
||||
{
|
||||
public:
|
||||
@ -1928,7 +1928,7 @@ int QTest::qRun()
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#if defined(Q_OS_UNIX)
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_WASM)
|
||||
QScopedPointer<FatalSignalHandler> handler;
|
||||
if (!noCrashHandler)
|
||||
handler.reset(new FatalSignalHandler);
|
||||
|
@ -504,7 +504,7 @@ void QWellArray::keyPressEvent(QKeyEvent* e)
|
||||
// Event filter to be installed on the dialog while in color-picking mode.
|
||||
class QColorPickingEventFilter : public QObject {
|
||||
public:
|
||||
explicit QColorPickingEventFilter(QColorDialogPrivate *dp, QObject *parent = 0) : QObject(parent), m_dp(dp) {}
|
||||
explicit QColorPickingEventFilter(QColorDialogPrivate *dp, QObject *parent) : QObject(parent), m_dp(dp) {}
|
||||
|
||||
bool eventFilter(QObject *, QEvent *event) override
|
||||
{
|
||||
@ -1611,7 +1611,7 @@ void QColorDialogPrivate::_q_pickScreenColor()
|
||||
{
|
||||
Q_Q(QColorDialog);
|
||||
if (!colorPickingEventFilter)
|
||||
colorPickingEventFilter = new QColorPickingEventFilter(this);
|
||||
colorPickingEventFilter = new QColorPickingEventFilter(this, q);
|
||||
q->installEventFilter(colorPickingEventFilter);
|
||||
// If user pushes Escape, the last color before picking will be restored.
|
||||
beforeScreenColorPicking = cs->currentColor();
|
||||
|
@ -4550,6 +4550,8 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
/*!
|
||||
\obsolete
|
||||
|
||||
@ -4588,6 +4590,7 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
|
||||
// Send post-notification.
|
||||
itemChange(ItemTransformHasChanged, QVariant::fromValue<QTransform>(newTransform));
|
||||
}
|
||||
QT_WARNING_POP
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@ -11524,9 +11527,12 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemChange change)
|
||||
str = "ItemFlagsHaveChanged";
|
||||
break;
|
||||
#if QT_DEPRECATED_SINCE(5, 14)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
case QGraphicsItem::ItemMatrixChange:
|
||||
str = "ItemMatrixChange";
|
||||
break;
|
||||
QT_WARNING_POP
|
||||
#endif
|
||||
case QGraphicsItem::ItemParentChange:
|
||||
str = "ItemParentChange";
|
||||
|
@ -35,59 +35,106 @@
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
namespace {
|
||||
template <typename F> struct Fuzzy {};
|
||||
/* Data taken from qglobal.h's implementation of qFuzzyCompare:
|
||||
* qFuzzyCompare conflates values with fractional difference up to (and
|
||||
* including) the given scale.
|
||||
*/
|
||||
template <> struct Fuzzy<double> { constexpr static double scale = 1e12; };
|
||||
template <> struct Fuzzy<float> { constexpr static float scale = 1e5f; };
|
||||
}
|
||||
|
||||
class tst_QNumeric: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void fuzzyCompare_data();
|
||||
void fuzzyCompare();
|
||||
void rawNaN_data();
|
||||
void rawNaN();
|
||||
// Support for floating-point:
|
||||
template<typename F> inline void fuzzyCompare_data();
|
||||
template<typename F> inline void fuzzyCompare();
|
||||
template<typename F> inline void checkNaN(F nan);
|
||||
template<typename F> inline void rawNaN_data();
|
||||
template<typename F> inline void rawNaN();
|
||||
#if QT_CONFIG(signaling_nan)
|
||||
void distinctNaN();
|
||||
template<typename F> inline void distinctNaN();
|
||||
#endif
|
||||
void generalNaN_data();
|
||||
void generalNaN();
|
||||
void infinity();
|
||||
void classifyfp();
|
||||
void floatDistance_data();
|
||||
void floatDistance();
|
||||
void floatDistance_double_data();
|
||||
void floatDistance_double();
|
||||
template<typename F, typename Whole> inline void generalNaN_data();
|
||||
template<typename F, typename Whole> inline void generalNaN();
|
||||
template<typename F> inline void infinity();
|
||||
template<typename F> inline void classifyfp();
|
||||
template<typename F, typename Count> inline void distance_data();
|
||||
template<typename F, typename Count> inline void distance();
|
||||
|
||||
private slots:
|
||||
// Floating-point tests:
|
||||
void fuzzyCompareF_data() { fuzzyCompare_data<float>(); }
|
||||
void fuzzyCompareF() { fuzzyCompare<float>(); }
|
||||
void fuzzyCompareD_data() { fuzzyCompare_data<double>(); }
|
||||
void fuzzyCompareD() { fuzzyCompare<double>(); }
|
||||
void rawNaNF_data() { rawNaN_data<float>(); }
|
||||
void rawNaNF() { rawNaN<float>(); }
|
||||
void rawNaND_data() { rawNaN_data<double>(); }
|
||||
void rawNaND() { rawNaN<double>(); }
|
||||
#if QT_CONFIG(signaling_nan)
|
||||
void distinctNaNF();
|
||||
void distinctNaND() { distinctNaN<double>(); }
|
||||
#endif
|
||||
void generalNaNd_data() { generalNaN_data<double, quint64>(); }
|
||||
void generalNaNd() { generalNaN<double, quint64>(); }
|
||||
void generalNaNf_data() { generalNaN_data<float, quint32>(); }
|
||||
void generalNaNf() { generalNaN<float, quint32>(); }
|
||||
void infinityF() { infinity<float>(); }
|
||||
void infinityD() { infinity<double>(); }
|
||||
void classifyF() { classifyfp<float>(); }
|
||||
void classifyD() { classifyfp<double>(); }
|
||||
void floatDistance_data() { distance_data<float, quint32>(); }
|
||||
void floatDistance() { distance<float, quint32>(); }
|
||||
void doubleDistance_data() { distance_data<double, quint64>(); }
|
||||
void doubleDistance() { distance<double, quint64>(); }
|
||||
|
||||
// Whole number tests:
|
||||
void addOverflow_data();
|
||||
void addOverflow();
|
||||
void mulOverflow_data();
|
||||
void mulOverflow();
|
||||
void signedOverflow();
|
||||
private:
|
||||
void checkNaN(double nan);
|
||||
};
|
||||
|
||||
// Floating-point tests:
|
||||
|
||||
template<typename F>
|
||||
void tst_QNumeric::fuzzyCompare_data()
|
||||
{
|
||||
QTest::addColumn<double>("val1");
|
||||
QTest::addColumn<double>("val2");
|
||||
QTest::addColumn<F>("val1");
|
||||
QTest::addColumn<F>("val2");
|
||||
QTest::addColumn<bool>("isEqual");
|
||||
const F zero(0), one(1), ten(10);
|
||||
const F huge = Fuzzy<F>::scale, tiny = one / huge;
|
||||
const F deci(.1), giga(1e9), nano(1e-9), big(1e7), small(1e-10);
|
||||
|
||||
QTest::newRow("zero") << 0.0 << 0.0 << true;
|
||||
QTest::newRow("ten") << 10.0 << 10.0 << true;
|
||||
QTest::newRow("large") << 1000000000.0 << 1000000000.0 << true;
|
||||
QTest::newRow("small") << 0.00000000001 << 0.00000000001 << true;
|
||||
QTest::newRow("eps") << 10.000000000000001 << 10.00000000000002 << true;
|
||||
QTest::newRow("eps2") << 10.000000000000001 << 10.000000000000009 << true;
|
||||
QTest::newRow("zero") << zero << zero << true;
|
||||
QTest::newRow("ten") << ten << ten << true;
|
||||
QTest::newRow("large") << giga << giga << true;
|
||||
QTest::newRow("small") << small << small << true;
|
||||
QTest::newRow("10+9*tiny==10") << (ten + 9 * tiny) << ten << true;
|
||||
QTest::newRow("huge+.9==huge") << (huge + 9 * deci) << huge << true;
|
||||
QTest::newRow("eps2") << (ten + tiny) << (ten + 2 * tiny) << true;
|
||||
QTest::newRow("eps9") << (ten + tiny) << (ten + 9 * tiny) << true;
|
||||
|
||||
QTest::newRow("mis1") << 0.0 << 1.0 << false;
|
||||
QTest::newRow("mis2") << 0.0 << 10000000.0 << false;
|
||||
QTest::newRow("mis3") << 0.0 << 0.000000001 << false;
|
||||
QTest::newRow("mis4") << 100000000.0 << 0.000000001 << false;
|
||||
QTest::newRow("mis5") << 0.0000000001 << 0.000000001 << false;
|
||||
QTest::newRow("0!=1") << zero << one << false;
|
||||
QTest::newRow("0!=big") << zero << big << false;
|
||||
QTest::newRow("0!=nano") << zero << nano << false;
|
||||
QTest::newRow("giga!=nano") << giga << nano << false;
|
||||
QTest::newRow("small!=nano") << small << nano << false;
|
||||
QTest::newRow("huge+1.1!=huge") << (huge + 1 + deci) << huge << false;
|
||||
QTest::newRow("1+1.1*tiny!=1") << (one + tiny * (one + deci)) << one << false;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void tst_QNumeric::fuzzyCompare()
|
||||
{
|
||||
QFETCH(double, val1);
|
||||
QFETCH(double, val2);
|
||||
QFETCH(F, val1);
|
||||
QFETCH(F, val2);
|
||||
QFETCH(bool, isEqual);
|
||||
|
||||
QCOMPARE(::qFuzzyCompare(val1, val2), isEqual);
|
||||
@ -101,11 +148,12 @@ void tst_QNumeric::fuzzyCompare()
|
||||
# pragma GCC optimize "no-fast-math"
|
||||
#endif
|
||||
|
||||
void tst_QNumeric::checkNaN(double nan)
|
||||
template<typename F>
|
||||
void tst_QNumeric::checkNaN(F nan)
|
||||
{
|
||||
#define CHECKNAN(value) \
|
||||
do { \
|
||||
const double v = (value); \
|
||||
const F v = (value); \
|
||||
QCOMPARE(qFpClassify(v), FP_NAN); \
|
||||
QVERIFY(qIsNaN(v)); \
|
||||
QVERIFY(!qIsFinite(v)); \
|
||||
@ -134,211 +182,197 @@ void tst_QNumeric::checkNaN(double nan)
|
||||
#undef CHECKNAN
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void tst_QNumeric::rawNaN_data()
|
||||
{
|
||||
#if defined __FAST_MATH__ && (__GNUC__ * 100 + __GNUC_MINOR__ < 404)
|
||||
QSKIP("Non-conformant fast math mode is enabled, cannot run test");
|
||||
#endif
|
||||
QTest::addColumn<double>("nan");
|
||||
QTest::addColumn<F>("nan");
|
||||
|
||||
QTest::newRow("quiet") << qQNaN();
|
||||
QTest::newRow("quiet") << F(qQNaN());
|
||||
#if QT_CONFIG(signaling_nan)
|
||||
QTest::newRow("signaling") << qSNaN();
|
||||
QTest::newRow("signaling") << F(qSNaN());
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void tst_QNumeric::rawNaN()
|
||||
{
|
||||
QFETCH(double, nan);
|
||||
QFETCH(F, nan);
|
||||
#ifdef Q_OS_WASM
|
||||
# ifdef __asmjs
|
||||
QEXPECT_FAIL("", "Fastcomp conflates quiet and signaling NaNs", Continue);
|
||||
# endif // but the modern clang compiler handls it fine.
|
||||
#endif
|
||||
checkNaN(nan);
|
||||
}
|
||||
|
||||
#if QT_CONFIG(signaling_nan)
|
||||
template<typename F>
|
||||
void tst_QNumeric::distinctNaN()
|
||||
{
|
||||
const double qnan = qQNaN();
|
||||
const double snan = qSNaN();
|
||||
QVERIFY(memcmp(&qnan, &snan, sizeof(double)) != 0);
|
||||
const F qnan = qQNaN();
|
||||
const F snan = qSNaN();
|
||||
QVERIFY(memcmp(&qnan, &snan, sizeof(F)) != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void tst_QNumeric::distinctNaNF() {
|
||||
#ifdef Q_CC_MSVC
|
||||
QEXPECT_FAIL("", "MSVC's float conflates quiet and signaling NaNs", Continue);
|
||||
#endif
|
||||
distinctNaN<float>();
|
||||
}
|
||||
#endif // signaling_nan
|
||||
|
||||
template<typename F, typename Whole>
|
||||
void tst_QNumeric::generalNaN_data()
|
||||
{
|
||||
QTest::addColumn<int>("most");
|
||||
QTest::addColumn<int>("next");
|
||||
QTest::addColumn<int>("least");
|
||||
Q_STATIC_ASSERT(sizeof(F) == sizeof(Whole));
|
||||
QTest::addColumn<Whole>("whole");
|
||||
// Every value with every bit of the exponent set is a NaN.
|
||||
// Sign and mantissa can be anything without interfering with that.
|
||||
// The 0x7f bits of most and the 0xf0 bits of next are the exponent.
|
||||
using Bounds = std::numeric_limits<F>;
|
||||
// Bounds::digits is one more than the number of bits used to encode the mantissa:
|
||||
const int mantissaBits = Bounds::digits - 1;
|
||||
// One bit for sign, the rest are mantissa and exponent:
|
||||
const int exponentBits = sizeof(F) * CHAR_BIT - 1 - mantissaBits;
|
||||
|
||||
QTest::newRow("lowload") << 0x7f << 0xf0 << 1;
|
||||
QTest::newRow("sign-lowload") << 0xff << 0xf0 << 1;
|
||||
QTest::newRow("highload") << 0x7f << 0xf1 << 0;
|
||||
QTest::newRow("sign-highload") << 0xff << 0xf1 << 0;
|
||||
const Whole exponent = ((Whole(1) << exponentBits) - 1) << mantissaBits;
|
||||
const Whole sign = Whole(1) << (exponentBits + mantissaBits);
|
||||
const Whole mantissaTop = Whole(1) << (mantissaBits - 1);
|
||||
|
||||
QTest::newRow("lowload") << (exponent | 1);
|
||||
QTest::newRow("sign-lowload") << (sign | exponent | 1);
|
||||
QTest::newRow("highload") << (exponent | mantissaTop);
|
||||
QTest::newRow("sign-highload") << (sign | exponent | mantissaTop);
|
||||
}
|
||||
|
||||
template<typename F, typename Whole>
|
||||
void tst_QNumeric::generalNaN()
|
||||
{
|
||||
QFETCH(int, most);
|
||||
QFETCH(int, next);
|
||||
QFETCH(int, least);
|
||||
double nan;
|
||||
Q_STATIC_ASSERT(sizeof(double) == 8);
|
||||
#ifdef Q_LITTLE_ENDIAN
|
||||
const uchar bytes[] = { uchar(least), 0, 0, 0, 0, 0, uchar(next), uchar(most) };
|
||||
#else
|
||||
const uchar bytes[] = { uchar(most), uchar(next), 0, 0, 0, 0, 0, uchar(least) };
|
||||
#endif
|
||||
memcpy(&nan, bytes, 8);
|
||||
Q_STATIC_ASSERT(sizeof(F) == sizeof(Whole));
|
||||
QFETCH(const Whole, whole);
|
||||
F nan;
|
||||
memcpy(&nan, &whole, sizeof(F));
|
||||
checkNaN(nan);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void tst_QNumeric::infinity()
|
||||
{
|
||||
const double inf = qInf();
|
||||
QVERIFY(inf > 0);
|
||||
QVERIFY(-inf < 0);
|
||||
const F inf = qInf();
|
||||
const F zero(0), one(1), two(2);
|
||||
QVERIFY(inf > zero);
|
||||
QVERIFY(-inf < zero);
|
||||
QVERIFY(qIsInf(inf));
|
||||
QCOMPARE(inf, inf);
|
||||
QCOMPARE(-inf, -inf);
|
||||
QVERIFY(qIsInf(-inf));
|
||||
QVERIFY(qIsInf(inf + 1));
|
||||
QVERIFY(qIsInf(inf - 1));
|
||||
QVERIFY(qIsInf(-inf - 1));
|
||||
QVERIFY(qIsInf(-inf + 1));
|
||||
QVERIFY(qIsInf(inf * 2.0));
|
||||
QVERIFY(qIsInf(-inf * 2.0));
|
||||
QVERIFY(qIsInf(inf / 2.0));
|
||||
QVERIFY(qIsInf(-inf / 2.0));
|
||||
QVERIFY(qFuzzyCompare(1.0 / inf, 0.0));
|
||||
QVERIFY(qIsInf(inf + one));
|
||||
QVERIFY(qIsInf(inf - one));
|
||||
QVERIFY(qIsInf(-inf - one));
|
||||
QVERIFY(qIsInf(-inf + one));
|
||||
QVERIFY(qIsInf(inf * two));
|
||||
QVERIFY(qIsInf(-inf * two));
|
||||
QVERIFY(qIsInf(inf / two));
|
||||
QVERIFY(qIsInf(-inf / two));
|
||||
QVERIFY(qFuzzyCompare(one / inf, zero));
|
||||
QCOMPARE(1.0 / inf, 0.0);
|
||||
QVERIFY(qFuzzyCompare(1.0 / -inf, 0.0));
|
||||
QCOMPARE(1.0 / -inf, 0.0);
|
||||
QVERIFY(qIsNaN(0.0 * inf));
|
||||
QVERIFY(qIsNaN(0.0 * -inf));
|
||||
QVERIFY(qFuzzyCompare(one / -inf, zero));
|
||||
QCOMPARE(one / -inf, zero);
|
||||
QVERIFY(qIsNaN(zero * inf));
|
||||
QVERIFY(qIsNaN(zero * -inf));
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void tst_QNumeric::classifyfp()
|
||||
{
|
||||
using Bounds = std::numeric_limits<F>;
|
||||
const F huge = Bounds::max();
|
||||
const F tiny = Bounds::min();
|
||||
// NaNs already handled, see checkNaN()'s callers.
|
||||
const F one(1), two(2), inf(qInf());
|
||||
|
||||
QCOMPARE(qFpClassify(qInf()), FP_INFINITE);
|
||||
QCOMPARE(qFpClassify(-qInf()), FP_INFINITE);
|
||||
QCOMPARE(qFpClassify(DBL_MAX * 2.0), FP_INFINITE);
|
||||
QCOMPARE(qFpClassify(FLT_MAX * 2.f), FP_INFINITE);
|
||||
QCOMPARE(qFpClassify(DBL_MAX * -2.0), FP_INFINITE);
|
||||
QCOMPARE(qFpClassify(FLT_MAX * -2.f), FP_INFINITE);
|
||||
QCOMPARE(qFpClassify(inf), FP_INFINITE);
|
||||
QCOMPARE(qFpClassify(-inf), FP_INFINITE);
|
||||
QCOMPARE(qFpClassify(huge * two), FP_INFINITE);
|
||||
QCOMPARE(qFpClassify(huge * -two), FP_INFINITE);
|
||||
|
||||
QCOMPARE(qFpClassify(1.0), FP_NORMAL);
|
||||
QCOMPARE(qFpClassify(DBL_MAX), FP_NORMAL);
|
||||
QCOMPARE(qFpClassify(-DBL_MAX), FP_NORMAL);
|
||||
QCOMPARE(qFpClassify(DBL_MIN), FP_NORMAL);
|
||||
QCOMPARE(qFpClassify(-DBL_MIN), FP_NORMAL);
|
||||
QCOMPARE(qFpClassify(DBL_MIN / 2.0), FP_SUBNORMAL);
|
||||
QCOMPARE(qFpClassify(DBL_MIN / -2.0), FP_SUBNORMAL);
|
||||
|
||||
QCOMPARE(qFpClassify(1.f), FP_NORMAL);
|
||||
QCOMPARE(qFpClassify(FLT_MAX), FP_NORMAL);
|
||||
QCOMPARE(qFpClassify(-FLT_MAX), FP_NORMAL);
|
||||
QCOMPARE(qFpClassify(FLT_MIN), FP_NORMAL);
|
||||
QCOMPARE(qFpClassify(-FLT_MIN), FP_NORMAL);
|
||||
QCOMPARE(qFpClassify(FLT_MIN / 2.f), FP_SUBNORMAL);
|
||||
QCOMPARE(qFpClassify(FLT_MIN / -2.f), FP_SUBNORMAL);
|
||||
QCOMPARE(qFpClassify(one), FP_NORMAL);
|
||||
QCOMPARE(qFpClassify(huge), FP_NORMAL);
|
||||
QCOMPARE(qFpClassify(-huge), FP_NORMAL);
|
||||
QCOMPARE(qFpClassify(tiny), FP_NORMAL);
|
||||
QCOMPARE(qFpClassify(-tiny), FP_NORMAL);
|
||||
if (Bounds::has_denorm == std::denorm_present) {
|
||||
QCOMPARE(qFpClassify(tiny / two), FP_SUBNORMAL);
|
||||
QCOMPARE(qFpClassify(tiny / -two), FP_SUBNORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QNumeric::floatDistance_data()
|
||||
template<typename F, typename Count>
|
||||
void tst_QNumeric::distance_data()
|
||||
{
|
||||
QTest::addColumn<float>("val1");
|
||||
QTest::addColumn<float>("val2");
|
||||
QTest::addColumn<quint32>("expectedDistance");
|
||||
using Bounds = std::numeric_limits<F>;
|
||||
const F huge = Bounds::max();
|
||||
const F tiny = Bounds::min();
|
||||
|
||||
// exponent: 8 bits
|
||||
// mantissa: 23 bits
|
||||
const quint32 number_of_denormals = (1 << 23) - 1; // Set to 0 if denormals are not included
|
||||
QTest::addColumn<F>("from");
|
||||
QTest::addColumn<F>("stop");
|
||||
QTest::addColumn<Count>("expectedDistance");
|
||||
|
||||
quint32 _0_to_1 = quint32((1 << 23) * 126 + 1 + number_of_denormals); // We need +1 to include the 0
|
||||
quint32 _1_to_2 = quint32(1 << 23);
|
||||
using Bounds = std::numeric_limits<F>;
|
||||
const int mantissaBits = Bounds::digits - 1;
|
||||
const int exponentBits = sizeof(F) * CHAR_BIT - 1 - mantissaBits;
|
||||
|
||||
// We don't need +1 because FLT_MAX has all bits set in the mantissa. (Thus mantissa
|
||||
// Set to 1 and 0 if denormals are not included:
|
||||
const Count count_0_to_tiny = Count(1) << mantissaBits;
|
||||
const Count count_denormals = count_0_to_tiny - 1;
|
||||
|
||||
// We need +1 to include the 0:
|
||||
const Count count_0_to_1
|
||||
= (Count(1) << mantissaBits) * ((Count(1) << (exponentBits - 1)) - 2)
|
||||
+ 1 + count_denormals;
|
||||
const Count count_1_to_2 = Count(1) << mantissaBits;
|
||||
|
||||
// We don't need +1 because huge has all bits set in the mantissa. (Thus mantissa
|
||||
// have not wrapped back to 0, which would be the case for 1 in _0_to_1
|
||||
quint32 _0_to_FLT_MAX = quint32((1 << 23) * 254) + number_of_denormals;
|
||||
const Count count_0_to_huge
|
||||
= (Count(1) << mantissaBits) * ((Count(1) << exponentBits) - 2)
|
||||
+ count_denormals;
|
||||
|
||||
quint32 _0_to_FLT_MIN = 1 + number_of_denormals;
|
||||
QTest::newRow("[0,FLT_MIN]") << 0.F << FLT_MIN << _0_to_FLT_MIN;
|
||||
QTest::newRow("[0,FLT_MAX]") << 0.F << FLT_MAX << _0_to_FLT_MAX;
|
||||
QTest::newRow("[1,1.5]") << 1.0F << 1.5F << quint32(1 << 22);
|
||||
QTest::newRow("[0,1]") << 0.F << 1.0F << _0_to_1;
|
||||
QTest::newRow("[0.5,1]") << 0.5F << 1.0F << quint32(1 << 23);
|
||||
QTest::newRow("[1,2]") << 1.F << 2.0F << _1_to_2;
|
||||
QTest::newRow("[-1,+1]") << -1.F << +1.0F << 2 * _0_to_1;
|
||||
QTest::newRow("[-1,0]") << -1.F << 0.0F << _0_to_1;
|
||||
QTest::newRow("[-1,FLT_MAX]") << -1.F << FLT_MAX << _0_to_1 + _0_to_FLT_MAX;
|
||||
QTest::newRow("[-2,-1") << -2.F << -1.F << _1_to_2;
|
||||
QTest::newRow("[-1,-2") << -1.F << -2.F << _1_to_2;
|
||||
QTest::newRow("[FLT_MIN,FLT_MAX]") << FLT_MIN << FLT_MAX << _0_to_FLT_MAX - _0_to_FLT_MIN;
|
||||
QTest::newRow("[-FLT_MAX,FLT_MAX]") << -FLT_MAX << FLT_MAX << (2*_0_to_FLT_MAX);
|
||||
float denormal = FLT_MIN;
|
||||
denormal/=2.0F;
|
||||
QTest::newRow("denormal") << 0.F << denormal << _0_to_FLT_MIN/2;
|
||||
const F zero(0), half(.5), one(1), sesqui(1.5), two(2);
|
||||
const F denormal = tiny / two;
|
||||
|
||||
QTest::newRow("[0,tiny]") << zero << tiny << count_0_to_tiny;
|
||||
QTest::newRow("[0,huge]") << zero << huge << count_0_to_huge;
|
||||
QTest::newRow("[1,1.5]") << one << sesqui << (Count(1) << (mantissaBits - 1));
|
||||
QTest::newRow("[0,1]") << zero << one << count_0_to_1;
|
||||
QTest::newRow("[0.5,1]") << half << one << (Count(1) << mantissaBits);
|
||||
QTest::newRow("[1,2]") << one << two << count_1_to_2;
|
||||
QTest::newRow("[-1,+1]") << -one << +one << 2 * count_0_to_1;
|
||||
QTest::newRow("[-1,0]") << -one << zero << count_0_to_1;
|
||||
QTest::newRow("[-1,huge]") << -one << huge << count_0_to_1 + count_0_to_huge;
|
||||
QTest::newRow("[-2,-1") << -two << -one << count_1_to_2;
|
||||
QTest::newRow("[-1,-2") << -one << -two << count_1_to_2;
|
||||
QTest::newRow("[tiny,huge]") << tiny << huge << count_0_to_huge - count_0_to_tiny;
|
||||
QTest::newRow("[-huge,huge]") << -huge << huge << (2 * count_0_to_huge);
|
||||
QTest::newRow("denormal") << zero << denormal << count_0_to_tiny / 2;
|
||||
}
|
||||
|
||||
void tst_QNumeric::floatDistance()
|
||||
template<typename F, typename Count>
|
||||
void tst_QNumeric::distance()
|
||||
{
|
||||
QFETCH(float, val1);
|
||||
QFETCH(float, val2);
|
||||
QFETCH(quint32, expectedDistance);
|
||||
QFETCH(F, from);
|
||||
QFETCH(F, stop);
|
||||
QFETCH(Count, expectedDistance);
|
||||
#ifdef Q_OS_QNX
|
||||
QEXPECT_FAIL("denormal", "See QTBUG-37094", Continue);
|
||||
#endif
|
||||
QCOMPARE(qFloatDistance(val1, val2), expectedDistance);
|
||||
QCOMPARE(qFloatDistance(from, stop), expectedDistance);
|
||||
}
|
||||
|
||||
void tst_QNumeric::floatDistance_double_data()
|
||||
{
|
||||
QTest::addColumn<double>("val1");
|
||||
QTest::addColumn<double>("val2");
|
||||
QTest::addColumn<quint64>("expectedDistance");
|
||||
|
||||
// exponent: 11 bits
|
||||
// mantissa: 52 bits
|
||||
const quint64 number_of_denormals = (Q_UINT64_C(1) << 52) - 1; // Set to 0 if denormals are not included
|
||||
|
||||
quint64 _0_to_1 = (Q_UINT64_C(1) << 52) * ((1 << (11-1)) - 2) + 1 + number_of_denormals; // We need +1 to include the 0
|
||||
quint64 _1_to_2 = Q_UINT64_C(1) << 52;
|
||||
|
||||
// We don't need +1 because DBL_MAX has all bits set in the mantissa. (Thus mantissa
|
||||
// have not wrapped back to 0, which would be the case for 1 in _0_to_1
|
||||
quint64 _0_to_DBL_MAX = quint64((Q_UINT64_C(1) << 52) * ((1 << 11) - 2)) + number_of_denormals;
|
||||
|
||||
quint64 _0_to_DBL_MIN = 1 + number_of_denormals;
|
||||
QTest::newRow("[0,DBL_MIN]") << 0.0 << DBL_MIN << _0_to_DBL_MIN;
|
||||
QTest::newRow("[0,DBL_MAX]") << 0.0 << DBL_MAX << _0_to_DBL_MAX;
|
||||
QTest::newRow("[1,1.5]") << 1.0 << 1.5 << (Q_UINT64_C(1) << 51);
|
||||
QTest::newRow("[0,1]") << 0.0 << 1.0 << _0_to_1;
|
||||
QTest::newRow("[0.5,1]") << 0.5 << 1.0 << (Q_UINT64_C(1) << 52);
|
||||
QTest::newRow("[1,2]") << 1.0 << 2.0 << _1_to_2;
|
||||
QTest::newRow("[-1,+1]") << -1.0 << +1.0 << 2 * _0_to_1;
|
||||
QTest::newRow("[-1,0]") << -1.0 << 0.0 << _0_to_1;
|
||||
QTest::newRow("[-1,DBL_MAX]") << -1.0 << DBL_MAX << _0_to_1 + _0_to_DBL_MAX;
|
||||
QTest::newRow("[-2,-1") << -2.0 << -1.0 << _1_to_2;
|
||||
QTest::newRow("[-1,-2") << -1.0 << -2.0 << _1_to_2;
|
||||
QTest::newRow("[DBL_MIN,DBL_MAX]") << DBL_MIN << DBL_MAX << _0_to_DBL_MAX - _0_to_DBL_MIN;
|
||||
QTest::newRow("[-DBL_MAX,DBL_MAX]") << -DBL_MAX << DBL_MAX << (2*_0_to_DBL_MAX);
|
||||
double denormal = DBL_MIN;
|
||||
denormal/=2.0;
|
||||
QTest::newRow("denormal") << 0.0 << denormal << _0_to_DBL_MIN/2;
|
||||
}
|
||||
|
||||
void tst_QNumeric::floatDistance_double()
|
||||
{
|
||||
QFETCH(double, val1);
|
||||
QFETCH(double, val2);
|
||||
QFETCH(quint64, expectedDistance);
|
||||
#ifdef Q_OS_QNX
|
||||
QEXPECT_FAIL("denormal", "See QTBUG-37094", Continue);
|
||||
#endif
|
||||
QCOMPARE(qFloatDistance(val1, val2), expectedDistance);
|
||||
}
|
||||
// Whole number tests:
|
||||
|
||||
void tst_QNumeric::addOverflow_data()
|
||||
{
|
||||
|
@ -27,13 +27,8 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <QtGui/QBitmap>
|
||||
#include <QtGui/QPalette>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QPicture>
|
||||
#include <QtGui/QTextLength>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QPen>
|
||||
#include <QtGui/QImage>
|
||||
|
||||
class tst_QDataStream : public QObject
|
||||
{
|
||||
@ -41,16 +36,20 @@ Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void stream_with_pixmap();
|
||||
|
||||
};
|
||||
|
||||
void tst_QDataStream::stream_with_pixmap()
|
||||
{
|
||||
// This is a QVariantMap with a 3x3 red QPixmap and two strings inside
|
||||
const QByteArray ba = QByteArray::fromBase64("AAAAAwAAAAIAegAAAAoAAAAACgB0AGgAZQByAGUAAAACAHAAAABBAAAAAAGJUE5HDQoaCgAAAA1JSERSAAAAAwAAAAMIAgAAANlKIugAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAQSURBVAiZY/zPAAVMDJgsAB1bAQXZn5ieAAAAAElFTkSuQmCCAAAAAgBhAAAACgAAAAAKAGgAZQBsAGwAbw==");
|
||||
const QByteArray ba = QByteArray::fromBase64(
|
||||
"AAAAAwAAAAIAegAAAAoAAAAACgB0AGgAZQByAGUAAAACAHAAAABBAAAAAAGJUE5H"
|
||||
"DQoaCgAAAA1JSERSAAAAAwAAAAMIAgAAANlKIugAAAAJcEhZcwAADsQAAA7EAZUr"
|
||||
"DhsAAAAQSURBVAiZY/zPAAVMDJgsAB1bAQXZn5ieAAAAAElFTkSuQmCCAAAAAgBh"
|
||||
"AAAACgAAAAAKAGgAZQBsAGwAbw==");
|
||||
QImage dummy; // Needed to make sure qtGui is loaded
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication");
|
||||
QTest::ignoreMessage(QtWarningMsg, "QPixmap::fromImageInPlace: "
|
||||
"QPixmap cannot be created without a QGuiApplication");
|
||||
|
||||
QVariantMap map;
|
||||
QDataStream d(ba);
|
||||
@ -58,11 +57,11 @@ void tst_QDataStream::stream_with_pixmap()
|
||||
d >> map;
|
||||
|
||||
QCOMPARE(map["a"].toString(), QString("hello"));
|
||||
QCOMPARE(map["p"].value<QPixmap>(), QPixmap()); // the pixmap is null because this is not a QGuiApplication
|
||||
// The pixmap is null because this is not a QGuiApplication:
|
||||
QCOMPARE(map["p"].value<QPixmap>(), QPixmap());
|
||||
QCOMPARE(map["z"].toString(), QString("there"));
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(tst_QDataStream)
|
||||
|
||||
#include "tst_qdatastream_core_pixmap.moc"
|
||||
|
||||
|
@ -11,7 +11,8 @@ SUBDIRS = \
|
||||
qxmlstream
|
||||
|
||||
!qtHaveModule(gui): SUBDIRS -= \
|
||||
qdatastream
|
||||
qdatastream \
|
||||
qdatastream_core_pixmap
|
||||
|
||||
!qtHaveModule(network): SUBDIRS -= \
|
||||
qtextstream
|
||||
|
@ -68,7 +68,4 @@ winrt|!qtHaveModule(gui)|!qtConfig(accessibility): SUBDIRS -= qaccessibility
|
||||
android: SUBDIRS += \
|
||||
android
|
||||
|
||||
qtConfig(xkbcommon): {
|
||||
SUBDIRS += \
|
||||
xkbkeyboard
|
||||
}
|
||||
qtHaveModule(gui):qtConfig(xkbcommon): SUBDIRS += xkbkeyboard
|
||||
|
@ -159,6 +159,14 @@ void tst_QGraphicsPixmapItem::contains()
|
||||
QFETCH(QPointF, point);
|
||||
QFETCH(bool, contains);
|
||||
|
||||
// At the time of writing, by default pixmaps will have:
|
||||
// - The same pixel format of the primary screen (which is platform dependent and may contain alpha)
|
||||
// - Uninitialized pixels, potentially including an alpha channel
|
||||
// - A ShapeMode of Mask (which mean it will use the alpha channel as a mask for contains())
|
||||
// This means that in order to prevent undefined behavior in this test, we either need to set
|
||||
// the shapeMode to something else, or set the pixels of the pixmap.
|
||||
pixmap.fill(); // Filling the pixmap to be on the safe side.
|
||||
|
||||
SubQGraphicsPixmapItem item(pixmap);
|
||||
QCOMPARE(item.contains(point), contains);
|
||||
}
|
||||
|
8
tests/manual/wasm/localfiles/localfiles.pro
Normal file
8
tests/manual/wasm/localfiles/localfiles.pro
Normal file
@ -0,0 +1,8 @@
|
||||
TEMPLATE = app
|
||||
TARGET = localfiles
|
||||
QT += core gui widgets
|
||||
|
||||
OBJECTS_DIR = .obj
|
||||
MOC_DIR = .moc
|
||||
|
||||
SOURCES += main.cpp
|
100
tests/manual/wasm/localfiles/main.cpp
Normal file
100
tests/manual/wasm/localfiles/main.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#include <QtWidgets/QtWidgets>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QByteArray content;
|
||||
|
||||
QWidget loadFileUi;
|
||||
QVBoxLayout *layout = new QVBoxLayout();
|
||||
QPushButton *loadFile = new QPushButton("Load File");
|
||||
QLabel *fileInfo = new QLabel("Opened file:");
|
||||
fileInfo->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
QLabel *fileHash = new QLabel("Sha256:");
|
||||
fileHash->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
QPushButton *saveFile = new QPushButton("Save File");
|
||||
saveFile->setEnabled(false);
|
||||
|
||||
auto onFileReady = [=, &content](const QString &fileName, const QByteArray &fileContents) {
|
||||
content = fileContents;
|
||||
fileInfo->setText(QString("Opened file: %1 size: %2").arg(fileName).arg(fileContents.size()));
|
||||
saveFile->setEnabled(true);
|
||||
|
||||
auto computeDisplayFileHash = [=](){
|
||||
QByteArray hash = QCryptographicHash::hash(fileContents, QCryptographicHash::Sha256);
|
||||
fileHash->setText(QString("Sha256: %1").arg(QString(hash.toHex())));
|
||||
};
|
||||
|
||||
QTimer::singleShot(100, computeDisplayFileHash); // update UI before computing hash
|
||||
};
|
||||
auto onLoadClicked = [=](){
|
||||
QFileDialog::getOpenFileContent("*.*", onFileReady);
|
||||
};
|
||||
QObject::connect(loadFile, &QPushButton::clicked, onLoadClicked);
|
||||
|
||||
auto onSaveClicked = [=, &content]() {
|
||||
QFileDialog::saveFileContent(content, "qtsavefiletest.dat");
|
||||
};
|
||||
QObject::connect(saveFile, &QPushButton::clicked, onSaveClicked);
|
||||
|
||||
layout->addWidget(loadFile);
|
||||
layout->addWidget(fileInfo);
|
||||
layout->addWidget(fileHash);
|
||||
layout->addWidget(saveFile);
|
||||
layout->addStretch();
|
||||
|
||||
loadFileUi.setLayout(layout);
|
||||
loadFileUi.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user