From f4889e63c7b7629f9c25f42ba6c8b7852b91366f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 16 Apr 2020 18:27:08 +0200 Subject: [PATCH 01/44] macOS: Rework worksWhenModal and update on modal session change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of basing the worksWhenModal property on the window type, which will include both windows inside the current modal session (as intend), but also windows below the current modal session (wrongly), we check to see if the window is a transient child of the current top level modal window. Going via NSApp.modalWindow means we also catch cases where the top level modal session is run by a native window, not part of the modal session stack in the Cocoa event dispatcher. The new logic relies on windows such as popups, dialogs, etc to set the correct transient parent, but this seems to be the case already. To ensure the window tag is also updated, we call setWorksWhenModal on modal session changes. We could change worksWhenModal into e.g. shouldWorkWhenModal and always use the setter, but that would mean the initial window tag update in [NSWindow _commonAwake] would pick up the incorrect value. And if the window tag is not updated after that due to the workaround in [QNSPanel setWorksWhenModal:] being compiled out, the window would not be possible to order front, which is worse than being able to order front a window with worksWhenModal=NO. Fixes: QTBUG-76654 Task-number: QTBUG-71480 Change-Id: I38b14422d274dcc03b4c7d5ef87066e282ed9111 Reviewed-by: Timur Pocheptsov Reviewed-by: Tor Arne Vestbø --- .../platforms/cocoa/qcocoawindowmanager.mm | 12 +++ src/plugins/platforms/cocoa/qnswindow.mm | 82 ++++++++++++++++--- 2 files changed, 83 insertions(+), 11 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindowmanager.mm b/src/plugins/platforms/cocoa/qcocoawindowmanager.mm index 9c45d8c7fc0..5e218157c25 100644 --- a/src/plugins/platforms/cocoa/qcocoawindowmanager.mm +++ b/src/plugins/platforms/cocoa/qcocoawindowmanager.mm @@ -100,6 +100,18 @@ void QCocoaWindowManager::modalSessionChanged() } } } + + // Our worksWhenModal implementation is declarative and will normally be picked + // up by AppKit when needed, but to make sure AppKit also reflects the state + // in the window tag, so that the window can be ordered front by clicking it, + // we need to explicitly call setWorksWhenModal. + for (id window in NSApp.windows) { + if ([window isKindOfClass:[QNSPanel class]]) { + auto *panel = static_cast(window); + // Call setter to tell AppKit that our state has changed + [panel setWorksWhenModal:panel.worksWhenModal]; + } + } } static void initializeWindowManager() { Q_UNUSED(QCocoaWindowManager::instance()); } diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index 6b4e110af27..311c2912523 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -158,8 +158,79 @@ static bool isMouseEvent(NSEvent *ev) #define QNSWINDOW_PROTOCOL_IMPLMENTATION 1 #include "qnswindow.mm" #undef QNSWINDOW_PROTOCOL_IMPLMENTATION + +- (BOOL)worksWhenModal +{ + if (!m_platformWindow) + return NO; + + // Conceptually there are two sets of windows we need consider: + // + // - windows 'lower' in the modal session stack + // - windows 'within' the current modal session + // + // The first set of windows should always be blocked by the current + // modal session, regardless of window type. The latter set may contain + // windows with a transient parent, which from Qt's point of view makes + // them 'child' windows, so we treat them as operable within the current + // modal session. + + if (!NSApp.modalWindow) + return NO; + + // If the current modal window (top level modal session) is not a Qt window we + // have no way of knowing if this window is transient child of the modal window. + if (![NSApp.modalWindow conformsToProtocol:@protocol(QNSWindowProtocol)]) + return NO; + + if (auto *modalWindow = static_cast(NSApp.modalWindow).platformWindow) { + if (modalWindow->window()->isAncestorOf(m_platformWindow->window(), QWindow::IncludeTransients)) + return YES; + } + + return NO; +} @end +#if !defined(QT_APPLE_NO_PRIVATE_APIS) +// When creating an NSWindow the worksWhenModal function is queried, +// and the resulting state is used to set the corresponding window tag, +// which the window server uses to determine whether or not the window +// should be allowed to activate via mouse clicks in the title-bar. +// Unfortunately, prior to macOS 10.15, this window tag was never +// updated after the initial assignment in [NSWindow _commonAwake], +// which meant that windows that dynamically change their worksWhenModal +// state will behave as if they were never allowed to work when modal. +// We work around this by manually updating the window tag when needed. + +typedef uint32_t CGSConnectionID; +typedef uint32_t CGSWindowID; + +extern "C" { +CGSConnectionID CGSMainConnectionID() __attribute__((weak_import)); +OSStatus CGSSetWindowTags(const CGSConnectionID, const CGSWindowID, int *, int) __attribute__((weak_import)); +OSStatus CGSClearWindowTags(const CGSConnectionID, const CGSWindowID, int *, int) __attribute__((weak_import)); +} + +@interface QNSPanel (WorksWhenModalWindowTagWorkaround) @end +@implementation QNSPanel (WorksWhenModalWindowTagWorkaround) +- (void)setWorksWhenModal:(BOOL)worksWhenModal +{ + [super setWorksWhenModal:worksWhenModal]; + + if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSCatalina) { + if (CGSMainConnectionID && CGSSetWindowTags && CGSClearWindowTags) { + static int kWorksWhenModalWindowTag = 0x40; + auto *function = worksWhenModal ? CGSSetWindowTags : CGSClearWindowTags; + function(CGSMainConnectionID(), self.windowNumber, &kWorksWhenModalWindowTag, 64); + } else { + qWarning() << "Missing APIs for window tag handling, can not update worksWhenModal state"; + } + } +} +@end +#endif // QT_APPLE_NO_PRIVATE_APIS + #else // QNSWINDOW_PROTOCOL_IMPLMENTATION // The following content is mixed in to the QNSWindow and QNSPanel classes via includes @@ -237,17 +308,6 @@ static bool isMouseEvent(NSEvent *ev) return canBecomeMain; } -- (BOOL)worksWhenModal -{ - if (m_platformWindow && [self isKindOfClass:[QNSPanel class]]) { - Qt::WindowType type = m_platformWindow->window()->type(); - if (type == Qt::Popup || type == Qt::Dialog || type == Qt::Tool) - return YES; - } - - return [super worksWhenModal]; -} - - (BOOL)isOpaque { return m_platformWindow ? m_platformWindow->isOpaque() : [super isOpaque]; From d04c9e23ff11da35f0c5784d85133cd6c65a7741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 13 Feb 2019 13:57:31 +0100 Subject: [PATCH 02/44] macOS: Activate non-modal windows during modal session if they support it Commit 593ab638609e ensured that non-modal windows would not be activated during a modal session, which makes sense for windows that can't be interacted with. But some windows can, and we should activate them as normal. Task-number: QTBUG-46304 Change-Id: I4a9b7ec53157b042d4d6e9535336fa3254f41e0e Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoawindow.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 79dfe58a4e2..5ddbfe43774 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -376,8 +376,11 @@ void QCocoaWindow::setVisible(bool visible) } else if (window()->modality() == Qt::ApplicationModal) { // Show the window as application modal eventDispatcher()->beginModalSession(window()); - } else if (m_view.window.canBecomeKeyWindow && !eventDispatcher()->hasModalSession()) { - [m_view.window makeKeyAndOrderFront:nil]; + } else if (m_view.window.canBecomeKeyWindow) { + if (!NSApp.modalWindow || m_view.window.worksWhenModal) + [m_view.window makeKeyAndOrderFront:nil]; + else + [m_view.window orderFront:nil]; } else { [m_view.window orderFront:nil]; } From a962bbec0789f05ba6f1ea50c8656eeb5ac3ab00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 13 Feb 2019 14:00:57 +0100 Subject: [PATCH 03/44] macOS: Support [NSPanel becomesKeyOnlyIfNeeded] We don't set this flag ourselves, but clients may do via winId(). If set, the panel will only activate if a view with needsPanelToBecomeKey is clicked. We do not implement needsPanelToBecomeKey in QNSView, which we ideally should, by e.g. looking at the IME hints. This still works as expected, as QtWidgets will make sure to activate the window as part of the normal focus handling. For other use-cases the user will have to catch the mouse event and activate the window manually. Change-Id: I4bacdd44b2f7df5920c6334806303bb5eb502b48 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoawindow.mm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 5ddbfe43774..2cbe1b8684e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -377,7 +377,14 @@ void QCocoaWindow::setVisible(bool visible) // Show the window as application modal eventDispatcher()->beginModalSession(window()); } else if (m_view.window.canBecomeKeyWindow) { - if (!NSApp.modalWindow || m_view.window.worksWhenModal) + bool shouldBecomeKeyNow = !NSApp.modalWindow || m_view.window.worksWhenModal; + + // Panels with becomesKeyOnlyIfNeeded set should not activate until a view + // with needsPanelToBecomeKey, for example a line edit, is clicked. + if ([m_view.window isKindOfClass:[NSPanel class]]) + shouldBecomeKeyNow &= !(static_cast(m_view.window).becomesKeyOnlyIfNeeded); + + if (shouldBecomeKeyNow) [m_view.window makeKeyAndOrderFront:nil]; else [m_view.window orderFront:nil]; From cd41b01f32104a484db53e8a1ea913d596c939c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 17 Apr 2020 17:04:33 +0200 Subject: [PATCH 04/44] macOS: Don't produce NSImages without a single representation Doing so results in exceptions inside AppKit when passed on to APIs that expect valid images. It's better to produce nil-images. Fixes: QTBUG-83494 Change-Id: I1e5bfa2a7fecd75a1ddb95bd1a6dc2e8db6b24f8 Reviewed-by: Volker Hilsheimer --- src/gui/painting/qcoregraphics.mm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm index 94ba004c932..7fb075d19ed 100644 --- a/src/gui/painting/qcoregraphics.mm +++ b/src/gui/painting/qcoregraphics.mm @@ -162,12 +162,12 @@ QT_END_NAMESPACE if (icon.isNull()) return nil; - auto nsImage = [[NSImage alloc] initWithSize:NSZeroSize]; - auto availableSizes = icon.availableSizes(); if (availableSizes.isEmpty() && size > 0) availableSizes << QSize(size, size); + auto nsImage = [[[NSImage alloc] initWithSize:NSZeroSize] autorelease]; + for (QSize size : qAsConst(availableSizes)) { QImage image = icon.pixmap(size).toImage(); if (image.isNull()) @@ -182,12 +182,15 @@ QT_END_NAMESPACE [nsImage addRepresentation:[imageRep autorelease]]; } + if (!nsImage.representations.count) + return nil; + [nsImage setTemplate:icon.isMask()]; if (size) nsImage.size = CGSizeMake(size, size); - return [nsImage autorelease]; + return nsImage; } @end From 164110f7bbea7345de709edd092afa84fdde232c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 17 Apr 2020 17:02:46 +0200 Subject: [PATCH 05/44] Warn when trying to load an icon without a matching icon engine A typical case is trying to load an SVG icon without the QtSvg module built. You want to know what's going on instead of trying to debug why the icon doesn't produce any valid images. Change-Id: I4418ad758a1232f1394058368c50e0d87235271e Reviewed-by: Volker Hilsheimer --- src/gui/image/qicon.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 41fe649fc54..562e5e9a3ef 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -1049,6 +1049,8 @@ static QIconEngine *iconEngineFromSuffix(const QString &fileName, const QString } } } + qWarning("Could not find icon engine for suffix '%s' of file '%s'", + qUtf8Printable(suffix), qUtf8Printable(fileName)); return nullptr; } From 86f228b819aba71f0d6cd89303d8226d6567209b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 17 Apr 2020 17:08:21 +0200 Subject: [PATCH 06/44] macOS: Restore fallback sizes when setting application or window icons We removed this logic in 059c3ae66a under the assumption that the icon would always provide a set of sizes, but for SVG icons this is not the case. Change-Id: Ib3cc5740bca32cf4068a71baf99b52fa536da2ca Reviewed-by: Volker Hilsheimer Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoaintegration.mm | 4 +++- src/plugins/platforms/cocoa/qcocoawindow.mm | 9 ++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 245db429c54..9b57b895296 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -472,7 +472,9 @@ QList *QCocoaIntegration::popupWindowStack() void QCocoaIntegration::setApplicationIcon(const QIcon &icon) const { - NSApp.applicationIconImage = [NSImage imageFromQIcon:icon]; + // Fall back to a size that looks good on the highest resolution screen available + auto fallbackSize = NSApp.dockTile.size.width * qGuiApp->devicePixelRatio(); + NSApp.applicationIconImage = [NSImage imageFromQIcon:icon withSize:fallbackSize]; } void QCocoaIntegration::beep() const diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 2cbe1b8684e..069e9ce8455 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -904,10 +904,13 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon) QMacAutoReleasePool pool; - if (icon.isNull()) + if (icon.isNull()) { iconButton.image = [NSWorkspace.sharedWorkspace iconForFile:m_view.window.representedFilename]; - else - iconButton.image = [NSImage imageFromQIcon:icon]; + } else { + // Fall back to a size that looks good on the highest resolution screen available + auto fallbackSize = iconButton.frame.size.height * qGuiApp->devicePixelRatio(); + iconButton.image = [NSImage imageFromQIcon:icon withSize:fallbackSize]; + } } void QCocoaWindow::setAlertState(bool enabled) From 864f18ba2f21a0eb1977acc53ebe733acdfc8d90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 24 Mar 2020 09:39:06 +0100 Subject: [PATCH 07/44] widgets: Re-calculate focus frame style option after setting new geometry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-83019 Change-Id: I75d3d93732cb0c5a5b7350f19f0227998bda4791 Reviewed-by: Friedemann Kleint (cherry picked from commit bd78753d625c573eef587fc0b8e767cffb99c2bf) Reviewed-by: Tor Arne Vestbø --- src/widgets/widgets/qfocusframe.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/widgets/widgets/qfocusframe.cpp b/src/widgets/widgets/qfocusframe.cpp index 4e793d7a297..aa9de7c35fc 100644 --- a/src/widgets/widgets/qfocusframe.cpp +++ b/src/widgets/widgets/qfocusframe.cpp @@ -99,6 +99,8 @@ void QFocusFramePrivate::updateSize() return; q->setGeometry(geom); + + opt.rect = q->rect(); QStyleHintReturnMask mask; if (q->style()->styleHint(QStyle::SH_FocusFrame_Mask, &opt, q, &mask)) q->setMask(mask.region); From 47eba459905ef884931aa1247c847f7a98a77b28 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 20 Apr 2020 13:24:50 +0200 Subject: [PATCH 08/44] winrt: Fix manifest creation for Visual Studio 2019 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 2019 still uses VCLIB version 140 - minVersion and maxVersionTested have to be set for every MSVC version Change-Id: I9300e03115e2e99fd250ec85bdd7f3367ab00d48 Reviewed-by: Friedemann Kleint Reviewed-by: André de la Rocha Reviewed-by: Miguel Costa --- mkspecs/features/winrt/package_manifest.prf | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf index 22bda003fbe..279971bd657 100644 --- a/mkspecs/features/winrt/package_manifest.prf +++ b/mkspecs/features/winrt/package_manifest.prf @@ -36,8 +36,9 @@ VCLIBS = $${VCLIBS}.Debug else: \ VCLIBS = $${VCLIBS} - # VS 2017 still uses vclibs 140 + # VS 2017 and 2019 still use vclibs 140 contains(MSVC_VER, "15.0"): VCLIBS = $$replace(VCLIBS, 150, 140) + contains(MSVC_VER, "16.0"): VCLIBS = $$replace(VCLIBS, 160, 140) VCLIBS = "$${VCLIBS}\" MinVersion=\"14.0.0.0\" Publisher=\"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" WINRT_MANIFEST.dependencies += $$VCLIBS } @@ -68,12 +69,10 @@ isEmpty(WINRT_MANIFEST.background): WINRT_MANIFEST.background = green isEmpty(WINRT_MANIFEST.foreground): WINRT_MANIFEST.foreground = light isEmpty(WINRT_MANIFEST.default_language): WINRT_MANIFEST.default_language = en - *-msvc2015|*-msvc2017 { - isEmpty(WINRT_MANIFEST.minVersion): \ - WINRT_MANIFEST.minVersion = $$WINDOWS_TARGET_PLATFORM_VERSION - isEmpty(WINRT_MANIFEST.maxVersionTested): \ - WINRT_MANIFEST.maxVersionTested = $$WINDOWS_TARGET_PLATFORM_MIN_VERSION - } + isEmpty(WINRT_MANIFEST.minVersion): \ + WINRT_MANIFEST.minVersion = $$WINDOWS_TARGET_PLATFORM_VERSION + isEmpty(WINRT_MANIFEST.maxVersionTested): \ + WINRT_MANIFEST.maxVersionTested = $$WINDOWS_TARGET_PLATFORM_MIN_VERSION INDENT = "$$escape_expand(\\r\\n) " From fdea55cb9832a194b5ec1262e216f12ae644ba6b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Apr 2020 18:52:49 -0300 Subject: [PATCH 09/44] QCborValue: fix double-accounting of the usedData when decoding strings We can only update usedData at the end, after we've decoded all chunks. The update inside the lambda was double-accounting for the first chunk, which could lead to signed integer overflows in usedData. Not unit-testable since the usedData value is not visible in the API. Change-Id: Ibdc95e9af7bd456a94ecfffd16061cc955208859 Reviewed-by: Ulf Hermann Reviewed-by: Edward Welbourne --- src/corelib/serialization/qcborvalue.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index c45a09ad997..90b45fb8531 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -1561,8 +1561,6 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader) if (newSize > MaxByteArraySize) return -1; - // since usedData <= data.size(), this can't overflow - usedData += increment; data.resize(newSize); return offset; }; From c197615bd99ec76ebb3ca9aff959826b4e7ff43b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Apr 2020 19:10:01 -0300 Subject: [PATCH 10/44] QCborValue: don't update internal states if decoding a string failed Change-Id: Ibdc95e9af7bd456a94ecfffd16061db982ad3fa7 Reviewed-by: Ulf Hermann Reviewed-by: Edward Welbourne --- src/corelib/serialization/qcborvalue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index 90b45fb8531..a3729b4ef9c 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -1633,7 +1633,7 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader) } // update size - if (e.flags & Element::HasByteData) { + if (r.status == QCborStreamReader::EndOfString && e.flags & Element::HasByteData) { auto b = new (dataPtr() + e.value) ByteData; b->len = data.size() - e.value - int(sizeof(*b)); usedData += b->len; From 9802b93cc76de8a033a9806383c1631f36225931 Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Mon, 20 Apr 2020 16:12:26 +0300 Subject: [PATCH 11/44] note QFileDialog::setNameFilters() is not supported on Android Task-number: QTBUG-83089 Change-Id: I134917476548f9756a14975be6b1b20312a8ca40 Reviewed-by: Friedemann Kleint --- src/widgets/dialogs/qfiledialog.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index bace311924e..b406333fefa 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -1370,6 +1370,9 @@ QStringList qt_make_filter_list(const QString &filter) \snippet code/src_gui_dialogs_qfiledialog.cpp 6 + \note This is not supported on Android's native file dialog. Use + \l{setMimeTypeFilters()} instead. + \sa setMimeTypeFilters(), setNameFilters() */ void QFileDialog::setNameFilter(const QString &filter) @@ -1441,6 +1444,9 @@ QStringList qt_strip_filters(const QStringList &filters) filters for each file type. For example, JPEG images have three possible extensions; if your application can open such files, selecting the \c image/jpeg mime type as a filter will allow you to open all of them. + + \note This is not supported on Android's native file dialog. Use + \l{setMimeTypeFilters()} instead. */ void QFileDialog::setNameFilters(const QStringList &filters) { From 10acfec765d2c947a180f52437b8df77dfc0658d Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 22 Apr 2020 09:06:31 +0200 Subject: [PATCH 12/44] Doc: Fix compilation issue with QVERIFY2 example Fixes error C2124: divide or mod by zero when compiling the test code (enabled by 713cd83200f3c60eac5d389dfabc44be1446e2ac). Pick-to: 5.15 Change-Id: I2ae39426fc0012f79714ff3d6484d792cab4bd92 Reviewed-by: Edward Welbourne --- src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp b/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp index eda0f430a19..cfa999a6f4a 100644 --- a/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp +++ b/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp @@ -84,7 +84,7 @@ class TestQString : public QObject void wrapInFunction() { //! [1] -QVERIFY2(qIsNaN(0.0 / 0.0), "Ill-defined division produced unambiguous result."); +QVERIFY2(QFileInfo("file.txt").exists(), "file.txt does not exist."); //! [1] //! [2] From 1e4801c7ce19c5750299bf762a106302b50e9b6b Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 22 Apr 2020 09:52:52 +0200 Subject: [PATCH 13/44] Fix build with -no-compile-examples configure -no-compile-examples means that the examples won't be compiled, but processed by qmake to generate install targets. So we shouldn't do any substitution (like it is done for CMake targets), or extra compilers / copies (like it is done for qmltypes). Also install the qmldir files that some qml examples need. Fixes: QTBUG-83375 Fixes: QTBUG-83704 Change-Id: I6a9393bd914d98a5d85f4089205510e49a435842 Reviewed-by: Joerg Bornemann Reviewed-by: Thiago Macieira --- mkspecs/features/qt_example_installs.prf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mkspecs/features/qt_example_installs.prf b/mkspecs/features/qt_example_installs.prf index 72b47bce276..15b373ba402 100644 --- a/mkspecs/features/qt_example_installs.prf +++ b/mkspecs/features/qt_example_installs.prf @@ -74,6 +74,7 @@ sourcefiles += \ extras = \ $$_PRO_FILE_PWD_/README \ $$_PRO_FILE_PWD_/README.TXT \ + $$_PRO_FILE_PWD_/qmldir \ $$files($$_PRO_FILE_PWD_/*.pri) \ $$replace(_PRO_FILE_, \\.pro$, .qmlproject) \ $$replace(_PRO_FILE_, \\.pro$, .json) \ @@ -140,6 +141,9 @@ equals(TEMPLATE, app)|equals(TEMPLATE, lib) { SOURCES = OBJECTIVE_SOURCES = INSTALLS -= target + QMAKE_SUBSTITUTES = + QMAKE_EXTRA_COMPILERS = + COPIES = } else { CONFIG += relative_qt_rpath # Examples built as part of Qt should be relocatable } From 9e83d268d6e0bd492fafad823a47cef57b7916c5 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Wed, 22 Apr 2020 20:06:16 +0200 Subject: [PATCH 14/44] Fix data corruption regression in QJsonObject::erase() The internal removeAt(index) method was implemented as taking cbor indexes directly, in contrast to the other ...At(index) methods. Fixes: QTBUG-83695 Change-Id: I16597eb6db1cf71e1585c041caa81bf8f7a75303 Reviewed-by: Thiago Macieira --- src/corelib/serialization/qjsonobject.cpp | 8 ++++---- tests/auto/corelib/serialization/json/tst_qtjson.cpp | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp index 850e878571f..36429662fc1 100644 --- a/src/corelib/serialization/qjsonobject.cpp +++ b/src/corelib/serialization/qjsonobject.cpp @@ -577,7 +577,7 @@ void QJsonObject::removeImpl(T key) if (!keyExists) return; - removeAt(index); + removeAt(index / 2); } #if QT_STRINGVIEW_LEVEL < 2 @@ -629,7 +629,7 @@ QJsonValue QJsonObject::takeImpl(T key) return QJsonValue(QJsonValue::Undefined); const QJsonValue v = QJsonPrivate::Value::fromTrustedCbor(o->extractAt(index + 1)); - removeAt(index); + removeAt(index / 2); return v; } @@ -1486,8 +1486,8 @@ void QJsonObject::setValueAt(int i, const QJsonValue &val) void QJsonObject::removeAt(int index) { detach2(); - o->removeAt(index + 1); - o->removeAt(index); + o->removeAt(2 * index + 1); + o->removeAt(2 * index); } uint qHash(const QJsonObject &object, uint seed) diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp index 7da20772f80..e5d909b9a7d 100644 --- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp +++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp @@ -927,9 +927,16 @@ void tst_QtJson::testObjectIteration() QCOMPARE(object, object2); QJsonObject::iterator it = object2.find(QString::number(5)); + QJsonValue val = *it; object2.erase(it); QCOMPARE(object.size(), 10); QCOMPARE(object2.size(), 9); + + for (QJsonObject::const_iterator it = object2.constBegin(); it != object2.constEnd(); ++it) { + QJsonValue value = it.value(); + QVERIFY(it.value() != val); + QCOMPARE((double)it.key().toInt(), value.toDouble()); + } } { From 37bd3fbccd2d414b17d2b6cf14b2b976afc5810a Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 26 Mar 2020 12:34:55 +0100 Subject: [PATCH 15/44] Doc: Describe updating fonts with substitutes Fixes: QTBUG-82577 Change-Id: I40662240da69c0d93d0386172c10f375fbb5fefc Reviewed-by: Paul Wicking --- src/gui/text/qfont.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index bf130fa0b77..1b33693ed8c 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -420,7 +420,9 @@ QFontEngineData::~QFontEngineData() be removed with removeSubstitutions(). Use substitute() to retrieve a family's first substitute, or the family name itself if it has no substitutes. Use substitutes() to retrieve a list of a family's - substitutes (which may be empty). + substitutes (which may be empty). After substituting a font, you must + trigger the updating of the font by destroying and re-creating all + QFont objects. Every QFont has a key() which you can use, for example, as the key in a cache or dictionary. If you want to store a user's font @@ -1864,6 +1866,9 @@ QStringList QFont::substitutes(const QString &familyName) Inserts \a substituteName into the substitution table for the family \a familyName. + After substituting a font, trigger the updating of the font by destroying + and re-creating all QFont objects. + \sa insertSubstitutions(), removeSubstitutions(), substitutions(), substitute(), substitutes() */ void QFont::insertSubstitution(const QString &familyName, @@ -1882,6 +1887,10 @@ void QFont::insertSubstitution(const QString &familyName, Inserts the list of families \a substituteNames into the substitution list for \a familyName. + After substituting a font, trigger the updating of the font by destroying + and re-creating all QFont objects. + + \sa insertSubstitution(), removeSubstitutions(), substitutions(), substitute() */ void QFont::insertSubstitutions(const QString &familyName, From 7c7b09dbac7d1921efb305cb7843b88a5247f17e Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 21 Apr 2020 10:20:28 +0200 Subject: [PATCH 16/44] Cocoa: If the grabRect is null then add in a null image for the area MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If it is null then it has nothing to grab, so a null QImage and QRect is added to the lists so that there is still a representation in some form for that display. This additionally ensures that it does take up space for the display in the final image too. Fixes: QTBUG-63086 Change-Id: I6e80ecc1170642025f6930e2211017c114e25c16 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoascreen.mm | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index e4dd4cf6c69..6a3172fb19f 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -614,7 +614,11 @@ QPixmap QCocoaScreen::grabWindow(WId view, int x, int y, int width, int height) QRect windowRect; for (uint i = 0; i < displayCount; ++i) { QRect displayBounds = QRectF::fromCGRect(CGDisplayBounds(displays[i])).toRect(); - windowRect = windowRect.united(displayBounds); + // Only include the screen if it is positioned past the x/y position + if ((displayBounds.x() >= x || displayBounds.right() > x) && + (displayBounds.y() >= y || displayBounds.bottom() > y)) { + windowRect = windowRect.united(displayBounds); + } } if (grabRect.width() < 0) grabRect.setWidth(windowRect.width()); @@ -631,6 +635,11 @@ QPixmap QCocoaScreen::grabWindow(WId view, int x, int y, int width, int height) auto display = displays[i]; QRect displayBounds = QRectF::fromCGRect(CGDisplayBounds(display)).toRect(); QRect grabBounds = displayBounds.intersected(grabRect); + if (grabBounds.isNull()) { + destinations.append(QRect()); + images.append(QImage()); + continue; + } QRect displayLocalGrabBounds = QRect(QPoint(grabBounds.topLeft() - displayBounds.topLeft()), grabBounds.size()); QImage displayImage = qt_mac_toQImage(QCFType(CGDisplayCreateImageForRect(display, displayLocalGrabBounds.toCGRect()))); displayImage.setDevicePixelRatio(displayImage.size().width() / displayLocalGrabBounds.size().width()); From d5f759cf6684d4d3574f5306cb5129861cab7103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 24 Apr 2020 12:46:03 +0200 Subject: [PATCH 17/44] iOS: Use storyboard instead of .xib file for launch screen Apps on the iOS app store are required to use storyboards for their launch screens from June 30th 2020. Change-Id: Iae34042294fb167a2c893542c57dfaacaf1e929c Fixes: QTBUG-83512 Reviewed-by: Joerg Bornemann --- mkspecs/features/uikit/default_post.prf | 2 +- .../macx-ios-clang/LaunchScreen.storyboard | 48 +++++++++++++++++++ mkspecs/macx-ios-clang/LaunchScreen.xib | 45 ----------------- 3 files changed, 49 insertions(+), 46 deletions(-) create mode 100644 mkspecs/macx-ios-clang/LaunchScreen.storyboard delete mode 100644 mkspecs/macx-ios-clang/LaunchScreen.xib diff --git a/mkspecs/features/uikit/default_post.prf b/mkspecs/features/uikit/default_post.prf index c1b6f38a6c6..088b39ff3f2 100644 --- a/mkspecs/features/uikit/default_post.prf +++ b/mkspecs/features/uikit/default_post.prf @@ -43,7 +43,7 @@ macx-xcode { warning("You need to update Xcode to version 6 or newer to fully support iPhone6/6+") } else { # Set up default LaunchScreen to support iPhone6/6+ - qmake_launch_screen = LaunchScreen.xib + qmake_launch_screen = LaunchScreen.storyboard qmake_copy_launch_screen.input = $$QMAKESPEC/$$qmake_launch_screen qmake_copy_launch_screen.output = $$OUT_PWD/$${TARGET}.xcodeproj/$$qmake_launch_screen QMAKE_SUBSTITUTES += qmake_copy_launch_screen diff --git a/mkspecs/macx-ios-clang/LaunchScreen.storyboard b/mkspecs/macx-ios-clang/LaunchScreen.storyboard new file mode 100644 index 00000000000..7d8d9a3405b --- /dev/null +++ b/mkspecs/macx-ios-clang/LaunchScreen.storyboard @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mkspecs/macx-ios-clang/LaunchScreen.xib b/mkspecs/macx-ios-clang/LaunchScreen.xib deleted file mode 100644 index d28c06b375c..00000000000 --- a/mkspecs/macx-ios-clang/LaunchScreen.xib +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 6fa50601ab7c55946eecc33453e7d694b5940d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 23 Apr 2020 11:04:58 +0200 Subject: [PATCH 18/44] Don't warn when loading icons via the image loaders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 9d5ae9f26c98 introduced a warning when a matching icon engine was not found for a given file suffix, under the assumption that all formats would go through icon engine plugins. Unfortunately QIcon itself falls back to a direct use of QPixmapIconEngine when no icon engine plugin is found, which would lead to the warning being emitted for built in formats such as PNG. Until this code can be moved properly into QPixmapIconEngine we'll remove it. Change-Id: I14d1d33a0f0c29e4b4604ef3b53c05cb8e02f867 Reviewed-by: Tor Arne Vestbø Reviewed-by: Simon Hausmann --- src/gui/image/qicon.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 562e5e9a3ef..41fe649fc54 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -1049,8 +1049,6 @@ static QIconEngine *iconEngineFromSuffix(const QString &fileName, const QString } } } - qWarning("Could not find icon engine for suffix '%s' of file '%s'", - qUtf8Printable(suffix), qUtf8Printable(fileName)); return nullptr; } From d433d0e089698bb2c3153360c583f5ad540a6566 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Mon, 27 Apr 2020 07:31:46 +0200 Subject: [PATCH 19/44] Doc: add since for QWheelEvent::position Fixes: QTBUG-83779 Change-Id: Icd39c6e3b65e17a51d04ea3c0718f2957948aaa4 Reviewed-by: Nico Vertriest --- src/gui/kernel/qevent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 466e70db30f..68f2d0392fd 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -951,6 +951,7 @@ QWheelEvent::~QWheelEvent() /*! \fn QPoint QWheelEvent::position() const + \since 5.14 Returns the position of the mouse cursor relative to the widget that received the event. From 41387bb330bb694f7e423f180bdbf88c7200985b Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 27 Apr 2020 10:58:39 +0200 Subject: [PATCH 20/44] Fix 8bit image conversions with non-default bytes_per_line Copy line by line when bytes per line doesn't match between input and output. Fixes: QTBUG-83777 Change-Id: I44ca75963df6188c1de76196d9c12fd8bb081688 Reviewed-by: Eirik Aavitsland --- src/gui/image/qimage_conversions.cpp | 44 +++++++++++++++++++++------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 34d2b8d8c75..506ebc797fe 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -2016,6 +2016,21 @@ static void convert_Mono_to_Indexed8(QImageData *dest, const QImageData *src, Qt } } +static void copy_8bit_pixels(QImageData *dest, const QImageData *src) +{ + if (src->bytes_per_line == dest->bytes_per_line) { + memcpy(dest->data, src->data, src->bytes_per_line * src->height); + } else { + const uchar *sdata = src->data; + uchar *ddata = dest->data; + for (int y = 0; y < src->height; ++y) { + memcpy(ddata, sdata, src->width); + sdata += src->bytes_per_line; + ddata += dest->bytes_per_line; + } + } +} + static void convert_Indexed8_to_Alpha8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { Q_ASSERT(src->format == QImage::Format_Indexed8); @@ -2031,11 +2046,15 @@ static void convert_Indexed8_to_Alpha8(QImageData *dest, const QImageData *src, } if (simpleCase) - memcpy(dest->data, src->data, src->bytes_per_line * src->height); + copy_8bit_pixels(dest, src); else { - qsizetype size = src->bytes_per_line * src->height; - for (qsizetype i = 0; i < size; ++i) { - dest->data[i] = translate[src->data[i]]; + const uchar *sdata = src->data; + uchar *ddata = dest->data; + for (int y = 0; y < src->height; ++y) { + for (int x = 0; x < src->width; ++x) + ddata[x] = translate[sdata[x]]; + sdata += src->bytes_per_line; + ddata += dest->bytes_per_line; } } } @@ -2055,11 +2074,15 @@ static void convert_Indexed8_to_Grayscale8(QImageData *dest, const QImageData *s } if (simpleCase) - memcpy(dest->data, src->data, src->bytes_per_line * src->height); + copy_8bit_pixels(dest, src); else { - qsizetype size = src->bytes_per_line * src->height; - for (qsizetype i = 0; i < size; ++i) { - dest->data[i] = translate[src->data[i]]; + const uchar *sdata = src->data; + uchar *ddata = dest->data; + for (int y = 0; y < src->height; ++y) { + for (int x = 0; x < src->width; ++x) + ddata[x] = translate[sdata[x]]; + sdata += src->bytes_per_line; + ddata += dest->bytes_per_line; } } } @@ -2107,7 +2130,7 @@ static void convert_Alpha8_to_Indexed8(QImageData *dest, const QImageData *src, Q_ASSERT(src->format == QImage::Format_Alpha8); Q_ASSERT(dest->format == QImage::Format_Indexed8); - memcpy(dest->data, src->data, src->bytes_per_line * src->height); + copy_8bit_pixels(dest, src); dest->colortable = defaultColorTables->alpha; } @@ -2117,8 +2140,7 @@ static void convert_Grayscale8_to_Indexed8(QImageData *dest, const QImageData *s Q_ASSERT(src->format == QImage::Format_Grayscale8); Q_ASSERT(dest->format == QImage::Format_Indexed8); - memcpy(dest->data, src->data, src->bytes_per_line * src->height); - + copy_8bit_pixels(dest, src); dest->colortable = defaultColorTables->gray; } From a1f9729b740e410f818864588d4829275c4d5f52 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 7 Apr 2020 15:48:46 +0200 Subject: [PATCH 21/44] Fix 32bit int overflow Do not continue if the conversion to 32bit int would cause an overflow. Change-Id: I8a198dce5962e7ebd248b9baa92aba8730bfd3b0 Reviewed-by: Edward Welbourne --- src/network/ssl/qasn1element.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/network/ssl/qasn1element.cpp b/src/network/ssl/qasn1element.cpp index 6558643386d..5634332a67e 100644 --- a/src/network/ssl/qasn1element.cpp +++ b/src/network/ssl/qasn1element.cpp @@ -45,6 +45,7 @@ #include #include +#include #include QT_BEGIN_NAMESPACE @@ -120,7 +121,7 @@ bool QAsn1Element::read(QDataStream &stream) return false; // length - qint64 length = 0; + quint64 length = 0; quint8 first; stream >> first; if (first & 0x80) { @@ -139,11 +140,13 @@ bool QAsn1Element::read(QDataStream &stream) length = (first & 0x7f); } + if (length > quint64(std::numeric_limits::max())) + return false; // value QByteArray tmpValue; tmpValue.resize(length); int count = stream.readRawData(tmpValue.data(), tmpValue.size()); - if (count != length) + if (count != int(length)) return false; mType = tmpType; From c068edcecf6876c7b57abbe302ad8b1347e4445e Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 24 Apr 2020 10:17:05 +0200 Subject: [PATCH 22/44] Always open a submenu on the same screen where the parent menu is We've seen submenus opening on different screens in different scenarios, but probably there's never a sensible reason to do that. QWidgetPrivate::setScreenForPoint() can often give incorrect results in multi-screen desktop configurations; this is a way of avoiding that. Task-number: QTBUG-76162 Change-Id: I895696c6858ad953258c84b21117beea4c4fc01d Reviewed-by: Andy Shaw --- src/widgets/widgets/qmenu.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 865e3b2fb6c..38fdbf2184b 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -40,6 +40,7 @@ #include "qmenu.h" #include +#include #include "qdebug.h" #include "qstyle.h" @@ -2343,15 +2344,23 @@ void QMenuPrivate::popup(const QPoint &p, QAction *atAction, PositionFunction po // Use d->popupScreen to remember, because initialScreenIndex will be reset after the first showing. // However if eventLoop exists, then exec() already did this by calling createWinId(); so leave it alone. (QTBUG-76162) if (!eventLoop) { + bool screenSet = false; const int screenIndex = topData()->initialScreenIndex; if (screenIndex >= 0) popupScreen = screenIndex; if (auto s = QGuiApplication::screens().value(popupScreen)) { if (setScreen(s)) itemsDirty = true; - } else if (setScreenForPoint(p)) { - itemsDirty = true; + screenSet = true; + } else if (QMenu *parentMenu = qobject_cast(parent)) { + // a submenu is always opened from an open parent menu, + // so show it on the same screen where the parent is. (QTBUG-76162) + if (setScreen(QMenuPrivate::get(parentMenu)->windowHandle()->screen())) + itemsDirty = true; + screenSet = true; } + if (!screenSet && setScreenForPoint(p)) + itemsDirty = true; } const bool contextMenu = isContextMenu(); From f58c8fb4537c5d751da9d2c86ca0f61ad0adbbb2 Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Fri, 17 Apr 2020 10:05:38 +0300 Subject: [PATCH 23/44] Add changes file for Qt 5.15.0 Change-Id: I28732113bcfd65e983dff6746f6787a266211c8c Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Edward Welbourne --- dist/changes-5.15.0 | 444 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 444 insertions(+) create mode 100644 dist/changes-5.15.0 diff --git a/dist/changes-5.15.0 b/dist/changes-5.15.0 new file mode 100644 index 00000000000..f8e23303115 --- /dev/null +++ b/dist/changes-5.15.0 @@ -0,0 +1,444 @@ +Qt 5.15 introduces many new features and improvements as well as bugfixes +over the 5.14.x series. 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.15 series is binary compatible with the 5.14.x series. +Applications compiled for 5.14 will continue to run with 5.15. + +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 * +**************************************************************************** + + - Calling QList::insert() or removeAt() with an out of bounds index is + deprecated and will no longer be supported in Qt 6. + +**************************************************************************** +* Potentially Binary-Incompatible Changes * +**************************************************************************** + + - QHash: + QHash's iterator category was changed from bidirectional iterator to + forward iterator. This may cause trouble if a library uses the + iterator category to alter functionality through tag dispatching. This + only applies when compiling the library or application with + QT_DISABLE_DEPRECATED_BEFORE=0x050F00 and the other with a lower value. + +**************************************************************************** +* Deprecation Notice * +**************************************************************************** + + - The binary JSON representation is deprecated. The CBOR format should be + used instead. + + - [QTBUG-80308] QUrl::topLevelDomain() was deprecated in 5.15 and will be + removed in 6.0 + + - QtNetwork: + * QNetworkConfigurationManager, QNetworkConfiguration and QNetworkSession + are deprecated, to be removed in Qt 6. + + - [REVERTED] [QTBUG-80369] QAbstractSocket::error() (the getter) is + deprecated; superseded by socketError(). + - [REVERTED] [QTBUG-80369] QLocalSocket::error() (the getter) is + deprecated; superseded by socketError(). + - [QTBUG-80369] QSslSocket::sslErrors() (the getter) was deprecated and + superseded by sslHandshakeErrors() + - [REVERTED] [QTBUG-80369] QNetworkReply::error() (the getter) was + deprecated; superseded by networkError(). + - [QTBUG-81630][QTBUG-80312] QLinkedList is deprecated and will be moved + to Qt5Compat in Qt 6. It is recommended to use std::list instead. + - QLocalSocket::error() (the signal) is deprecated; superseded by + errorOccurred() + - QAbstractSocket::error() (the signal) is deprecated; superseded by + errorOccurred() + - QNetworkReply::error() (the signal) is deprecated; superseded by + errorOccurred() + +See also the various sections below, which include many more deprecations. + +**************************************************************************** +* QtCore * +**************************************************************************** + + - QCalendar::monthsInYear(QCalendar::Unspecified) now returns + maximumMonthsInYear(). QCalendar::daysInYear() now makes clear that its + handling of unspecified year is undefined. + + - Containers: + * Added operator-> to the key-value iterator for QHash/QMap. + + - QAbstractItemModel: + * [QTBUG-72587] The match() method now supports the new + Qt::RegularExpression match flag value. This will allow users to use + either a string or a fully configured QRegularExpression when doing + searches. In the second case, the case sensitivity flag will be + ignored if passed. + + - QByteArray: + * resize() will no longer shrink the capacity. That means resize(0) now + reliably preserves capacity(). + * Added the new fromBase64Encoding function. + * Added new flags to make fromBase64 / fromBase64Encoding strictly + validate their input, instead of skipping over invalid characters. + + - QCborArray: + * Fixed an infinite loop when operator[] was called with an index larger + than the array's size plus 1. + + - QCborMap: + * [QTBUG-83366] Fixed some issues relating to assigning elements from a + map to itself. + + - QCborValue: + * fromCbor() now limits decoding to at most 1024 nested maps, arrays, + and tags to prevent stack overflows. This should be sufficient for + most uses of CBOR. An API to limit further or to relax the limit will + be provided in 5.15. Meanwhile, if decoding more is required, + QCborStreamReader can be used (note that each level of map and array + allocates memory). + + - QDate: + * QDate::toString(Qt::DateFormat, QCalendar) no longer takes calendar + into account for Qt::TextDate. There was no matching support in + QDateTime and the locale-independent formats are intended to be + standard, rather than customized to the user. + + - QDateTime: + * Added some missing QCalendar variants of QDateTime::toString(). + Included docs for QCalendar variants in both QDate and QDateTime. + + - QFile: + * Introduce QFile::moveToTrash to allow applications to move files to + the trash. + + - QFileInfo: + * [QTBUG-75869] Add QFileInfo::isJunction so that applications can + recognize NTFS file system entries as junctions + + - QHash: + * Reverse iteration over QHash is now deprecated. + * insertMulti(), unite() and values(const Key &key) are now deprecated. + Please use QMultiHash instead. + + - QJsonObject: + * Fixed a regression from 5.13 that incorrect results when assigning + elements from an object to itself. + + - QLatin1String: + * Added compare(). + + - QLibrary and QPluginLoader: + * [QTBUG-39642] Fixed a deadlock that would happen if the plugin or + library being loaded has load-time initialization code (C++ global + variables) that recursed back into the same QLibrary or QPluginLoader + object. + + - QLocale: + * Deprecated toTime() variants taking a calendar. The calendar is + ignored in time parsing. + * Data used for currency formats in several locales and list patterns in + some locales have changed due to now parsing the CLDR data more + faithfully. + * [QTBUG-79902] Currency formats are now based on CLDR's accounting + formats, where they were previously mostly based (more or less by + accident) on standard formats. In particular, this now means negative + currency formats are specified, where available, where they (mostly) + were not previously. + + - QMap: + * [QTBUG-35544] insertMulti(), unite(), values(Key), uniqueKeys(), + count(Key) is now deprecated. Please use QMultiMap instead. + + - QObject: + * [QTBUG-76375] A logging category + qt.core.qmetaobject.connectslotsbyname was added, which will report + on the connections made by QMetaObject::connectSlotsByName(). + + - QProcess: + * Overloads of start/execute/startDatached that parse a single command + string into program and arguments have been marked as deprecated. A + static helper splitCommand has been added to construct a QStringList + from a command string. + + - QRandomGenerator: + * The system() random generator will now use the RDSEED instruction on + x86 processors whenever available as the first source of random data. + It will fall back to RDRAND and then to the system functions, in that + order. + + - QRegularExpression: + * The escape(), wildcardToRegularExpression() and anchoredPattern() + functions now have overloads taking a QStringView parameter. + + - QResource: + * Added uncompressedSize() and uncompressedData(), which will perform + any required decompression on the data, prior to returning (unlike + data() and size()). + + - QSet: + * Reverse iteration over QSet is now deprecated. + + - QStandardPaths: + * When used in a low-integrity process on Windows, + QStandardPaths::writableLocation returns respective low-integrity + paths. + + - QString: + * Added QString::isValidUtf16. + + - QStringView: + * Added QStringView::isValidUtf16. + * Added compare() overloads taking QLatin1String, QChar. + * Conversion from std::basic_string can now be constexpr (when + std::basic_string is). + + - QTimeZone: + * The constructor can now handle general UTC-offset zone names. The + reported id() of such a zone shall be in canonical form, so might not + match the ID passed to the constructor. + + - QXmlStream: + * QXmlStreamReader does now by default limit the expansion of entities + to 4096 characters. Documents where a single entity expands to more + characters than the limit are not considered well formed. The limit is + there to avoid DoS attacks through recursively expanding entities when + loading untrusted content. The limit can be changed through the + QXmlStreamReader::setEntityExpansionLimit() method. + + - moc: + * Moc now correctly sets a non-null QMetaObject::superClass for + Q_GADGETs that inherit from a template which inherits another + Q_GADGET. + * [QTBUG-74521][QTBUG-76598] moc can now output a ".d" dep file that can + be consumed by other build systems. + +**************************************************************************** +* QtGui * +**************************************************************************** + + - Extended QVulkanWindow to allow user to specify additional queues to be + created. + - Added API for starting interactive window resize and move operations + handled by the system. + + - QClipboard: + * Support lazily-provided copying of data to the clipboard on macOS + + - QCursor: + * [QTBUG-48701] QCursor::bitmap() and QCursor::mask() can now return + by-value instead of by-pointer. + + - QFont: + * Deprecated QFont::ForceIntegerMetrics and QFont::OpenGLCompatible, + with the intention of removing them in Qt 6.0.0. + + - QMarkdownWriter: + * [QTBUG-80603] Code blocks are no longer word-wrapped; the beginning + fence of a code block no longer has a space before the language string; + and the ending fence is no longer skipped in some cases where it was. + + - QPdfWriter: + * New API to provide external document XMP metadata and attach files to + PDF. + + - QTabletEvent: + * QTabletEvent::device() is deprecated, because the plan is to return + an object pointer in Qt 6 rather than an enum. The enum is now provided + by deviceType(). + * hiResGlobalX() and hiResGlobalY() are deprecated, because globalPosF() + has the same resolution. But globalPosF() (and several others) will + probably be renamed in Qt 6. The replacements are not in place yet. + * [QTBUG-77826] Local coordinates are now correct when the event is + delivered to a nested window on X11. + + - Text: + * Fixed a problem where pixel sizes would be truncated before calculating + glyph positions. + * Fixed an issue with QFont::PreferNoShaping where boxes would appear in + place of unprintable characters. + * Fixed a problem where certain bold fonts would be synthetically + emboldened by Qt when using the Freetype font engine. + + - Application palettes are now resolved against the platform's theme + palette, the same way widget palettes are resolved against their parents, + and the application palette. This means the application palette reflected + through QGuiApplication::palette() may not be exactly the same palette as + set via QGuiApplication::setPalette(). + +**************************************************************************** +* QtWidgets * +**************************************************************************** + + - Added QStyleOptionTabV4 as a subclass of QStyleOptionTab so that the + tab's index information can be obtained. + + - ItemViews: + * [QTBUG-76423] The convenience views QList/Table/TreeWidgetItem now + treat a default constructed QBrush or QSize as an empty QVariant which + allows resetting of the values set to it's default values. + + - QApplication: + * The globalStrut property has been deprecated and will be removed from + Qt 6. + + - QButtonGroup: + * Added signals idClicked/Pressed/Released/Toggled that replace the + deprecated signal overloads. + + - QComboBox: + * QComboBox got a new property 'placeholderText' + * Support checkable items in styles that use a popup for the dropdown. + * the SizeAdjustPolicy value AdjustToMinimumContentLength is deprecated, + use AdjustToContents or AdjustToContentsOnFirstShow instead. + + - QGraphicsView: + * Fixed a bug where hover events would not be delivered if the item was + added while blocked by a modal panel. + + - QLabel: + * [QTBUG-48701] QLabel::pixmap() and QLabel::picture() can now return + by-value instead of by-pointer. + + - QLineEdit: + * Inputmask X character now requires non-blank input. + + - QMenu: + * a popup menu hides when a QWidgetAction added to it fires the + triggered signal. + + - QShortcut: + * QShortcut ctor has now pointer to member function overloads + + - QStyle: + * You can now set the CSS property 'icon' on a QPushButton to override + which icon to draw. + + - QSystemTrayIcon: + * On macOS, clicking on the message will remove the notification. + + - QTabWidget/QTabBar: + * Tabs can now be hidden with setTabVisible + + - QWidget: + * Fonts and palette settings are inherited by children from their + parents even if the children have application-wide platform theme + overrides. + + - QWizard: + * visitedPages has been deprecated, use visitedIds instead. + +**************************************************************************** +* QtNetwork * +**************************************************************************** + + - A new signal introduced to report when a valid session ticket is received + (TLS 1.3) + + - SSL: + * Removed OpenSSL 1.0.x support, now 1.1.x is required + * The minimum required version of OpenSSL is now 1.1.1. + + - QSslCertificate: + * [QTBUG-72587] Add overload of fromPath that does not make use of + QRegExp and deprecate the QRegExp variant. + +**************************************************************************** +* QtSql * +**************************************************************************** + + - QMYSQL: + * Removed support for MySql < 5.0 since 5.0 was released 14 years ago. + * The QMYSQL plugin can now be build with the MariaDB C connector libs + on Windows. + + - QSqlDriver: + * The one-arg version of QSqlDriver::notifcation() is now deprecated. + +**************************************************************************** +* QTestLib * +**************************************************************************** + + - The formerly named 'xunitxml' test reporter has been renamed to what it + actually is: a JUnit test reporter, and is now triggered by passing -o + junitxml to the test binary. + +**************************************************************************** +* QtXml * +**************************************************************************** + + - [QTBUG-76177] SAX classes are now deprecated. Use QXmlStreamReader, + QXmlStreamWriter in QtCore instead. + +**************************************************************************** +* Configure * +**************************************************************************** + + - Add switch "-coverage source-based" to enable clang's "source-based" code + coverage feature. This can be used for code coverage analysis. + + - X11: + * [QTBUG-67277][QTBUG-30939] The minimal required version of libxcb now + is 1.11. + * [QTBUG-67277][QTBUG-30939] Removed -qt-xcb, -system-xcb, -xkb, + -xcb-xinput switches. + +**************************************************************************** +* cmake * +**************************************************************************** + + - Fixed an issue where some Qt location and declarative plugins whose name + did not end with "Plugin" where not imported by the corresponding Qt + component package. + +**************************************************************************** +* Third-Party Code * +**************************************************************************** + + - libjpeg-turbo was updated to version 2.0.4 + + - X11: + * [QTBUG-67277][QTBUG-30939] Removed all bundled XCB libs, with the + exception of xcb-xinput, which is not available on systems with libxcb + 1.11. + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + + - Linux: + * Enable accessibility on Linux when Orca is started by hand + * [QTBUG-78754] Vulkan is now supported by eglfs (eglfs_viv backend) on + i.MX8 devices with the Vivante graphics stack. This is done via + VK_KHR_display so no windowing system is required. + + - X11: + * [QTBUG-67277][QTBUG-30939] XKB and XInput2 now are mandatory + dependencies for XCB plugin. XCB-XKB is a part of libxcb 1.11 + releases. XCB-XInput is not part of libxcb 1.11 releases, but Qt + builders can use the -bundled-xcb-xinput switch. + + - Android: + * [REVERTED] Qt::MaximizeUsingFullscreenGeometryHint window flag is + now supported, and will make the window fullscreen, but keep the + system UI on-screen, with a translucent background color. + * [QTBUG-82120] Use native file dialog by default for open and save + operations. + + - Windows: + * Fixed a bug where some fonts would not be accessible by + referencing their typographic name. + * Fixed a 2 pixel offset on glyphs when using color fonts or any + hinting preference other than the default (full) hinting. + + - WebAssembly: + * Updated emscripten to version 1.39.8 From bfde4f4a962ca56a7f2d7d63e788e79aa64cfb1f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 27 Apr 2020 13:44:29 +0200 Subject: [PATCH 24/44] torrent example: fix stripping of file extension Due to QChar being convertible from almost any integral type, the old code actually called QString::remove(QChar). Fix by using QString::chop() instead. Change-Id: I345b018aa137ecff608a130e69ade5d37ef0805c Reviewed-by: Edward Welbourne Reviewed-by: Paul Wicking --- examples/network/torrent/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/network/torrent/mainwindow.cpp b/examples/network/torrent/mainwindow.cpp index c343ee81b94..0d568585145 100644 --- a/examples/network/torrent/mainwindow.cpp +++ b/examples/network/torrent/mainwindow.cpp @@ -407,7 +407,7 @@ bool MainWindow::addTorrent(const QString &fileName, const QString &destinationF QString baseFileName = QFileInfo(fileName).fileName(); if (baseFileName.toLower().endsWith(".torrent")) - baseFileName.remove(baseFileName.size() - 8); + baseFileName.chop(8); item->setText(0, baseFileName); item->setToolTip(0, tr("Torrent: %1
Destination: %2") From 85c09f3c518c3dcd3ba3503adb9ae9a0eab34253 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 6 Apr 2020 14:04:11 +0200 Subject: [PATCH 25/44] Use QMAKE_TARGET for the name of the object script file Since TARGET at this point contains the path to where the target will be then it can include ".." as part of it which will cause problems when building for Android on Windows. Therefore, QMAKE_TARGET should be used as an identifier here as the path is not needed. Change-Id: Idb8babd0459c65cbcfd64fe47baeac4303a3fd87 Reviewed-by: Joerg Bornemann --- qmake/generators/unix/unixmake2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 9789c9c8e52..0412b528134 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -1560,7 +1560,7 @@ std::pair UnixMakefileGenerator::writeObjectsPart(QTextStream &t, objectsLinkLine = "$(OBJECTS)"; } else { QString ld_response_file = fileVar("OBJECTS_DIR"); - ld_response_file += var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET"); + ld_response_file += var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("QMAKE_TARGET"); if (!var("BUILD_NAME").isEmpty()) ld_response_file += "." + var("BUILD_NAME"); if (!var("MAKEFILE").isEmpty()) From 084525a034fa9306247eec2005fa9e8279753829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 16 Apr 2020 17:40:54 +0200 Subject: [PATCH 26/44] QNAM/QNetConMon: emit networkAccessibleChanged on changes For compatibility with the bearer functionality. Change-Id: I26ba6bad046b3f99c8ee13e709a26ddcbd868e25 Reviewed-by: Timur Pocheptsov --- src/network/access/qnetworkaccessmanager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 6f6aa73f62e..d36cb46ce17 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -2116,7 +2116,10 @@ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) Q_Q(QNetworkAccessManager); if (statusMonitor.isEnabled()) { + auto previous = networkAccessible; networkAccessible = isOnline ? QNetworkAccessManager::Accessible : QNetworkAccessManager::NotAccessible; + if (previous != networkAccessible) + emit q->networkAccessibleChanged(networkAccessible); return; } From 562d7ded3b23f7aa92cbe4f3132bec0053ed7163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 28 Apr 2020 10:52:01 +0200 Subject: [PATCH 27/44] macOS: draw toolbar separator line in unfifed mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 836a2fb8 changed the contentBorderThickness property to also include the title bar height, in order to position sheets correctly when unified toolbar mode is enabled. As an accidental side effect this made Qt stop drawing the toolbar separator line. Account for the added title bar height also in testContentBorderAreaPosition(). Task-number: QTBUG-78110 Change-Id: I4ecfd010a6784bbb592646affc676d8cbfd9b6da Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoawindow.mm | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 79dfe58a4e2..2cbdb3c8731 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1815,8 +1815,17 @@ void QCocoaWindow::updateNSToolbar() bool QCocoaWindow::testContentBorderAreaPosition(int position) const { - return isContentView() && m_drawContentBorderGradient && - 0 <= position && position < [m_view.window contentBorderThicknessForEdge:NSMaxYEdge]; + if (!m_drawContentBorderGradient || !isContentView()) + return false; + + // Determine if the given y postion (relative to the content area) is inside the + // unified toolbar area. Note that the value returned by contentBorderThicknessForEdge + // includes the title bar height; subtract it. + const int contentBorderThickness = [m_view.window contentBorderThicknessForEdge:NSMaxYEdge]; + const NSRect frameRect = m_view.window.frame; + const NSRect contentRect = [m_view.window contentRectForFrameRect:frameRect]; + const CGFloat titlebarHeight = frameRect.size.height - contentRect.size.height; + return 0 <= position && position < (contentBorderThickness - titlebarHeight); } qreal QCocoaWindow::devicePixelRatio() const From 85dab30b157babc5c59920ddc8a1710fb6d9efd1 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Fri, 24 Apr 2020 13:52:32 +0200 Subject: [PATCH 28/44] Fix building of autotests for certain configurations When a configuration is static and has builtin_testdata defined, it was possible that the "testdata" resource that is generated in testcase.prf was used for a qmlimportscan directly. This generated test data resource is no file though. It's a "qmake struct" that contains files and a base folder so that we should add every file from the "file list" of that struct. It is possible, that the generated resource has a base, but no files. Thus we need two loops or we can end up with a command line that ends with "-qmldir". If qmlimportscanner decided to warn/error out in this case in the future this feature could be broken and the point of breakage might not be obvious. Change-Id: I2111f594f7d5cf40521b8fe9236a8be9e2ed1b07 Reviewed-by: Edward Welbourne Reviewed-by: Joerg Bornemann --- mkspecs/features/qt.prf | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index fc46bcb74b4..6fe0059bf73 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -279,11 +279,22 @@ contains(all_qt_module_deps, qml): \ for (QMLPATH, QMLPATHS): \ IMPORTPATHS += -importPath $$system_quote($$QMLPATH) - # add qrc files, too - !isEmpty(RESOURCES) { - IMPORTPATHS += -qrcFiles - for (RESOURCE, RESOURCES): \ - IMPORTPATHS += $$absolute_path($$system_quote($$RESOURCE), $$_PRO_FILE_PWD_) + # add resources to qmlimportscanner + for (RESOURCE, RESOURCES) { + defined($${RESOURCE}.files, var) { + # in case of a "struct", add the struct's files + base = $$RESOURCE.base + for (f, $$RESOURCE.files): SCANNERRESOURCES += "$$base/$$f" + } else { + # if the resource is a file, just add it + SCANNERRESOURCES += $$RESOURCE + } + } + + !isEmpty(SCANNERRESOURCES) { + IMPORTPATHS += -qrcFiles + for (RESOURCE, SCANNERRESOURCES) + IMPORTPATHS += $$absolute_path($$system_quote($$RESOURCE), $$_PRO_FILE_PWD_) } From e6a39c13bfe44719ee345419e98638e5f38fe7ee Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Thu, 23 Apr 2020 19:28:38 +0200 Subject: [PATCH 29/44] Doc: Remove manual duplicate alias descriptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the introduction of the \typealias command to QDoc, QDoc generates a standardized line for aliased types. This patch removes duplication caused by the change in QDoc. Change-Id: I1a01c378f85b0decb7c0400a3b21146f0898c6ec Reviewed-by: Topi Reiniö --- src/corelib/text/qstring.cpp | 32 -------------------------------- src/network/ssl/qdtls.cpp | 2 -- 2 files changed, 34 deletions(-) diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 210a8afc533..54a2f9cdd2f 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -1803,57 +1803,39 @@ const QString::Null QString::null = { }; /*! \typedef QString::const_iterator - This typedef provides an STL-style const iterator for QString. - \sa QString::iterator */ /*! \typedef QString::iterator - The QString::iterator typedef provides an STL-style non-const - iterator for QString. - \sa QString::const_iterator */ /*! \typedef QString::const_reverse_iterator \since 5.6 - This typedef provides an STL-style const reverse iterator for QString. - \sa QString::reverse_iterator, QString::const_iterator */ /*! \typedef QString::reverse_iterator \since 5.6 - This typedef provides an STL-style non-const reverse iterator for QString. - \sa QString::const_reverse_iterator, QString::iterator */ /*! \typedef QString::size_type - - The QString::size_type typedef provides an STL-style type for sizes (int). */ /*! \typedef QString::difference_type - - The QString::size_type typedef provides an STL-style type for difference between pointers. */ /*! \typedef QString::const_reference - - This typedef provides an STL-style const reference for a QString element (QChar). */ /*! \typedef QString::reference - - This typedef provides an STL-style - reference for a QString element (QChar). */ /*! @@ -1871,8 +1853,6 @@ const QString::Null QString::null = { }; /*! \typedef QString::value_type - - This typedef provides an STL-style value type for QString. */ /*! \fn QString::iterator QString::begin() @@ -9537,8 +9517,6 @@ QString &QString::setRawData(const QChar *unicode, int size) \typedef QLatin1String::iterator \since 5.10 - This typedef provides an STL-style const iterator for QLatin1String. - QLatin1String does not support mutable iterators, so this is the same as const_iterator. @@ -9549,8 +9527,6 @@ QString &QString::setRawData(const QChar *unicode, int size) \typedef QLatin1String::const_iterator \since 5.10 - This typedef provides an STL-style const iterator for QLatin1String. - \sa iterator, const_reverse_iterator */ @@ -9558,8 +9534,6 @@ QString &QString::setRawData(const QChar *unicode, int size) \typedef QLatin1String::reverse_iterator \since 5.10 - This typedef provides an STL-style const reverse iterator for QLatin1String. - QLatin1String does not support mutable reverse iterators, so this is the same as const_reverse_iterator. @@ -9570,8 +9544,6 @@ QString &QString::setRawData(const QChar *unicode, int size) \typedef QLatin1String::const_reverse_iterator \since 5.10 - This typedef provides an STL-style const reverse iterator for QLatin1String. - \sa reverse_iterator, const_iterator */ @@ -10472,8 +10444,6 @@ QDataStream &operator>>(QDataStream &in, QString &str) \typedef QStringRef::const_iterator \since 5.4 - This typedef provides an STL-style const iterator for QStringRef. - \sa QStringRef::const_reverse_iterator */ @@ -10481,8 +10451,6 @@ QDataStream &operator>>(QDataStream &in, QString &str) \typedef QStringRef::const_reverse_iterator \since 5.7 - This typedef provides an STL-style const reverse iterator for QStringRef. - \sa QStringRef::const_iterator */ diff --git a/src/network/ssl/qdtls.cpp b/src/network/ssl/qdtls.cpp index a2280a7d102..74fb691dde6 100644 --- a/src/network/ssl/qdtls.cpp +++ b/src/network/ssl/qdtls.cpp @@ -278,8 +278,6 @@ /*! \typedef QDtls::GeneratorParameters - - This is a synonym for QDtlsClientVerifier::GeneratorParameters. */ /*! From 5e8bd204e2af4fb53ef64c9e385223b52c26006e Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Tue, 28 Apr 2020 08:21:47 +1000 Subject: [PATCH 30/44] wasm: fix network download crash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems it was defaulting to the indexdb filesystem, but it is not mounted. Fixes: QTBUG-83827 Change-Id: I1f81d790e5786fe41b59c0f41ca7f6025732c9b2 Reviewed-by: Morten Johan Sørvig --- src/network/access/qnetworkreplywasmimpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp index af8b39bab6f..5b840147890 100644 --- a/src/network/access/qnetworkreplywasmimpl.cpp +++ b/src/network/access/qnetworkreplywasmimpl.cpp @@ -245,7 +245,7 @@ void QNetworkReplyWasmImplPrivate::doSendRequest() attr.password = request.url().password().toUtf8(); } - attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_PERSIST_FILE | EMSCRIPTEN_FETCH_REPLACE; + attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY; QNetworkRequest::CacheLoadControl CacheLoadControlAttribute = (QNetworkRequest::CacheLoadControl)request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(); From 15026f309b3c69b94de39e0cbeba09dd8bdd5e29 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 27 Apr 2020 15:28:10 +0200 Subject: [PATCH 31/44] QMacStyle - change the arrow type only for 'OnlyOneTab' option It appears the hack was not needed when we have several tabs (popup button works as expected). Otherwise, this button suddenly has a different size: it's bigger when selected and smaller if not (and the holes clipped under the tab shape are becoming quite visible in the dark mode to the left and right of a tabbar). For the single tab we need some adjustment in the size not to have visible difference between inactive/selected tab. Fixes: QTBUG-83216 Change-Id: I52511e610ae7b36f261e0218b7e432e747bc9491 Reviewed-by: Volker Hilsheimer --- src/plugins/styles/mac/qmacstyle_mac.mm | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 8e4aaa19c7b..84233d65211 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -3977,13 +3977,19 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter // which makes no sense on tabs. NSPopUpArrowPosition oldPosition = NSPopUpArrowAtCenter; NSPopUpButtonCell *pbCell = nil; - if (isPopupButton) { + auto rAdjusted = r; + if (isPopupButton && tp == QStyleOptionTab::OnlyOneTab) { pbCell = static_cast(pb.cell); oldPosition = pbCell.arrowPosition; pbCell.arrowPosition = NSPopUpNoArrow; + if (pb.state == NSOffState) { + // NSPopUpButton in this state is smaller. + rAdjusted.origin.x -= 3; + rAdjusted.size.width += 6; + } } - [pb.cell drawBezelWithFrame:r inView:pb.superview]; + [pb.cell drawBezelWithFrame:rAdjusted inView:pb.superview]; if (pbCell) // Restore, we may reuse it for a ComboBox. pbCell.arrowPosition = oldPosition; From 042b118cafc68c677e9eafa7f718a025a34940da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 29 Apr 2020 19:14:06 +0200 Subject: [PATCH 32/44] macOS: Avoid modifying hash while iterating it QCocoaTouch sneakily updated the list of active touches in the destructor, causing problems when we switched from Q_FOREACH to ranged-for. Fixes: QTBUG-83876 Change-Id: If7ec9e9116b7eb581580b461ae12ad70c739906d Reviewed-by: Simon Hausmann --- src/plugins/platforms/cocoa/qmultitouch_mac.mm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qmultitouch_mac.mm b/src/plugins/platforms/cocoa/qmultitouch_mac.mm index 95256657fe2..ac2317b2178 100644 --- a/src/plugins/platforms/cocoa/qmultitouch_mac.mm +++ b/src/plugins/platforms/cocoa/qmultitouch_mac.mm @@ -184,7 +184,10 @@ QCocoaTouch::getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch) if (_touchCount != _currentTouches.size()) { // Remove all instances, and basically start from scratch: touchPoints.clear(); - for (QCocoaTouch *qcocoaTouch : _currentTouches) { + // Deleting touch points will remove them from current touches, + // so we make a copy of the touches before iterating them. + const auto currentTouchesSnapshot = _currentTouches; + for (QCocoaTouch *qcocoaTouch : currentTouchesSnapshot) { if (!_updateInternalStateOnly) { qcocoaTouch->_touchPoint.state = Qt::TouchPointReleased; touchPoints.insert(qcocoaTouch->_touchPoint.id, qcocoaTouch->_touchPoint); From f9d219b92636fc279a3dc0c0e667b6668d0943db Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 27 Apr 2020 14:55:01 +0200 Subject: [PATCH 33/44] iOS: Teach edit menu popover to have a readonly mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should have foreseen the need for customizing this menu in 2014 when Controls 1 needed it, but here we are: Qt 5 is "done", this still wasn't done, and it's too late for new enum values in 5.15. So the workaround is to add a property on the focus object that the iOS plugin can query, and give us a menu that has Copy instead of Paste. Task-number: QTBUG-83811 Change-Id: Id8d18260002952fe7aa77aa5608cf7d0e440dacb Reviewed-by: Richard Moe Gustavsen Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiostextresponder.mm | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index a3350bda87b..19e476a0645 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -416,6 +416,17 @@ if (unknownAction) return [super canPerformAction:action withSender:sender]; + + QObject *focusObject = QGuiApplication::focusObject(); + if (focusObject && focusObject->property("qt_im_readonly").toBool()) { + // exceptional menu items for read-only views: do include Copy, do not include Paste etc. + if (action == @selector(cut:) + || action == @selector(paste:) + || action == @selector(delete:)) + return NO; + if (action == @selector(copy:)) + return YES; + } return (hasSelection && isEditAction) || (!hasSelection && isSelectAction); } From 91d18c646443c812addf6d1cdada99d3c2d3a3ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 24 Apr 2020 15:36:23 +0200 Subject: [PATCH 34/44] iOS: Pick up theme palette from system colors For now we just fill out the system palette, and react to the system changing theme from dark to light. A further improvement would be to fill in the control-specific palettes. Change-Id: I764db4415f5b55ccb193dae43e9f4386c765b30b Fixes: QTBUG-42944 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.mm | 13 +++++++++ src/plugins/platforms/ios/qiostheme.h | 5 +++- src/plugins/platforms/ios/qiostheme.mm | 38 ++++++++++++++++++++++--- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 9aba658479a..c3376c08e86 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -45,6 +45,7 @@ #include "qiosapplicationdelegate.h" #include "qiosviewcontroller.h" #include "quiview.h" +#include "qiostheme.h" #include @@ -207,6 +208,18 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) [super sendEvent:event]; } +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection +{ + [super traitCollectionDidChange:previousTraitCollection]; + + if (self.screen == UIScreen.mainScreen) { + if (previousTraitCollection.userInterfaceStyle != self.traitCollection.userInterfaceStyle) { + QIOSTheme::initializeSystemPalette(); + QWindowSystemInterface::handleThemeChange(nullptr); + } + } +} + @end // ------------------------------------------------------------------------- diff --git a/src/plugins/platforms/ios/qiostheme.h b/src/plugins/platforms/ios/qiostheme.h index c917679a91e..c9d833713da 100644 --- a/src/plugins/platforms/ios/qiostheme.h +++ b/src/plugins/platforms/ios/qiostheme.h @@ -65,9 +65,12 @@ public: static const char *name; + static void initializeSystemPalette(); + private: mutable QHash m_fonts; - QPalette m_systemPalette; + + static QPalette s_systemPalette; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiostheme.mm b/src/plugins/platforms/ios/qiostheme.mm index 5534264a601..626fbb66fe9 100644 --- a/src/plugins/platforms/ios/qiostheme.mm +++ b/src/plugins/platforms/ios/qiostheme.mm @@ -44,6 +44,7 @@ #include #include +#include #include #include @@ -63,10 +64,8 @@ QT_BEGIN_NAMESPACE const char *QIOSTheme::name = "ios"; QIOSTheme::QIOSTheme() - : m_systemPalette(*QPlatformTheme::palette(QPlatformTheme::SystemPalette)) { - m_systemPalette.setBrush(QPalette::Highlight, QColor(204, 221, 237)); - m_systemPalette.setBrush(QPalette::HighlightedText, Qt::black); + initializeSystemPalette(); } QIOSTheme::~QIOSTheme() @@ -74,10 +73,41 @@ QIOSTheme::~QIOSTheme() qDeleteAll(m_fonts); } +QPalette QIOSTheme::s_systemPalette; + +void QIOSTheme::initializeSystemPalette() +{ + Q_DECL_IMPORT QPalette qt_fusionPalette(void); + s_systemPalette = qt_fusionPalette(); + + if (@available(ios 13.0, *)) { + s_systemPalette.setBrush(QPalette::Window, qt_mac_toQBrush(UIColor.systemGroupedBackgroundColor.CGColor)); + s_systemPalette.setBrush(QPalette::Active, QPalette::WindowText, qt_mac_toQBrush(UIColor.labelColor.CGColor)); + + s_systemPalette.setBrush(QPalette::Base, qt_mac_toQBrush(UIColor.secondarySystemGroupedBackgroundColor.CGColor)); + s_systemPalette.setBrush(QPalette::Active, QPalette::Text, qt_mac_toQBrush(UIColor.labelColor.CGColor)); + + s_systemPalette.setBrush(QPalette::Button, qt_mac_toQBrush(UIColor.secondarySystemBackgroundColor.CGColor)); + s_systemPalette.setBrush(QPalette::Active, QPalette::ButtonText, qt_mac_toQBrush(UIColor.labelColor.CGColor)); + + s_systemPalette.setBrush(QPalette::Active, QPalette::BrightText, qt_mac_toQBrush(UIColor.lightTextColor.CGColor)); + s_systemPalette.setBrush(QPalette::Active, QPalette::PlaceholderText, qt_mac_toQBrush(UIColor.placeholderTextColor.CGColor)); + + s_systemPalette.setBrush(QPalette::Active, QPalette::Link, qt_mac_toQBrush(UIColor.linkColor.CGColor)); + s_systemPalette.setBrush(QPalette::Active, QPalette::LinkVisited, qt_mac_toQBrush(UIColor.linkColor.CGColor)); + + s_systemPalette.setBrush(QPalette::Highlight, QColor(11, 70, 150, 60)); + s_systemPalette.setBrush(QPalette::HighlightedText, qt_mac_toQBrush(UIColor.labelColor.CGColor)); + } else { + s_systemPalette.setBrush(QPalette::Highlight, QColor(204, 221, 237)); + s_systemPalette.setBrush(QPalette::HighlightedText, Qt::black); + } +} + const QPalette *QIOSTheme::palette(QPlatformTheme::Palette type) const { if (type == QPlatformTheme::SystemPalette) - return &m_systemPalette; + return &s_systemPalette; return 0; } From 1eeabc6652220ff263eaa63872cd52c1693cbf69 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 30 Apr 2020 09:39:16 +0200 Subject: [PATCH 35/44] Don't output a warning that can trigger before Qt has fully initialized If a warning is outputted before Qt has had a chance to initialize the logging rules then it will cause it to hang as it will be stuck trying to initialize but can't continue because it needs to output the warning which triggered during that initialization. Therefore the warning should not be outputted to avoid this from happening. Change-Id: I202752c377bf69def2f7fb76be71b78d00ad3fd5 Reviewed-by: Volker Hilsheimer --- src/corelib/text/qlocale.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp index 60bfac62ab5..e74b825774b 100644 --- a/src/corelib/text/qlocale.cpp +++ b/src/corelib/text/qlocale.cpp @@ -763,8 +763,6 @@ static void updateSystemPrivate() const ushort group = res.toString().at(0).unicode(); if (group != globalLocaleData.m_decimal) globalLocaleData.m_group = group; - else if (group == globalLocaleData.m_group) - qWarning("System-supplied decimal and grouping character are both 0x%hx", group); } res = sys_locale->query(QSystemLocale::ZeroDigit, QVariant()); From 52a2505672cbb1ca8b5b32f7bc1259485c65483b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Apr 2020 13:58:33 -0300 Subject: [PATCH 36/44] QCborValue: avoid signed integer oveflows when decoding time_t QDateTime::fromSecsSinceEpoch() multiplies by 1000 but does not check for overflow. That means we must do so in QCborValue validation. We can't use mul_overflow on 32-bit platforms, so we do a compare- and-branch there. For 64-bit platforms, we prefer to do the multiplication with checked overflow, as the common case is that it will not overflow and we'll need the multiplication anyway. Change-Id: Ibdc95e9af7bd456a94ecfffd16060cba6f1c86b8 Reviewed-by: Edward Welbourne --- src/corelib/serialization/qcborvalue.cpp | 23 +++- .../qcborvalue/tst_qcborvalue.cpp | 109 ++++++++++++++++++ 2 files changed, 128 insertions(+), 4 deletions(-) diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index a3729b4ef9c..f5cccf1be18 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -788,10 +788,25 @@ static QCborValue::Type convertToExtendedType(QCborContainerPrivate *d) // The data is supposed to be US-ASCII. If it isn't (contains UTF-8), // QDateTime::fromString will fail anyway. dt = QDateTime::fromString(b->asLatin1(), Qt::ISODateWithMs); - } else if (tag == qint64(QCborKnownTags::UnixTime_t) && e.type == QCborValue::Integer) { - dt = QDateTime::fromSecsSinceEpoch(e.value, Qt::UTC); - } else if (tag == qint64(QCborKnownTags::UnixTime_t) && e.type == QCborValue::Double) { - dt = QDateTime::fromMSecsSinceEpoch(qint64(e.fpvalue() * 1000), Qt::UTC); + } else if (tag == qint64(QCborKnownTags::UnixTime_t)) { + qint64 msecs; + bool ok = false; + if (e.type == QCborValue::Integer) { +#if QT_POINTER_SIZE == 8 + // we don't have a fast 64-bit mul_overflow implementation on + // 32-bit architectures. + ok = !mul_overflow(e.value, qint64(1000), &msecs); +#else + static const qint64 Limit = std::numeric_limits::max() / 1000; + ok = (e.value > -Limit && e.value < Limit); + if (ok) + msecs = e.value * 1000; +#endif + } else if (e.type == QCborValue::Double) { + ok = convertDoubleTo(round(e.fpvalue() * 1000), &msecs); + } + if (ok) + dt = QDateTime::fromMSecsSinceEpoch(msecs, Qt::UTC); } if (dt.isValid()) { QByteArray text = dt.toString(Qt::ISODateWithMs).toLatin1(); diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index 64321c11faa..0b3046fbdc7 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -106,6 +106,8 @@ private slots: void fromCborStreamReaderIODevice(); void validation_data(); void validation(); + void extendedTypeValidation_data(); + void extendedTypeValidation(); void hugeDeviceValidation_data(); void hugeDeviceValidation(); void recursionLimit_data(); @@ -118,6 +120,68 @@ private slots: void streamVariantSerialization(); }; +namespace SimpleEncodeToCbor { +inline size_t lengthOf(int) +{ + return 1; // encode as byte +} + +template inline size_t lengthOf(T) +{ + return sizeof(T); +} + +static void encodeOneAt(char *ptr, int v) +{ + // encode as byte + *ptr = char(v); +} + +template +static typename std::enable_if::value>::type +encodeOneAt(char *ptr, T v) +{ + qToBigEndian(v, ptr); +} + +template +static typename std::enable_if::value || + std::is_same::value>::type +encodeOneAt(char *ptr, T v) +{ + typename QIntegerForSizeof::Unsigned u; + memcpy(&u, &v, sizeof(u)); + qToBigEndian(u, ptr); +} + +static char *encodeAt(char *ptr) +{ + return ptr; +} + +template +static char *encodeAt(char *ptr, Arg0 a0, Args... a) +{ + encodeOneAt(ptr, a0); + return encodeAt(ptr + lengthOf(a0), a...); +} + +} // namespace SimpleEncodetoCbor + +template +static QByteArray encode(Args... a) +{ + // this would be much easier with C++17 fold expressions... + using namespace SimpleEncodeToCbor; + using namespace std; + size_t lengths[] = { lengthOf(a)... }; + size_t total = accumulate(begin(lengths), end(lengths), size_t(0), plus{}); + QByteArray result(QByteArray::size_type(total), Qt::Uninitialized); + char *ptr = result.data(); + encodeAt(ptr, a...); + return result; +} + // Get the validation data from TinyCBOR (see src/3rdparty/tinycbor/tests/parser/data.cpp) #include "data.cpp" @@ -1882,6 +1946,51 @@ void tst_QCborValue::validation() } } +void tst_QCborValue::extendedTypeValidation_data() +{ + QTest::addColumn("data"); + QTest::addColumn("expected"); + + // QDateTime currently stores time in milliseconds, so make sure + // we don't overflow + { + quint64 limit = std::numeric_limits::max() / 1000; + QTest::newRow("UnixTime_t:integer-overflow-positive") + << encode(0xc1, 0x1b, limit + 1) + << QCborValue(QCborKnownTags::UnixTime_t, qint64(limit) + 1); + QTest::newRow("UnixTime_t:integer-overflow-negative") + << encode(0xc1, 0x3b, limit) + << QCborValue(QCborKnownTags::UnixTime_t, -qint64(limit) - 1); + + double fplimit = std::numeric_limits::min() / (-1000.); // 2^63 ms + QTest::newRow("UnixTime_t:fp-overflow-positive") + << encode(0xc1, 0xfb, fplimit) + << QCborValue(QCborKnownTags::UnixTime_t, fplimit); + QTest::newRow("UnixTime_t:fp-overflow-negative") + << encode(0xc1, 0xfb, -fplimit) + << QCborValue(QCborKnownTags::UnixTime_t, -fplimit); + } +} + +void tst_QCborValue::extendedTypeValidation() +{ + QFETCH(QByteArray, data); + QFETCH(QCborValue, expected); + + QCborParserError error; + QCborValue decoded = QCborValue::fromCbor(data, &error); + QVERIFY2(error.error == QCborError(), qPrintable(error.errorString())); + QCOMPARE(error.offset, data.size()); + QCOMPARE(decoded, expected); + + QByteArray encoded = decoded.toCbor(); +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) + // behavior change, see qdatetime.cpp:fromIsoTimeString + QEXPECT_FAIL("DateTime:Null-at-19", "QDateTime parsing fixed, but only in 6.0", Abort); +#endif + QCOMPARE(encoded, data); +} + void tst_QCborValue::hugeDeviceValidation_data() { addValidationHugeDevice(MaxByteArraySize + 1, MaxStringSize + 1); From 2a53017df488b3cedbfbf5a56bf105b9fc5392fa Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Apr 2020 14:00:05 -0300 Subject: [PATCH 37/44] QCborValue: add an extra check against producing invalid ISO dates By QCborValue design, we store the textual representation in ISO format, equivalent of CBOR tag 0, which isn't allowed to have negative years or beyond year 10000. Change-Id: Ibdc95e9af7bd456a94ecfffd16060ccff359c296 Reviewed-by: Ulf Hermann --- src/corelib/serialization/qcborvalue.cpp | 10 ++++++---- .../serialization/qcborvalue/tst_qcborvalue.cpp | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index f5cccf1be18..30bfa367edb 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -810,10 +810,12 @@ static QCborValue::Type convertToExtendedType(QCborContainerPrivate *d) } if (dt.isValid()) { QByteArray text = dt.toString(Qt::ISODateWithMs).toLatin1(); - replaceByteData(text, text.size(), Element::StringIsAscii); - e.type = QCborValue::String; - d->elements[0].value = qint64(QCborKnownTags::DateTimeString); - return QCborValue::DateTime; + if (!text.isEmpty()) { + replaceByteData(text, text.size(), Element::StringIsAscii); + e.type = QCborValue::String; + d->elements[0].value = qint64(QCborKnownTags::DateTimeString); + return QCborValue::DateTime; + } } break; } diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index 0b3046fbdc7..d035ca4ee54 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -1970,6 +1970,21 @@ void tst_QCborValue::extendedTypeValidation_data() << encode(0xc1, 0xfb, -fplimit) << QCborValue(QCborKnownTags::UnixTime_t, -fplimit); } + + // But in fact, QCborValue stores date/times as their ISO textual + // representation, which means it can't represent dates before year 1 or + // after year 9999. + { + QDateTime dt(QDate(-1, 1, 1), QTime(0, 0), Qt::UTC); + QTest::newRow("UnixTime_t:negative-year") + << encode(0xc1, 0x3b, quint64(-dt.toSecsSinceEpoch()) - 1) + << QCborValue(QCborKnownTags::UnixTime_t, dt.toSecsSinceEpoch()); + + dt.setDate(QDate(10000, 1, 1)); + QTest::newRow("UnixTime_t:year10k") + << encode(0xc1, 0x1b, quint64(dt.toSecsSinceEpoch())) + << QCborValue(QCborKnownTags::UnixTime_t, dt.toSecsSinceEpoch()); + } } void tst_QCborValue::extendedTypeValidation() From 8366c06d46f63b12b88abaddb0ff7a6b6dda75a4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Apr 2020 15:13:14 -0300 Subject: [PATCH 38/44] QCborValue: add tests of parsing invalid ISO date-time strings We rely on QDateTime::fromString being proper, so this is not extensive testing. Change-Id: Ibdc95e9af7bd456a94ecfffd160610cdac5d62e1 Reviewed-by: Thiago Macieira Reviewed-by: Edward Welbourne --- .../qcborvalue/tst_qcborvalue.cpp | 76 ++++++++++++++++++- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index d035ca4ee54..e8acd29bbc9 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -126,20 +126,36 @@ inline size_t lengthOf(int) return 1; // encode as byte } +template inline size_t lengthOf(const char (&)[N]) +{ + return N - 1; +} + + +inline size_t lengthOf(const char *str) +{ + return strlen(str); +} + template inline size_t lengthOf(T) { return sizeof(T); } -static void encodeOneAt(char *ptr, int v) +static void encodeOneAt(char *ptr, int v, size_t) { // encode as byte *ptr = char(v); } +static void encodeOneAt(char *ptr, const char *v, size_t size) +{ + memcpy(ptr, v, size); +} + template static typename std::enable_if::value>::type -encodeOneAt(char *ptr, T v) +encodeOneAt(char *ptr, T v, size_t) { qToBigEndian(v, ptr); } @@ -147,7 +163,7 @@ encodeOneAt(char *ptr, T v) template static typename std::enable_if::value || std::is_same::value>::type -encodeOneAt(char *ptr, T v) +encodeOneAt(char *ptr, T v, size_t) { typename QIntegerForSizeof::Unsigned u; memcpy(&u, &v, sizeof(u)); @@ -162,7 +178,7 @@ static char *encodeAt(char *ptr) template static char *encodeAt(char *ptr, Arg0 a0, Args... a) { - encodeOneAt(ptr, a0); + encodeOneAt(ptr, a0, lengthOf(a0)); return encodeAt(ptr + lengthOf(a0), a...); } @@ -1778,6 +1794,15 @@ void tst_QCborValue::fromCbor_data() QTest::newRow("DateTime:NoMilli") << QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, Qt::UTC)) << raw("\xc0\x74" "2018-01-10T06:24:37Z"); + // date-only is only permitted local time + QTest::newRow("DateTime:NoTime:Local") << QCborValue(QDateTime(QDate(2020, 4, 15), QTime(0, 0), Qt::LocalTime)) + << raw("\xc0\x6a" "2020-04-15"); + QTest::newRow("DateTime:24:00:00") << QCborValue(QDateTime(QDate(2020, 4, 16), QTime(0, 0), Qt::UTC)) + << raw("\xc0\x74" "2020-04-15T24:00:00Z"); + QTest::newRow("DateTime:+00:00") << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, Qt::UTC)) + << raw("\xc0\x78\x1d" "2018-01-10T06:24:37.125+00:00"); + QTest::newRow("DateTime:+01:00") << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, Qt::OffsetFromUTC, 60*60)) + << raw("\xc0\x78\x1d" "2018-01-10T07:24:37.125+01:00"); QTest::newRow("UnixTime_t:Integer") << QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, Qt::UTC)) << raw("\xc1\x1a\x5a\x55\xb1\xa5"); QTest::newRow("UnixTime_t:Double") << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, Qt::UTC)) @@ -1985,6 +2010,49 @@ void tst_QCborValue::extendedTypeValidation_data() << encode(0xc1, 0x1b, quint64(dt.toSecsSinceEpoch())) << QCborValue(QCborKnownTags::UnixTime_t, dt.toSecsSinceEpoch()); } + + // Invalid ISO date/time strings + { + auto add = [](const char *tag, const char *str) { + QByteArray raw; + if (strlen(str) < 0x18) + raw = encode(0xc0, 0x60 + int(strlen(str)), str); + else + raw = encode(0xc0, 0x78, quint8(strlen(str)), str); + QTest::addRow("DateTime:%s", tag) + << raw << QCborValue(QCborKnownTags::DateTimeString, QString(str)); + }; + // tst_QDateTime::fromStringDateFormat has more tests + add("junk", "jjj"); + add("zoned-date-only", "2020-04-15Z"); + add("month-13", "2020-13-01T00:00:00Z"); + add("negative-month", "2020--1-01T00:00:00Z"); + add("jan-32", "2020-01-32T00:00:00Z"); + add("apr-31", "2020-04-31T00:00:00Z"); + add("feb-30", "2020-02-30T00:00:00Z"); + add("feb-29-nonleap", "2021-02-29T00:00:00Z"); + add("negative-day", "2020-01--1T00:00:00Z"); + add("bad-separator", "2020-04-15j13:30:59Z"); + add("hour-25", "2020-04-15T25:00:00Z"); + add("negative-hour", "2020-04-15T-1:00:00Z"); + add("minute-60", "2020-04-15T23:60:00Z"); + add("negative-minute", "2020-04-15T23:-1:00Z"); + add("second-60", "2020-04-15T23:59:60Z"); // not a leap second + add("negative-second", "2020-04-15T23:59:-1Z"); + add("negative-milli", "2020-04-15T23.59:59.-1Z"); + + // walking null + char dt[] = "2020-04-15T17:33:32.125Z"; + quint8 len = strlen(dt); + for (int i = 0; i < int(len); ++i) { + char c = '\0'; + qSwap(c, dt[i]); + QTest::addRow("DateTime:Null-at-%d", i) + << encode(0xc0, 0x78, len) + QByteArray(dt, len) + << QCborValue(QCborKnownTags::DateTimeString, QLatin1String(dt, len)); + qSwap(c, dt[i]); + } + } } void tst_QCborValue::extendedTypeValidation() From 821e71fded090d815b5cd396057ac9823874fe1f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Apr 2020 15:16:06 -0300 Subject: [PATCH 39/44] QCborValue: check parsing of invalid URL QUrl will reject invalid URLs for us, so we don't get normalization. The original junk should be retrievable, of course. Change-Id: Ibdc95e9af7bd456a94ecfffd160610f5b2c8e1a2 Reviewed-by: Ulf Hermann Reviewed-by: Edward Welbourne --- src/corelib/serialization/qcborvalue.cpp | 8 +++++--- .../corelib/serialization/qcborvalue/tst_qcborvalue.cpp | 8 ++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index 30bfa367edb..3bca15d5625 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -827,9 +827,11 @@ static QCborValue::Type convertToExtendedType(QCborContainerPrivate *d) // normalize to a short (decoded) form, so as to save space QUrl url(e.flags & Element::StringIsUtf16 ? b->asQStringRaw() : - b->toUtf8String()); - QByteArray encoded = url.toString(QUrl::DecodeReserved).toUtf8(); - replaceByteData(encoded, encoded.size(), {}); + b->toUtf8String(), QUrl::StrictMode); + if (url.isValid()) { + QByteArray encoded = url.toString(QUrl::DecodeReserved).toUtf8(); + replaceByteData(encoded, encoded.size(), {}); + } } return QCborValue::Url; } diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index e8acd29bbc9..9c1341e252d 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -2053,6 +2053,14 @@ void tst_QCborValue::extendedTypeValidation_data() qSwap(c, dt[i]); } } + + // Improperly-encoded URLs + { + const char badurl[] = "%zz"; + QTest::newRow("Url:Invalid") + << encode(0xd8, int(QCborKnownTags::Url), 0x60 + int(strlen(badurl)), badurl) + << QCborValue(QCborKnownTags::Url, QLatin1String(badurl)); + } } void tst_QCborValue::extendedTypeValidation() From c78a960198d59fb9a9ddd83ad7098b1db396edfd Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 15 Apr 2020 13:10:31 +0200 Subject: [PATCH 40/44] QCOMPARE: treat values as equal if qFuzzyIsNull(each) We hope this shall avoid some flaky failures noticed in quick tests, e.g. tst_QQuickMenu::Material::subMenuPosition(cascading,flip) was recently seen failing with 3.88e-11 != 0. This required some revision to test data in the testlib selftest for floats; the resulting expected output differs in details but not in which tests pass or fail. QEMU, naturally, made life difficult, requiring special-case code in the test-driver. [ChangeLog][QtTestLib][QCOMPARE] QCOMPARE() now treats its values as equal when qFuzzyIsNull() is true for both of them. Change-Id: Icc6ad5164b609937eddbe39cc69120f0abf0f3b4 Reviewed-by: Qt CI Bot Reviewed-by: Mitch Curtis --- src/testlib/qtestcase.cpp | 17 +- src/testlib/qtestcase.qdoc | 21 +- .../testlib/selftests/expected_float.junitxml | 26 +- .../testlib/selftests/expected_float.lightxml | 26 +- .../auto/testlib/selftests/expected_float.tap | 310 +++++++++--------- .../testlib/selftests/expected_float.teamcity | 16 +- .../auto/testlib/selftests/expected_float.txt | 26 +- .../auto/testlib/selftests/expected_float.xml | 26 +- tests/auto/testlib/selftests/float/float.pro | 5 +- .../testlib/selftests/float/tst_float.cpp | 51 +-- .../auto/testlib/selftests/tst_selftests.cpp | 10 +- 11 files changed, 278 insertions(+), 256 deletions(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index f45999c7fab..74507c11e14 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** @@ -2525,16 +2525,21 @@ bool QTest::compare_helper(bool success, const char *failureMsg, } template -static bool floatingCompare(const T &t1, const T &t2) +static bool floatingCompare(const T &actual, const T &expected) { - switch (qFpClassify(t1)) + switch (qFpClassify(expected)) { case FP_INFINITE: - return (t1 < 0) == (t2 < 0) && qFpClassify(t2) == FP_INFINITE; + return (expected < 0) == (actual < 0) && qFpClassify(actual) == FP_INFINITE; case FP_NAN: - return qFpClassify(t2) == FP_NAN; + return qFpClassify(actual) == FP_NAN; default: - return qFuzzyCompare(t1, t2); + if (!qFuzzyIsNull(expected)) + return qFuzzyCompare(actual, expected); + Q_FALLTHROUGH(); + case FP_SUBNORMAL: // subnormal is always fuzzily null + case FP_ZERO: + return qFuzzyIsNull(actual); } } diff --git a/src/testlib/qtestcase.qdoc b/src/testlib/qtestcase.qdoc index e4e1825bb5a..72f8cdaf8c0 100644 --- a/src/testlib/qtestcase.qdoc +++ b/src/testlib/qtestcase.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -109,19 +109,18 @@ continues. If not, a failure is recorded in the test log and the test function returns without attempting any later checks. - Always respect QCOMPARE() parameter semantics. The first parameter passed to it - should always be the actual value produced by the code-under-test, while the - second parameter should always be the expected value. When the values don't - match, QCOMPARE() prints them with the labels \e Actual and \e Expected. - If the parameter order is swapped, debugging a failing test can be confusing. + Always respect QCOMPARE() parameter semantics. The first parameter passed to + it should always be the actual value produced by the code-under-test, while + the second parameter should always be the expected value. When the values + don't match, QCOMPARE() prints them with the labels \e Actual and \e + Expected. If the parameter order is swapped, debugging a failing test can be + confusing and tests expecting zero may fail due to rounding errors. When comparing floating-point types (\c float, \c double, and \c qfloat16), - \l qFuzzyCompare() is used for finite values. Infinities match if they have + \l qFuzzyCompare() is used for finite values. If qFuzzyIsNull() is true for + both values, they are also considered equal. Infinities match if they have the same sign, and any NaN as actual value matches with any NaN as expected - value (even though NaN != NaN, even when they're identical). This means that - expecting 0 can fail when the actual value may be affected by rounding errors. - One solution to this is to offset both actual and expected values by adding - some suitable constant (such as 1). + value (even though NaN != NaN, even when they're identical). QCOMPARE() tries to output the contents of the values if the comparison fails, so it is visible from the test log why the comparison failed. diff --git a/tests/auto/testlib/selftests/expected_float.junitxml b/tests/auto/testlib/selftests/expected_float.junitxml index 602f9252a4b..51a711efb77 100644 --- a/tests/auto/testlib/selftests/expected_float.junitxml +++ b/tests/auto/testlib/selftests/expected_float.junitxml @@ -17,8 +17,8 @@ Actual (operandLeft) : 999999999999 Expected (operandRight): 999999999998" result="fail"/> + Actual (operandLeft) : 1e-12 + Expected (operandRight): 9.99999999999e-13" result="fail"/> @@ -106,14 +106,14 @@ Actual (operandLeft) : 1 Expected (operandRight): 3" result="fail"/> + Actual (operandLeft) : 1e-05 + Expected (operandRight): 3e-05" result="fail"/> + Actual (operandLeft) : 1.00001e-05 + Expected (operandRight): 9.9999e-06" result="fail"/> @@ -201,14 +201,14 @@ Actual (operandLeft) : 1 Expected (operandRight): 3" result="fail"/> + Actual (operandLeft) : 0.000999 + Expected (operandRight): 0.003" result="fail"/> + Actual (operandLeft) : 0.00101 + Expected (operandRight): 0.00099" result="fail"/> @@ -295,9 +295,9 @@ - + diff --git a/tests/auto/testlib/selftests/expected_float.lightxml b/tests/auto/testlib/selftests/expected_float.lightxml index 5f5114bb2e7..cf82929fd02 100644 --- a/tests/auto/testlib/selftests/expected_float.lightxml +++ b/tests/auto/testlib/selftests/expected_float.lightxml @@ -38,8 +38,8 @@ + Actual (operandLeft) : 1e-12 + Expected (operandRight): 9.99999999999e-13]]> @@ -230,8 +230,8 @@ + Actual (operandLeft) : 1e-05 + Expected (operandRight): 3e-05]]> @@ -248,8 +248,8 @@ + Actual (operandLeft) : 1.00001e-05 + Expected (operandRight): 9.9999e-06]]> @@ -440,8 +440,8 @@ + Actual (operandLeft) : 0.000999 + Expected (operandRight): 0.003]]> @@ -458,8 +458,8 @@ + Actual (operandLeft) : 0.00101 + Expected (operandRight): 0.00099]]> @@ -645,10 +645,10 @@ Expected (t3): 3]]> - + + Actual (t1): 1e-05 + Expected (t3): 3e-05]]> diff --git a/tests/auto/testlib/selftests/expected_float.tap b/tests/auto/testlib/selftests/expected_float.tap index 9da51b93b31..f5249b8b4e1 100644 --- a/tests/auto/testlib/selftests/expected_float.tap +++ b/tests/auto/testlib/selftests/expected_float.tap @@ -44,10 +44,10 @@ not ok 8 - doubleComparisons(should FAIL 4) --- type: QCOMPARE message: Compared doubles are not the same (fuzzy compare) - wanted: 9.99999999997e-311 (operandRight) - found: 9.99999999999e-311 (operandLeft) - expected: 9.99999999997e-311 (operandRight) - actual: 9.99999999999e-311 (operandLeft) + wanted: 9.99999999999e-13 (operandRight) + found: 1e-12 (operandLeft) + expected: 9.99999999999e-13 (operandRight) + actual: 1e-12 (operandLeft) at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:103) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp line: 103 @@ -388,22 +388,22 @@ not ok 40 - floatComparisons(should FAIL 1) found: 1 (operandLeft) expected: 3 (operandRight) actual: 1 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... ok 41 - floatComparisons(should PASS 1) not ok 42 - floatComparisons(should FAIL 2) --- type: QCOMPARE message: Compared floats are not the same (fuzzy compare) - wanted: 3e-07 (operandRight) - found: 1e-07 (operandLeft) - expected: 3e-07 (operandRight) - actual: 1e-07 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + wanted: 3e-05 (operandRight) + found: 1e-05 (operandLeft) + expected: 3e-05 (operandRight) + actual: 1e-05 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... ok 43 - floatComparisons(should PASS 2) not ok 44 - floatComparisons(should FAIL 3) @@ -414,22 +414,22 @@ not ok 44 - floatComparisons(should FAIL 3) found: 99999 (operandLeft) expected: 99998 (operandRight) actual: 99999 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... ok 45 - floatComparisons(should PASS 3) not ok 46 - floatComparisons(should FAIL 4) --- type: QCOMPARE message: Compared floats are not the same (fuzzy compare) - wanted: 9.99971e-40 (operandRight) - found: 9.9999e-40 (operandLeft) - expected: 9.99971e-40 (operandRight) - actual: 9.9999e-40 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + wanted: 9.9999e-06 (operandRight) + found: 1.00001e-05 (operandLeft) + expected: 9.9999e-06 (operandRight) + actual: 1.00001e-05 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... ok 47 - floatComparisons(should PASS 4) not ok 48 - floatComparisons(should FAIL 5) @@ -440,9 +440,9 @@ not ok 48 - floatComparisons(should FAIL 5) found: 9.9999e+37 (operandLeft) expected: 9.9997e+37 (operandRight) actual: 9.9999e+37 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... ok 49 - floatComparisons(should PASS: NaN == NaN) not ok 50 - floatComparisons(should FAIL: NaN != 0) @@ -453,9 +453,9 @@ not ok 50 - floatComparisons(should FAIL: NaN != 0) found: nan (operandLeft) expected: 0 (operandRight) actual: nan (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 51 - floatComparisons(should FAIL: 0 != NaN) --- @@ -465,9 +465,9 @@ not ok 51 - floatComparisons(should FAIL: 0 != NaN) found: 0 (operandLeft) expected: nan (operandRight) actual: 0 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 52 - floatComparisons(should FAIL: NaN != 1) --- @@ -477,9 +477,9 @@ not ok 52 - floatComparisons(should FAIL: NaN != 1) found: nan (operandLeft) expected: 1 (operandRight) actual: nan (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 53 - floatComparisons(should FAIL: 1 != NaN) --- @@ -489,9 +489,9 @@ not ok 53 - floatComparisons(should FAIL: 1 != NaN) found: 1 (operandLeft) expected: nan (operandRight) actual: 1 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... ok 54 - floatComparisons(should PASS: inf == inf) ok 55 - floatComparisons(should PASS: -inf == -inf) @@ -503,9 +503,9 @@ not ok 56 - floatComparisons(should FAIL: inf != -inf) found: inf (operandLeft) expected: -inf (operandRight) actual: inf (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 57 - floatComparisons(should FAIL: -inf != inf) --- @@ -515,9 +515,9 @@ not ok 57 - floatComparisons(should FAIL: -inf != inf) found: -inf (operandLeft) expected: inf (operandRight) actual: -inf (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 58 - floatComparisons(should FAIL: inf != nan) --- @@ -527,9 +527,9 @@ not ok 58 - floatComparisons(should FAIL: inf != nan) found: inf (operandLeft) expected: nan (operandRight) actual: inf (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 59 - floatComparisons(should FAIL: nan != inf) --- @@ -539,9 +539,9 @@ not ok 59 - floatComparisons(should FAIL: nan != inf) found: nan (operandLeft) expected: inf (operandRight) actual: nan (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 60 - floatComparisons(should FAIL: -inf != nan) --- @@ -551,9 +551,9 @@ not ok 60 - floatComparisons(should FAIL: -inf != nan) found: -inf (operandLeft) expected: nan (operandRight) actual: -inf (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 61 - floatComparisons(should FAIL: nan != -inf) --- @@ -563,9 +563,9 @@ not ok 61 - floatComparisons(should FAIL: nan != -inf) found: nan (operandLeft) expected: -inf (operandRight) actual: nan (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 62 - floatComparisons(should FAIL: inf != 0) --- @@ -575,9 +575,9 @@ not ok 62 - floatComparisons(should FAIL: inf != 0) found: inf (operandLeft) expected: 0 (operandRight) actual: inf (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 63 - floatComparisons(should FAIL: 0 != inf) --- @@ -587,9 +587,9 @@ not ok 63 - floatComparisons(should FAIL: 0 != inf) found: 0 (operandLeft) expected: inf (operandRight) actual: 0 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 64 - floatComparisons(should FAIL: -inf != 0) --- @@ -599,9 +599,9 @@ not ok 64 - floatComparisons(should FAIL: -inf != 0) found: -inf (operandLeft) expected: 0 (operandRight) actual: -inf (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 65 - floatComparisons(should FAIL: 0 != -inf) --- @@ -611,9 +611,9 @@ not ok 65 - floatComparisons(should FAIL: 0 != -inf) found: 0 (operandLeft) expected: -inf (operandRight) actual: 0 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 66 - floatComparisons(should FAIL: inf != 1) --- @@ -623,9 +623,9 @@ not ok 66 - floatComparisons(should FAIL: inf != 1) found: inf (operandLeft) expected: 1 (operandRight) actual: inf (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 67 - floatComparisons(should FAIL: 1 != inf) --- @@ -635,9 +635,9 @@ not ok 67 - floatComparisons(should FAIL: 1 != inf) found: 1 (operandLeft) expected: inf (operandRight) actual: 1 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 68 - floatComparisons(should FAIL: -inf != 1) --- @@ -647,9 +647,9 @@ not ok 68 - floatComparisons(should FAIL: -inf != 1) found: -inf (operandLeft) expected: 1 (operandRight) actual: -inf (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 69 - floatComparisons(should FAIL: 1 != -inf) --- @@ -659,9 +659,9 @@ not ok 69 - floatComparisons(should FAIL: 1 != -inf) found: 1 (operandLeft) expected: -inf (operandRight) actual: 1 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 70 - floatComparisons(should FAIL: inf != max) --- @@ -671,9 +671,9 @@ not ok 70 - floatComparisons(should FAIL: inf != max) found: inf (operandLeft) expected: 3.40282e+38 (operandRight) actual: inf (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 71 - floatComparisons(should FAIL: inf != -max) --- @@ -683,9 +683,9 @@ not ok 71 - floatComparisons(should FAIL: inf != -max) found: inf (operandLeft) expected: -3.40282e+38 (operandRight) actual: inf (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 72 - floatComparisons(should FAIL: max != inf) --- @@ -695,9 +695,9 @@ not ok 72 - floatComparisons(should FAIL: max != inf) found: 3.40282e+38 (operandLeft) expected: inf (operandRight) actual: 3.40282e+38 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 73 - floatComparisons(should FAIL: -max != inf) --- @@ -707,9 +707,9 @@ not ok 73 - floatComparisons(should FAIL: -max != inf) found: -3.40282e+38 (operandLeft) expected: inf (operandRight) actual: -3.40282e+38 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 74 - floatComparisons(should FAIL: -inf != max) --- @@ -719,9 +719,9 @@ not ok 74 - floatComparisons(should FAIL: -inf != max) found: -inf (operandLeft) expected: 3.40282e+38 (operandRight) actual: -inf (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 75 - floatComparisons(should FAIL: -inf != -max) --- @@ -731,9 +731,9 @@ not ok 75 - floatComparisons(should FAIL: -inf != -max) found: -inf (operandLeft) expected: -3.40282e+38 (operandRight) actual: -inf (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 76 - floatComparisons(should FAIL: max != -inf) --- @@ -743,9 +743,9 @@ not ok 76 - floatComparisons(should FAIL: max != -inf) found: 3.40282e+38 (operandLeft) expected: -inf (operandRight) actual: 3.40282e+38 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 77 - floatComparisons(should FAIL: -max != -inf) --- @@ -755,9 +755,9 @@ not ok 77 - floatComparisons(should FAIL: -max != -inf) found: -3.40282e+38 (operandLeft) expected: -inf (operandRight) actual: -3.40282e+38 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:137) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:139) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 137 + line: 139 ... not ok 78 - float16Comparisons(should FAIL 1) --- @@ -767,22 +767,22 @@ not ok 78 - float16Comparisons(should FAIL 1) found: 1 (operandLeft) expected: 3 (operandRight) actual: 1 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... ok 79 - float16Comparisons(should PASS 1) not ok 80 - float16Comparisons(should FAIL 2) --- type: QCOMPARE message: Compared qfloat16s are not the same (fuzzy compare) - wanted: 0.0003 (operandRight) - found: 0.0001 (operandLeft) - expected: 0.0003 (operandRight) - actual: 0.0001 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + wanted: 0.003 (operandRight) + found: 0.000999 (operandLeft) + expected: 0.003 (operandRight) + actual: 0.000999 (operandLeft) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... ok 81 - float16Comparisons(should PASS 2) not ok 82 - float16Comparisons(should FAIL 3) @@ -793,22 +793,22 @@ not ok 82 - float16Comparisons(should FAIL 3) found: 98 (operandLeft) expected: 99 (operandRight) actual: 98 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... ok 83 - float16Comparisons(should PASS 3) not ok 84 - float16Comparisons(should FAIL 4) --- type: QCOMPARE message: Compared qfloat16s are not the same (fuzzy compare) - wanted: 5.87e-05 (operandRight) - found: 5.93e-05 (operandLeft) - expected: 5.87e-05 (operandRight) - actual: 5.93e-05 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + wanted: 0.00099 (operandRight) + found: 0.00101 (operandLeft) + expected: 0.00099 (operandRight) + actual: 0.00101 (operandLeft) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... ok 85 - float16Comparisons(should PASS 4) not ok 86 - float16Comparisons(should FAIL 5) @@ -819,9 +819,9 @@ not ok 86 - float16Comparisons(should FAIL 5) found: 5.94e+04 (operandLeft) expected: 5.88e+04 (operandRight) actual: 5.94e+04 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... ok 87 - float16Comparisons(should PASS: NaN == NaN) not ok 88 - float16Comparisons(should FAIL: NaN != 0) @@ -832,9 +832,9 @@ not ok 88 - float16Comparisons(should FAIL: NaN != 0) found: nan (operandLeft) expected: 0 (operandRight) actual: nan (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 89 - float16Comparisons(should FAIL: 0 != NaN) --- @@ -844,9 +844,9 @@ not ok 89 - float16Comparisons(should FAIL: 0 != NaN) found: 0 (operandLeft) expected: nan (operandRight) actual: 0 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 90 - float16Comparisons(should FAIL: NaN != 1) --- @@ -856,9 +856,9 @@ not ok 90 - float16Comparisons(should FAIL: NaN != 1) found: nan (operandLeft) expected: 1 (operandRight) actual: nan (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 91 - float16Comparisons(should FAIL: 1 != NaN) --- @@ -868,9 +868,9 @@ not ok 91 - float16Comparisons(should FAIL: 1 != NaN) found: 1 (operandLeft) expected: nan (operandRight) actual: 1 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... ok 92 - float16Comparisons(should PASS: inf == inf) ok 93 - float16Comparisons(should PASS: -inf == -inf) @@ -882,9 +882,9 @@ not ok 94 - float16Comparisons(should FAIL: inf != -inf) found: inf (operandLeft) expected: -inf (operandRight) actual: inf (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 95 - float16Comparisons(should FAIL: -inf != inf) --- @@ -894,9 +894,9 @@ not ok 95 - float16Comparisons(should FAIL: -inf != inf) found: -inf (operandLeft) expected: inf (operandRight) actual: -inf (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 96 - float16Comparisons(should FAIL: inf != nan) --- @@ -906,9 +906,9 @@ not ok 96 - float16Comparisons(should FAIL: inf != nan) found: inf (operandLeft) expected: nan (operandRight) actual: inf (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 97 - float16Comparisons(should FAIL: nan != inf) --- @@ -918,9 +918,9 @@ not ok 97 - float16Comparisons(should FAIL: nan != inf) found: nan (operandLeft) expected: inf (operandRight) actual: nan (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 98 - float16Comparisons(should FAIL: -inf != nan) --- @@ -930,9 +930,9 @@ not ok 98 - float16Comparisons(should FAIL: -inf != nan) found: -inf (operandLeft) expected: nan (operandRight) actual: -inf (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 99 - float16Comparisons(should FAIL: nan != -inf) --- @@ -942,9 +942,9 @@ not ok 99 - float16Comparisons(should FAIL: nan != -inf) found: nan (operandLeft) expected: -inf (operandRight) actual: nan (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 100 - float16Comparisons(should FAIL: inf != 0) --- @@ -954,9 +954,9 @@ not ok 100 - float16Comparisons(should FAIL: inf != 0) found: inf (operandLeft) expected: 0 (operandRight) actual: inf (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 101 - float16Comparisons(should FAIL: 0 != inf) --- @@ -966,9 +966,9 @@ not ok 101 - float16Comparisons(should FAIL: 0 != inf) found: 0 (operandLeft) expected: inf (operandRight) actual: 0 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 102 - float16Comparisons(should FAIL: -inf != 0) --- @@ -978,9 +978,9 @@ not ok 102 - float16Comparisons(should FAIL: -inf != 0) found: -inf (operandLeft) expected: 0 (operandRight) actual: -inf (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 103 - float16Comparisons(should FAIL: 0 != -inf) --- @@ -990,9 +990,9 @@ not ok 103 - float16Comparisons(should FAIL: 0 != -inf) found: 0 (operandLeft) expected: -inf (operandRight) actual: 0 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 104 - float16Comparisons(should FAIL: inf != 1) --- @@ -1002,9 +1002,9 @@ not ok 104 - float16Comparisons(should FAIL: inf != 1) found: inf (operandLeft) expected: 1 (operandRight) actual: inf (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 105 - float16Comparisons(should FAIL: 1 != inf) --- @@ -1014,9 +1014,9 @@ not ok 105 - float16Comparisons(should FAIL: 1 != inf) found: 1 (operandLeft) expected: inf (operandRight) actual: 1 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 106 - float16Comparisons(should FAIL: -inf != 1) --- @@ -1026,9 +1026,9 @@ not ok 106 - float16Comparisons(should FAIL: -inf != 1) found: -inf (operandLeft) expected: 1 (operandRight) actual: -inf (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 107 - float16Comparisons(should FAIL: 1 != -inf) --- @@ -1038,9 +1038,9 @@ not ok 107 - float16Comparisons(should FAIL: 1 != -inf) found: 1 (operandLeft) expected: -inf (operandRight) actual: 1 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 108 - float16Comparisons(should FAIL: inf != max) --- @@ -1050,9 +1050,9 @@ not ok 108 - float16Comparisons(should FAIL: inf != max) found: inf (operandLeft) expected: 6.55e+04 (operandRight) actual: inf (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 109 - float16Comparisons(should FAIL: inf != -max) --- @@ -1062,9 +1062,9 @@ not ok 109 - float16Comparisons(should FAIL: inf != -max) found: inf (operandLeft) expected: -6.55e+04 (operandRight) actual: inf (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 110 - float16Comparisons(should FAIL: max != inf) --- @@ -1074,9 +1074,9 @@ not ok 110 - float16Comparisons(should FAIL: max != inf) found: 6.55e+04 (operandLeft) expected: inf (operandRight) actual: 6.55e+04 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 111 - float16Comparisons(should FAIL: -max != inf) --- @@ -1086,9 +1086,9 @@ not ok 111 - float16Comparisons(should FAIL: -max != inf) found: -6.55e+04 (operandLeft) expected: inf (operandRight) actual: -6.55e+04 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 112 - float16Comparisons(should FAIL: -inf != max) --- @@ -1098,9 +1098,9 @@ not ok 112 - float16Comparisons(should FAIL: -inf != max) found: -inf (operandLeft) expected: 6.55e+04 (operandRight) actual: -inf (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 113 - float16Comparisons(should FAIL: -inf != -max) --- @@ -1110,9 +1110,9 @@ not ok 113 - float16Comparisons(should FAIL: -inf != -max) found: -inf (operandLeft) expected: -6.55e+04 (operandRight) actual: -inf (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 114 - float16Comparisons(should FAIL: max != -inf) --- @@ -1122,9 +1122,9 @@ not ok 114 - float16Comparisons(should FAIL: max != -inf) found: 6.55e+04 (operandLeft) expected: -inf (operandRight) actual: 6.55e+04 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 115 - float16Comparisons(should FAIL: -max != -inf) --- @@ -1134,9 +1134,9 @@ not ok 115 - float16Comparisons(should FAIL: -max != -inf) found: -6.55e+04 (operandLeft) expected: -inf (operandRight) actual: -6.55e+04 (operandLeft) - at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:171) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:174) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 171 + line: 174 ... not ok 116 - compareFloatTests(1e0) --- @@ -1146,21 +1146,21 @@ not ok 116 - compareFloatTests(1e0) found: 1 (t1) expected: 3 (t3) actual: 1 (t1) - at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:210) + at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:215) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 210 + line: 215 ... -not ok 117 - compareFloatTests(1e-7) +not ok 117 - compareFloatTests(1e-5) --- type: QCOMPARE message: Compared floats are not the same (fuzzy compare) - wanted: 3e-07 (t3) - found: 1e-07 (t1) - expected: 3e-07 (t3) - actual: 1e-07 (t1) - at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:210) + wanted: 3e-05 (t3) + found: 1e-05 (t1) + expected: 3e-05 (t3) + actual: 1e-05 (t1) + at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:215) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 210 + line: 215 ... not ok 118 - compareFloatTests(1e+7) --- @@ -1170,9 +1170,9 @@ not ok 118 - compareFloatTests(1e+7) found: 1e+07 (t1) expected: 3e+07 (t3) actual: 1e+07 (t1) - at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:210) + at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:215) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 210 + line: 215 ... ok 119 - cleanupTestCase() 1..119 diff --git a/tests/auto/testlib/selftests/expected_float.teamcity b/tests/auto/testlib/selftests/expected_float.teamcity index af81296c42e..f8d65a71c7b 100644 --- a/tests/auto/testlib/selftests/expected_float.teamcity +++ b/tests/auto/testlib/selftests/expected_float.teamcity @@ -17,7 +17,7 @@ ##teamcity[testStarted name='doubleComparisons(should PASS 3)' flowId='tst_float'] ##teamcity[testFinished name='doubleComparisons(should PASS 3)' flowId='tst_float'] ##teamcity[testStarted name='doubleComparisons(should FAIL 4)' flowId='tst_float'] -##teamcity[testFailed name='doubleComparisons(should FAIL 4)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 9.99999999999e-311|n Expected (operandRight): 9.99999999997e-311' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL 4)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 1e-12|n Expected (operandRight): 9.99999999999e-13' flowId='tst_float'] ##teamcity[testFinished name='doubleComparisons(should FAIL 4)' flowId='tst_float'] ##teamcity[testStarted name='doubleComparisons(should PASS 4)' flowId='tst_float'] ##teamcity[testFinished name='doubleComparisons(should PASS 4)' flowId='tst_float'] @@ -114,7 +114,7 @@ ##teamcity[testStarted name='floatComparisons(should PASS 1)' flowId='tst_float'] ##teamcity[testFinished name='floatComparisons(should PASS 1)' flowId='tst_float'] ##teamcity[testStarted name='floatComparisons(should FAIL 2)' flowId='tst_float'] -##teamcity[testFailed name='floatComparisons(should FAIL 2)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 1e-07|n Expected (operandRight): 3e-07' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL 2)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 1e-05|n Expected (operandRight): 3e-05' flowId='tst_float'] ##teamcity[testFinished name='floatComparisons(should FAIL 2)' flowId='tst_float'] ##teamcity[testStarted name='floatComparisons(should PASS 2)' flowId='tst_float'] ##teamcity[testFinished name='floatComparisons(should PASS 2)' flowId='tst_float'] @@ -124,7 +124,7 @@ ##teamcity[testStarted name='floatComparisons(should PASS 3)' flowId='tst_float'] ##teamcity[testFinished name='floatComparisons(should PASS 3)' flowId='tst_float'] ##teamcity[testStarted name='floatComparisons(should FAIL 4)' flowId='tst_float'] -##teamcity[testFailed name='floatComparisons(should FAIL 4)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 9.9999e-40|n Expected (operandRight): 9.99971e-40' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL 4)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 1.00001e-05|n Expected (operandRight): 9.9999e-06' flowId='tst_float'] ##teamcity[testFinished name='floatComparisons(should FAIL 4)' flowId='tst_float'] ##teamcity[testStarted name='floatComparisons(should PASS 4)' flowId='tst_float'] ##teamcity[testFinished name='floatComparisons(should PASS 4)' flowId='tst_float'] @@ -221,7 +221,7 @@ ##teamcity[testStarted name='float16Comparisons(should PASS 1)' flowId='tst_float'] ##teamcity[testFinished name='float16Comparisons(should PASS 1)' flowId='tst_float'] ##teamcity[testStarted name='float16Comparisons(should FAIL 2)' flowId='tst_float'] -##teamcity[testFailed name='float16Comparisons(should FAIL 2)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared qfloat16s are not the same (fuzzy compare)|n Actual (operandLeft) : 0.0001|n Expected (operandRight): 0.0003' flowId='tst_float'] +##teamcity[testFailed name='float16Comparisons(should FAIL 2)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared qfloat16s are not the same (fuzzy compare)|n Actual (operandLeft) : 0.000999|n Expected (operandRight): 0.003' flowId='tst_float'] ##teamcity[testFinished name='float16Comparisons(should FAIL 2)' flowId='tst_float'] ##teamcity[testStarted name='float16Comparisons(should PASS 2)' flowId='tst_float'] ##teamcity[testFinished name='float16Comparisons(should PASS 2)' flowId='tst_float'] @@ -231,7 +231,7 @@ ##teamcity[testStarted name='float16Comparisons(should PASS 3)' flowId='tst_float'] ##teamcity[testFinished name='float16Comparisons(should PASS 3)' flowId='tst_float'] ##teamcity[testStarted name='float16Comparisons(should FAIL 4)' flowId='tst_float'] -##teamcity[testFailed name='float16Comparisons(should FAIL 4)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared qfloat16s are not the same (fuzzy compare)|n Actual (operandLeft) : 5.93e-05|n Expected (operandRight): 5.87e-05' flowId='tst_float'] +##teamcity[testFailed name='float16Comparisons(should FAIL 4)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared qfloat16s are not the same (fuzzy compare)|n Actual (operandLeft) : 0.00101|n Expected (operandRight): 0.00099' flowId='tst_float'] ##teamcity[testFinished name='float16Comparisons(should FAIL 4)' flowId='tst_float'] ##teamcity[testStarted name='float16Comparisons(should PASS 4)' flowId='tst_float'] ##teamcity[testFinished name='float16Comparisons(should PASS 4)' flowId='tst_float'] @@ -325,9 +325,9 @@ ##teamcity[testStarted name='compareFloatTests(1e0)' flowId='tst_float'] ##teamcity[testFailed name='compareFloatTests(1e0)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (t1): 1|n Expected (t3): 3' flowId='tst_float'] ##teamcity[testFinished name='compareFloatTests(1e0)' flowId='tst_float'] -##teamcity[testStarted name='compareFloatTests(1e-7)' flowId='tst_float'] -##teamcity[testFailed name='compareFloatTests(1e-7)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (t1): 1e-07|n Expected (t3): 3e-07' flowId='tst_float'] -##teamcity[testFinished name='compareFloatTests(1e-7)' flowId='tst_float'] +##teamcity[testStarted name='compareFloatTests(1e-5)' flowId='tst_float'] +##teamcity[testFailed name='compareFloatTests(1e-5)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (t1): 1e-05|n Expected (t3): 3e-05' flowId='tst_float'] +##teamcity[testFinished name='compareFloatTests(1e-5)' flowId='tst_float'] ##teamcity[testStarted name='compareFloatTests(1e+7)' flowId='tst_float'] ##teamcity[testFailed name='compareFloatTests(1e+7)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (t1): 1e+07|n Expected (t3): 3e+07' flowId='tst_float'] ##teamcity[testFinished name='compareFloatTests(1e+7)' flowId='tst_float'] diff --git a/tests/auto/testlib/selftests/expected_float.txt b/tests/auto/testlib/selftests/expected_float.txt index d22a52a63d6..25c8c6b6de5 100644 --- a/tests/auto/testlib/selftests/expected_float.txt +++ b/tests/auto/testlib/selftests/expected_float.txt @@ -17,8 +17,8 @@ FAIL! : tst_float::doubleComparisons(should FAIL 3) Compared doubles are not th Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] PASS : tst_float::doubleComparisons(should PASS 3) FAIL! : tst_float::doubleComparisons(should FAIL 4) Compared doubles are not the same (fuzzy compare) - Actual (operandLeft) : 9.99999999999e-311 - Expected (operandRight): 9.99999999997e-311 + Actual (operandLeft) : 1e-12 + Expected (operandRight): 9.99999999999e-13 Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] PASS : tst_float::doubleComparisons(should PASS 4) FAIL! : tst_float::doubleComparisons(should FAIL 5) Compared doubles are not the same (fuzzy compare) @@ -138,8 +138,8 @@ FAIL! : tst_float::floatComparisons(should FAIL 1) Compared floats are not the Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] PASS : tst_float::floatComparisons(should PASS 1) FAIL! : tst_float::floatComparisons(should FAIL 2) Compared floats are not the same (fuzzy compare) - Actual (operandLeft) : 1e-07 - Expected (operandRight): 3e-07 + Actual (operandLeft) : 1e-05 + Expected (operandRight): 3e-05 Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] PASS : tst_float::floatComparisons(should PASS 2) FAIL! : tst_float::floatComparisons(should FAIL 3) Compared floats are not the same (fuzzy compare) @@ -148,8 +148,8 @@ FAIL! : tst_float::floatComparisons(should FAIL 3) Compared floats are not the Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] PASS : tst_float::floatComparisons(should PASS 3) FAIL! : tst_float::floatComparisons(should FAIL 4) Compared floats are not the same (fuzzy compare) - Actual (operandLeft) : 9.9999e-40 - Expected (operandRight): 9.99971e-40 + Actual (operandLeft) : 1.00001e-05 + Expected (operandRight): 9.9999e-06 Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] PASS : tst_float::floatComparisons(should PASS 4) FAIL! : tst_float::floatComparisons(should FAIL 5) Compared floats are not the same (fuzzy compare) @@ -269,8 +269,8 @@ FAIL! : tst_float::float16Comparisons(should FAIL 1) Compared qfloat16s are not Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] PASS : tst_float::float16Comparisons(should PASS 1) FAIL! : tst_float::float16Comparisons(should FAIL 2) Compared qfloat16s are not the same (fuzzy compare) - Actual (operandLeft) : 0.0001 - Expected (operandRight): 0.0003 + Actual (operandLeft) : 0.000999 + Expected (operandRight): 0.003 Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] PASS : tst_float::float16Comparisons(should PASS 2) FAIL! : tst_float::float16Comparisons(should FAIL 3) Compared qfloat16s are not the same (fuzzy compare) @@ -279,8 +279,8 @@ FAIL! : tst_float::float16Comparisons(should FAIL 3) Compared qfloat16s are not Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] PASS : tst_float::float16Comparisons(should PASS 3) FAIL! : tst_float::float16Comparisons(should FAIL 4) Compared qfloat16s are not the same (fuzzy compare) - Actual (operandLeft) : 5.93e-05 - Expected (operandRight): 5.87e-05 + Actual (operandLeft) : 0.00101 + Expected (operandRight): 0.00099 Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] PASS : tst_float::float16Comparisons(should PASS 4) FAIL! : tst_float::float16Comparisons(should FAIL 5) Compared qfloat16s are not the same (fuzzy compare) @@ -398,9 +398,9 @@ FAIL! : tst_float::compareFloatTests(1e0) Compared floats are not the same (fuz Actual (t1): 1 Expected (t3): 3 Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] -FAIL! : tst_float::compareFloatTests(1e-7) Compared floats are not the same (fuzzy compare) - Actual (t1): 1e-07 - Expected (t3): 3e-07 +FAIL! : tst_float::compareFloatTests(1e-5) Compared floats are not the same (fuzzy compare) + Actual (t1): 1e-05 + Expected (t3): 3e-05 Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] FAIL! : tst_float::compareFloatTests(1e+7) Compared floats are not the same (fuzzy compare) Actual (t1): 1e+07 diff --git a/tests/auto/testlib/selftests/expected_float.xml b/tests/auto/testlib/selftests/expected_float.xml index 247bce95776..8ddc72a9176 100644 --- a/tests/auto/testlib/selftests/expected_float.xml +++ b/tests/auto/testlib/selftests/expected_float.xml @@ -40,8 +40,8 @@ + Actual (operandLeft) : 1e-12 + Expected (operandRight): 9.99999999999e-13]]> @@ -232,8 +232,8 @@ + Actual (operandLeft) : 1e-05 + Expected (operandRight): 3e-05]]> @@ -250,8 +250,8 @@ + Actual (operandLeft) : 1.00001e-05 + Expected (operandRight): 9.9999e-06]]> @@ -442,8 +442,8 @@ + Actual (operandLeft) : 0.000999 + Expected (operandRight): 0.003]]> @@ -460,8 +460,8 @@ + Actual (operandLeft) : 0.00101 + Expected (operandRight): 0.00099]]> @@ -647,10 +647,10 @@ Expected (t3): 3]]> - + + Actual (t1): 1e-05 + Expected (t3): 3e-05]]> diff --git a/tests/auto/testlib/selftests/float/float.pro b/tests/auto/testlib/selftests/float/float.pro index 479eb152c51..8f169921c3c 100644 --- a/tests/auto/testlib/selftests/float/float.pro +++ b/tests/auto/testlib/selftests/float/float.pro @@ -1,9 +1,10 @@ -SOURCES += tst_float.cpp QT = core testlib - mac:CONFIG -= app_bundle CONFIG -= debug_and_release_target +INCLUDEPATH += ../../../../shared/ +HEADERS = ../../../../shared/emulationdetector.h +SOURCES += tst_float.cpp TARGET = float include($$QT_SOURCE_TREE/src/testlib/selfcover.pri) diff --git a/tests/auto/testlib/selftests/float/tst_float.cpp b/tests/auto/testlib/selftests/float/tst_float.cpp index cefd8a57c41..823495f8637 100644 --- a/tests/auto/testlib/selftests/float/tst_float.cpp +++ b/tests/auto/testlib/selftests/float/tst_float.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -31,6 +31,8 @@ #include #include +#include "emulationdetector.h" + // Test proper handling of floating-point types class tst_float: public QObject { @@ -113,16 +115,18 @@ void tst_float::doubleComparisons_data() const QTest::newRow("should PASS 1") << zero << zero; QTest::newRow("should FAIL 2") << 1.e-7 << 3.e-7; - // QCOMPARE for doubles uses qFuzzyCompare(), which succeeds if the numbers - // differ by no more than 1e-12 times the smaller value. Thus - // QCOMPARE(1e12-2, 1e12-1) should fail, while QCOMPARE(1e12+1, 1e12+2) - // should pass. + // QCOMPARE() uses qFuzzyCompare(), which succeeds if doubles differ by no + // more than 1e-12 times the smaller value; but QCOMPARE() also considers + // values equal if qFuzzyIsNull() is true for both, so all doubles smaller + // than 1e-12 are equal. Thus QCOMPARE(1e12-2, 1e12-1) should fail, while + // QCOMPARE(1e12+1, 1e12+2) should pass, as should QCOMPARE(1e-12-2e-24, + // 1e-12-1e-24), despite the values differing by more than one part in 1e12. QTest::newRow("should PASS 2") << 1e12 + one << 1e12 + 2.; QTest::newRow("should FAIL 3") << 1e12 - one << 1e12 - 2.; + QTest::newRow("should PASS 3") << 1e-12 << -1e-12; // ... but rounding makes that a bit unrelaible when scaled close to the bounds. - QTest::newRow("should PASS 3") << 1e-310 + 1e-322 << 1e-310 + 2e-322; - QTest::newRow("should FAIL 4") << 1e-310 - 1e-322 << 1e-310 - 3e-322; + QTest::newRow("should FAIL 4") << 1e-12 + 1e-24 << 1e-12 - 1e-24; QTest::newRow("should PASS 4") << 1e307 + 1e295 << 1e307 + 2e295; QTest::newRow("should FAIL 5") << 1e307 - 1e295 << 1e307 - 3e295; @@ -145,18 +149,20 @@ void tst_float::floatComparisons_data() const QTest::newRow("should FAIL 1") << one << 3.f; QTest::newRow("should PASS 1") << zero << zero; - QTest::newRow("should FAIL 2") << 1.e-7f << 3.e-7f; + QTest::newRow("should FAIL 2") << 1.e-5f << 3.e-5f; - // QCOMPARE for floats uses qFuzzyCompare(), which succeeds if the numbers - // differ by no more than 1e-5 times the smaller value. Thus - // QCOMPARE(1e5-2, 1e5-1) should fail, while QCOMPARE(1e5+1, 1e5+2) - // should pass. + // QCOMPARE() uses qFuzzyCompare(), which succeeds if the floats differ by + // no more than 1e-5 times the smaller value; but QCOMPARE() also considers + // values equal if qFuzzyIsNull is true for both, so all floats smaller than + // 1e-5 are equal. Thus QCOMPARE(1e5-2, 1e5-1) should fail, while + // QCOMPARE(1e5+1, 1e5+2) should pass, as should QCOMPARE(1e-5-2e-10, + // 1e-5-1e-10), despite the values differing by more than one part in 1e5. QTest::newRow("should PASS 2") << 1e5f + one << 1e5f + 2.f; QTest::newRow("should FAIL 3") << 1e5f - one << 1e5f - 2.f; + QTest::newRow("should PASS 3") << 1e-5f << -1e-5f; // ... but rounding makes that a bit unrelaible when scaled close to the bounds. - QTest::newRow("should PASS 3") << 1e-39f + 1e-44f << 1e-39f + 2e-44f; - QTest::newRow("should FAIL 4") << 1e-39f - 1e-44f << 1e-39f - 3e-44f; + QTest::newRow("should FAIL 4") << 1e-5f + 1e-10f << 1e-5f - 1e-10f; QTest::newRow("should PASS 4") << 1e38f + 1e33f << 1e38f + 2e33f; QTest::newRow("should FAIL 5") << 1e38f - 1e33f << 1e38f - 3e33f; @@ -175,18 +181,21 @@ void tst_float::float16Comparisons_data() const { QTest::addColumn("operandLeft"); QTest::addColumn("operandRight"); - qfloat16 zero(0), one(1); + const qfloat16 zero(0), one(1); + const qfloat16 tiny(EmulationDetector::isRunningArmOnX86() ? 0.00099f : 0.001f); QTest::newRow("should FAIL 1") << one << qfloat16(3); QTest::newRow("should PASS 1") << zero << zero; - QTest::newRow("should FAIL 2") << qfloat16(1e-4f) << qfloat16(3e-4f); + QTest::newRow("should FAIL 2") << qfloat16(1e-3f) << qfloat16(3e-3f); - // QCOMPARE for qfloat16s uses qFuzzyCompare() + // QCOMPARE for uses qFuzzyCompare(), which ignores differences of one part + // in 102.5 and considers any two qFuzzyIsNull() values, i.e. values smaller + // than 1e-3, equal QTest::newRow("should PASS 2") << qfloat16(1001) << qfloat16(1002); QTest::newRow("should FAIL 3") << qfloat16(98) << qfloat16(99); + QTest::newRow("should PASS 3") << tiny << -tiny; // ... which gets a bit unreliable near to the type's bounds - QTest::newRow("should PASS 3") << qfloat16(6e-5f) + qfloat16(6e-7f) << qfloat16(6e-5f) + qfloat16(11e-7f); - QTest::newRow("should FAIL 4") << qfloat16(6e-5f) - qfloat16(7e-7f) << qfloat16(6e-5f) - qfloat16(13e-7f); + QTest::newRow("should FAIL 4") << qfloat16(1.01e-3f) << qfloat16(0.99e-3f); QTest::newRow("should PASS 4") << qfloat16(6e4) + qfloat16(700) << qfloat16(6e4) + qfloat16(1200); QTest::newRow("should FAIL 5") << qfloat16(6e4) - qfloat16(600) << qfloat16(6e4) - qfloat16(1200); @@ -200,7 +209,7 @@ void tst_float::compareFloatTests() const // Create two more values // t2 differs from t1 by 1 ppm (part per million) // t3 differs from t1 by 200% - // we should consider that t1 == t2 and t1 != t3 + // We should consider that t1 == t2 and t1 != t3 (provided at least one is > 1e-5) const float t2 = t1 + (t1 / 1e6); const float t3 = 3 * t1; @@ -214,7 +223,7 @@ void tst_float::compareFloatTests_data() const { QTest::addColumn("t1"); QTest::newRow("1e0") << 1e0f; - QTest::newRow("1e-7") << 1e-7f; + QTest::newRow("1e-5") << 1e-5f; QTest::newRow("1e+7") << 1e+7f; } diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index cab6589984f..84090c22cae 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** @@ -940,6 +940,14 @@ bool tst_Selftests::compareLine(const QString &logger, const QString &subdir, return true; } + if (EmulationDetector::isRunningArmOnX86() && subdir == QLatin1String("float")) { + // QEMU cheats at qfloat16, so outputs it as if it were a float. + if (actualLine.endsWith(QLatin1String("Actual (operandLeft) : 0.001")) + && expectedLine.endsWith(QLatin1String("Actual (operandLeft) : 0.000999"))) { + return true; + } + } + *errorMessage = msgMismatch(actualLine, expectedLine); return false; } From 8e4c32857de277c36a4876d5d4e5df8e3b84f18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 14 Apr 2020 17:54:24 +0200 Subject: [PATCH 41/44] QAuthenticator: make sure we load the SSPI library Change-Id: Iac371065dfc20ad5920889be66c8282a45c5805e Reviewed-by: Timur Pocheptsov --- src/network/kernel/qauthenticator.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index c95b1280b00..3ac54605e49 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -71,6 +71,7 @@ QT_BEGIN_NAMESPACE static QByteArray qNtlmPhase1(); static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phase2data); #if QT_CONFIG(sspi) // SSPI +static bool q_SSPI_library_load(); static QByteArray qSspiStartup(QAuthenticatorPrivate *ctx, QAuthenticatorPrivate::Method method, const QString& host); static QByteArray qSspiContinue(QAuthenticatorPrivate *ctx, QAuthenticatorPrivate::Method method, @@ -503,8 +504,13 @@ QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMet if (challenge.isEmpty()) { #if QT_CONFIG(sspi) // SSPI QByteArray phase1Token; - if (user.isEmpty()) // Only pull from system if no user was specified in authenticator + if (user.isEmpty()) { // Only pull from system if no user was specified in authenticator phase1Token = qSspiStartup(this, method, host); + } else if (!q_SSPI_library_load()) { + // Since we're not running qSspiStartup we have to make sure the library is loaded + qWarning("Failed to load the SSPI libraries"); + return ""; + } if (!phase1Token.isEmpty()) { response = phase1Token.toBase64(); phase = Phase2; From 90012f12b0fd7a6f9d2554fb2027e5f8c08d95ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 2 Apr 2020 17:16:47 +0200 Subject: [PATCH 42/44] QNAM: Don't check if a session is needed for a cache lookup QNetworkAccessCacheBackend didn't override the virtual start() function which then deferred to QNetworkAccessBackend::start() which conditions its success on whether or not a network session is available. Override the function and reimplement it without the network session check. Fixes: QTBUG-83205 Change-Id: I45d98a6f5da8ad04bb9da551a131f109e83074d7 Reviewed-by: Timur Pocheptsov --- src/network/access/qnetworkaccesscachebackend.cpp | 6 ++++++ src/network/access/qnetworkaccesscachebackend_p.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/network/access/qnetworkaccesscachebackend.cpp b/src/network/access/qnetworkaccesscachebackend.cpp index 22fdc5bb0b4..4986b36ab15 100644 --- a/src/network/access/qnetworkaccesscachebackend.cpp +++ b/src/network/access/qnetworkaccesscachebackend.cpp @@ -123,6 +123,12 @@ bool QNetworkAccessCacheBackend::sendCacheContents() return true; } +bool QNetworkAccessCacheBackend::start() +{ + open(); + return true; +} + void QNetworkAccessCacheBackend::closeDownstreamChannel() { } diff --git a/src/network/access/qnetworkaccesscachebackend_p.h b/src/network/access/qnetworkaccesscachebackend_p.h index dfb0ce84d9c..ceb02946dc3 100644 --- a/src/network/access/qnetworkaccesscachebackend_p.h +++ b/src/network/access/qnetworkaccesscachebackend_p.h @@ -68,6 +68,7 @@ public: void open() override; void closeDownstreamChannel() override; void closeUpstreamChannel(); + bool start() override; void upstreamReadyRead(); void downstreamReadyWrite() override; From a426326e99a76a92c8d0c870e19c67311a434483 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Mon, 3 Feb 2020 15:49:30 +0100 Subject: [PATCH 43/44] Doc: Make snippets Qt Widgets compilable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed mainwindowsnippet.cpp and widgetdelegate.cpp from snippets.pro Task-number: QTBUG-81497 Change-Id: I40d1f34e64d958d2fb857dc8e468b9c40fff527c Reviewed-by: Paul Wicking Reviewed-by: Kai Koehne Reviewed-by: Topi Reiniö --- src/widgets/doc/snippets/customviewstyle.cpp | 7 +-- src/widgets/doc/snippets/filedialogurls.cpp | 8 +-- .../snippets/graphicssceneadditemsnippet.cpp | 17 ++--- src/widgets/doc/snippets/graphicsview.cpp | 62 +++++++++++------- .../doc/snippets/graphicsview_snippet.cpp | 63 +++++++++++++++++++ src/widgets/doc/snippets/mdiareasnippets.cpp | 3 +- src/widgets/doc/snippets/myscrollarea.cpp | 23 ++----- src/widgets/doc/snippets/snippets.pro | 16 +++++ src/widgets/doc/src/graphicsview.qdoc | 2 +- 9 files changed, 137 insertions(+), 64 deletions(-) create mode 100644 src/widgets/doc/snippets/graphicsview_snippet.cpp create mode 100644 src/widgets/doc/snippets/snippets.pro diff --git a/src/widgets/doc/snippets/customviewstyle.cpp b/src/widgets/doc/snippets/customviewstyle.cpp index b9c10cb31d8..1e4cf2b711a 100644 --- a/src/widgets/doc/snippets/customviewstyle.cpp +++ b/src/widgets/doc/snippets/customviewstyle.cpp @@ -50,11 +50,10 @@ #include -#include "customviewstyle.h" +#include "./customstyle/customstyle.h" - - -void CustomViewStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const +void CustomStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, + QPainter *painter, const QWidget *widget) const { //![0] diff --git a/src/widgets/doc/snippets/filedialogurls.cpp b/src/widgets/doc/snippets/filedialogurls.cpp index cd91e797e79..4b73a6c8180 100644 --- a/src/widgets/doc/snippets/filedialogurls.cpp +++ b/src/widgets/doc/snippets/filedialogurls.cpp @@ -49,11 +49,10 @@ ****************************************************************************/ #include +#include -int main(int argv, char **args) +int loadFileDialog() { - QApplication app(argv, args); - //![0] QList urls; urls << QUrl::fromLocalFile("/Users/foo/Code/qt5") @@ -66,6 +65,5 @@ int main(int argv, char **args) // ... } //![0] - - return app.exec(); + return 1; } diff --git a/src/widgets/doc/snippets/graphicssceneadditemsnippet.cpp b/src/widgets/doc/snippets/graphicssceneadditemsnippet.cpp index 96e6bd650c0..0ce135dc63e 100644 --- a/src/widgets/doc/snippets/graphicssceneadditemsnippet.cpp +++ b/src/widgets/doc/snippets/graphicssceneadditemsnippet.cpp @@ -49,6 +49,9 @@ ****************************************************************************/ #include +#include +#include +#include class CustomScene : public QGraphicsScene { @@ -70,21 +73,9 @@ void CustomScene::drawItems(QPainter *painter, int numItems, for (int i = 0; i < numItems; ++i) { // Draw the item painter->save(); - painter->setMatrix(items[i]->sceneMatrix(), true); + painter->setTransform(items[i]->sceneTransform(), true); items[i]->paint(painter, &options[i], widget); painter->restore(); } } //! [0] - -int main(int argv, char **args) -{ - QApplication app(argv, args); - - CustomScene scene; - QGraphicsView view(&scene); - - view.show(); - - return app.exec(); -} diff --git a/src/widgets/doc/snippets/graphicsview.cpp b/src/widgets/doc/snippets/graphicsview.cpp index 9578f91eec3..6262137c901 100644 --- a/src/widgets/doc/snippets/graphicsview.cpp +++ b/src/widgets/doc/snippets/graphicsview.cpp @@ -47,53 +47,70 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +int main() +{ //! [0] QGraphicsScene scene; QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100)); -QGraphicsItem *item = scene.itemAt(50, 50); -// item == rect +QGraphicsItem *item = scene.itemAt(50, 50, QTransform()); //! [0] +Q_UNUSED(rect); +Q_UNUSED(item); +} +void myPopulateScene(QGraphicsScene *) +{ + // Intentionally left empty +} +void snippetThatUsesMyPopulateScene() +{ //! [1] QGraphicsScene scene; myPopulateScene(&scene); - QGraphicsView view(&scene); view.show(); //! [1] +} - -//! [2] -class View : public QGraphicsView +class CustomItem : public QStandardItem { -Q_OBJECT - ... -public slots: - void zoomIn() { scale(1.2, 1.2); } - void zoomOut() { scale(1 / 1.2, 1 / 1.2); } - void rotateLeft() { rotate(-10); } - void rotateRight() { rotate(10); } - ... +public: + using QStandardItem::QStandardItem; + + int type() const override { return UserType; } + void mousePressEvent(QGraphicsSceneMouseEvent *event); + QStandardItem *clone() const override { return new CustomItem; } }; -//! [2] +void printScene() +{ //! [3] QGraphicsScene scene; +QPrinter printer; scene.addRect(QRectF(0, 0, 100, 200), QPen(Qt::black), QBrush(Qt::green)); -QPrinter printer; if (QPrintDialog(&printer).exec() == QDialog::Accepted) { QPainter painter(&printer); painter.setRenderHint(QPainter::Antialiasing); scene.render(&painter); } //! [3] +} - +void pixmapScene() +{ //! [4] QGraphicsScene scene; scene.addRect(QRectF(0, 0, 100, 200), QPen(Qt::black), QBrush(Qt::green)); @@ -106,21 +123,21 @@ painter.end(); pixmap.save("scene.png"); //! [4] - +} //! [5] void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { QMimeData *data = new QMimeData; - data->setColor(Qt::green); - QDrag *drag = new QDrag(event->widget()); drag->setMimeData(data); - drag->start(); + drag->exec(); } //! [5] - +void viewScene() +{ +QGraphicsScene scene; //! [6] QGraphicsView view(&scene); QOpenGLWidget *gl = new QOpenGLWidget(); @@ -129,3 +146,4 @@ format.setSamples(4); gl->setFormat(format); view.setViewport(gl); //! [6] +} diff --git a/src/widgets/doc/snippets/graphicsview_snippet.cpp b/src/widgets/doc/snippets/graphicsview_snippet.cpp new file mode 100644 index 00000000000..9d058d0f6a4 --- /dev/null +++ b/src/widgets/doc/snippets/graphicsview_snippet.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +//! [2] +class View : public QGraphicsView +{ +Q_OBJECT + ... +public slots: + void zoomIn() { scale(1.2, 1.2); } + void zoomOut() { scale(1 / 1.2, 1 / 1.2); } + void rotateLeft() { rotate(-10); } + void rotateRight() { rotate(10); } + ... +}; +//! [2] diff --git a/src/widgets/doc/snippets/mdiareasnippets.cpp b/src/widgets/doc/snippets/mdiareasnippets.cpp index dec7aaa1e7e..c1e2d37ccb0 100644 --- a/src/widgets/doc/snippets/mdiareasnippets.cpp +++ b/src/widgets/doc/snippets/mdiareasnippets.cpp @@ -85,6 +85,7 @@ void addingSubWindowsExample() mdiArea.show(); } +/* int main(int argv, char **args) { QApplication app(argv, args); @@ -103,5 +104,5 @@ int main(int argv, char **args) return app.exec(); } - +*/ diff --git a/src/widgets/doc/snippets/myscrollarea.cpp b/src/widgets/doc/snippets/myscrollarea.cpp index dbf8da1603c..8afe4a68346 100644 --- a/src/widgets/doc/snippets/myscrollarea.cpp +++ b/src/widgets/doc/snippets/myscrollarea.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include +#include class MyScrollArea : public QAbstractScrollArea { @@ -97,8 +97,10 @@ void MyScrollArea::updateWidgetPosition() //! [0] } -void MyScrollArea::scrollContentsBy(int /*dx*/, int /*dy*/) +void MyScrollArea::scrollContentsBy(int dx, int dy) { + Q_UNUSED(dx); + Q_UNUSED(dy); updateWidgetPosition(); } @@ -118,21 +120,6 @@ void MyScrollArea::updateArea() void MyScrollArea::resizeEvent(QResizeEvent *event) { + Q_UNUSED(event); updateArea(); } - -int main(int argv, char **args) -{ - QApplication app(argv, args); - - QPixmap pixmap("mypixmap.png"); - QLabel label; - label.setPixmap(pixmap); - MyScrollArea area(&label); - area.resize(300, 300); - area.show(); - - area.setWidget(&label); - - return app.exec(); -} diff --git a/src/widgets/doc/snippets/snippets.pro b/src/widgets/doc/snippets/snippets.pro new file mode 100644 index 00000000000..f1d3596f9d2 --- /dev/null +++ b/src/widgets/doc/snippets/snippets.pro @@ -0,0 +1,16 @@ +requires(qtHaveModule(widgets)) +requires(qtHaveModule(printsupport)) + +TEMPLATE = app + +TARGET = widgets_snippets + +QT += widgets printsupport + +SOURCES += customviewstyle.cpp \ + filedialogurls.cpp \ + graphicssceneadditemsnippet.cpp \ + graphicsview.cpp \ + mdiareasnippets.cpp \ + myscrollarea.cpp + diff --git a/src/widgets/doc/src/graphicsview.qdoc b/src/widgets/doc/src/graphicsview.qdoc index 94c824c2edc..46a68adc56f 100644 --- a/src/widgets/doc/src/graphicsview.qdoc +++ b/src/widgets/doc/src/graphicsview.qdoc @@ -327,7 +327,7 @@ Here is an example of how to implement zoom and rotate slots in a subclass of QGraphicsView: - \snippet graphicsview.cpp 2 + \snippet graphicsview_snippet.cpp 2 The slots could be connected to \l{QToolButton}{QToolButtons} with \l{QAbstractButton::autoRepeat}{autoRepeat} enabled. From f0ea852d4dd6b3139869a952ee92e74cd367866d Mon Sep 17 00:00:00 2001 From: David Faure Date: Thu, 30 Apr 2020 20:44:11 +0200 Subject: [PATCH 44/44] QCommandLineParser: Wrap very long option names to leave room for descriptions Fixes: QTBUG-79926 Change-Id: I3302e0ed5b58949a35ccb001c71b22a6400a6c81 Reviewed-by: Thiago Macieira --- src/corelib/tools/qcommandlineparser.cpp | 29 ++++++++++------ .../qcommandlineparser_test_helper.cpp | 7 ++++ .../tst_qcommandlineparser.cpp | 33 +++++++++++++++++++ 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp index 48501f5271e..a3d2a2f7c0a 100644 --- a/src/corelib/tools/qcommandlineparser.cpp +++ b/src/corelib/tools/qcommandlineparser.cpp @@ -1063,18 +1063,23 @@ QString QCommandLineParser::helpText() const return d->helpText(false); } -static QString wrapText(const QString &names, int longestOptionNameString, const QString &description) +static QString wrapText(const QString &names, int optionNameMaxWidth, const QString &description) { const QLatin1Char nl('\n'); const QLatin1String indentation(" "); - if (description.isEmpty()) - return indentation + names + nl; - QString text = indentation + names.leftJustified(longestOptionNameString) + QLatin1Char(' '); - const int indent = text.length(); + // In case the list of option names is very long, wrap it as well + int nameIndex = 0; + auto nextNameSection = [&]() { + QString section = names.mid(nameIndex, optionNameMaxWidth); + nameIndex += section.size(); + return section; + }; + + QString text; int lineStart = 0; int lastBreakable = -1; - const int max = 79 - indent; + const int max = 79 - (indentation.size() + optionNameMaxWidth + 1); int x = 0; const int len = description.length(); @@ -1103,8 +1108,7 @@ static QString wrapText(const QString &names, int longestOptionNameString, const if (breakAt != -1) { const int numChars = breakAt - lineStart; //qDebug() << "breakAt=" << description.at(breakAt) << "breakAtSpace=" << breakAtSpace << lineStart << "to" << breakAt << description.mid(lineStart, numChars); - if (lineStart > 0) - text += QString(indent, QLatin1Char(' ')); + text += indentation + nextNameSection().leftJustified(optionNameMaxWidth) + QLatin1Char(' '); text += description.midRef(lineStart, numChars) + nl; x = 0; lastBreakable = -1; @@ -1115,6 +1119,10 @@ static QString wrapText(const QString &names, int longestOptionNameString, const } } + while (nameIndex < names.size()) { + text += indentation + nextNameSection() + nl; + } + return text; } @@ -1158,11 +1166,12 @@ QString QCommandLineParserPrivate::helpText(bool includeQtOptions) const longestOptionNameString = qMax(longestOptionNameString, optionNamesString.length()); } ++longestOptionNameString; + const int optionNameMaxWidth = qMin(50, longestOptionNameString); auto optionNameIterator = optionNameList.cbegin(); for (const QCommandLineOption &option : qAsConst(options)) { if (option.flags() & QCommandLineOption::HiddenFromHelp) continue; - text += wrapText(*optionNameIterator, longestOptionNameString, option.description()); + text += wrapText(*optionNameIterator, optionNameMaxWidth, option.description()); ++optionNameIterator; } if (!positionalArgumentDefinitions.isEmpty()) { @@ -1170,7 +1179,7 @@ QString QCommandLineParserPrivate::helpText(bool includeQtOptions) const text += nl; text += QCommandLineParser::tr("Arguments:") + nl; for (const PositionalArgumentDefinition &arg : positionalArgumentDefinitions) - text += wrapText(arg.name, longestOptionNameString, arg.description); + text += wrapText(arg.name, optionNameMaxWidth, arg.description); } return text; } diff --git a/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.cpp b/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.cpp index 513c8117883..88dfdeccabb 100644 --- a/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.cpp +++ b/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.cpp @@ -97,6 +97,13 @@ int main(int argc, char *argv[]) parser.process(app); const QString size = parser.value("size"); printf("Resizing %s to %s and saving to %s\n", qPrintable(parser.value("load")), qPrintable(size), qPrintable(parser.value("o"))); + } else if (command == "long") { + // A very long option (QTBUG-79926) + QCommandLineOption longOption(QStringList{QStringLiteral("looooooooooooong-option"), QStringLiteral("looooong-opt-alias")}); + longOption.setDescription(QStringLiteral("Short description")); + longOption.setValueName(QStringLiteral("looooooooooooong-value-name")); + parser.addOption(longOption); + parser.process(app); } else { // Call process again, to handle unknown options this time. parser.process(app); diff --git a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp index 1e87c76d2f0..493d8d4982f 100644 --- a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp +++ b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp @@ -78,6 +78,7 @@ private slots: void testUnknownOption(); void testHelpAll_data(); void testHelpAll(); + void testVeryLongOptionNames(); }; static char *empty_argv[] = { 0 }; @@ -737,6 +738,38 @@ void tst_QCommandLineParser::testHelpAll() #endif // QT_CONFIG(process) } +void tst_QCommandLineParser::testVeryLongOptionNames() +{ +#if !QT_CONFIG(process) + QSKIP("This test requires QProcess support"); +#else +#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) + QSKIP("Deploying executable applications to file system on Android not supported."); +#endif + + QCoreApplication app(empty_argc, empty_argv); + QProcess process; + process.start("testhelper/qcommandlineparser_test_helper", QStringList() << "0" << "long" << "--help"); + QVERIFY(process.waitForFinished(5000)); + QCOMPARE(process.exitStatus(), QProcess::NormalExit); + QString output = process.readAll(); +#ifdef Q_OS_WIN + output.replace(QStringLiteral("\r\n"), QStringLiteral("\n")); +#endif + const QStringList lines = output.split('\n'); + const int last = lines.count() - 1; + // Let's not compare everything, just the final parts. + QCOMPARE(lines.at(last - 7), " cdefghijklmnopqrstuvwxyz"); + QCOMPARE(lines.at(last - 6), " --looooooooooooong-option, --looooong-opt-alias "); + QCOMPARE(lines.at(last - 4), ""); + QCOMPARE(lines.at(last - 3), "Arguments:"); + QCOMPARE(lines.at(last - 2), " parsingMode The parsing mode to test."); + QCOMPARE(lines.at(last - 1), " command The command to execute."); + +#endif // QT_CONFIG(process) +} + QTEST_APPLESS_MAIN(tst_QCommandLineParser) #include "tst_qcommandlineparser.moc"