From be6921e8605ef3951ff8e8f2528c4c2e4f8d9b71 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sun, 26 Jun 2016 15:36:15 +0200 Subject: Doc: fix app type notes for QDirModel and QFileSystemModel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "GUI application" is quite confusing, because in fact, these models are part of QtWidgets and thus require QApplication instead of QGuiApplication. Change-Id: I35ccc8bfeb74c75a84b2ffbe1cab0c0839495980 Reviewed-by: Sze Howe Koh Reviewed-by: Topi Reiniö Reviewed-by: Friedemann Kleint --- src/widgets/dialogs/qfilesystemmodel.cpp | 2 +- src/widgets/itemviews/qdirmodel.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 0e2eee3b47..441a54bd7d 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -81,7 +81,7 @@ QT_BEGIN_NAMESPACE about the underlying files and directories related to items in the model. Directories can be created and removed using mkdir(), rmdir(). - \note QFileSystemModel requires an instance of a GUI application. + \note QFileSystemModel requires an instance of \l QApplication. \section1 Example Usage diff --git a/src/widgets/itemviews/qdirmodel.cpp b/src/widgets/itemviews/qdirmodel.cpp index ac23e22ef7..b2d2a981fc 100644 --- a/src/widgets/itemviews/qdirmodel.cpp +++ b/src/widgets/itemviews/qdirmodel.cpp @@ -202,7 +202,7 @@ void QDirModelPrivate::invalidate() Directories can be created and removed using mkdir(), rmdir(), and the model will be automatically updated to take the changes into account. - \note QDirModel requires an instance of a GUI application. + \note QDirModel requires an instance of \l QApplication. \sa nameFilters(), setFilter(), filter(), QListView, QTreeView, QFileSystemModel, {Dir View Example}, {Model Classes} -- cgit v1.2.3 From 596ce989b5efff9d062540544e9c024dabe14e05 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 29 Jun 2016 08:35:58 +0200 Subject: Windows QPA: Improve warning about SetProcessDpiAwareness() failure Silence warning in case DPI awareness was set externally unless debug is enabled. Task-number: QTBUG-54416 Change-Id: Id48769e3d4be3047f582e331633905c640930f21 Reviewed-by: Kai Koehne --- src/plugins/platforms/windows/qwindowscontext.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 09c2f7df2e..39054b6a64 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -409,7 +409,9 @@ void QWindowsContext::setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiA qCDebug(lcQpaWindows) << __FUNCTION__ << dpiAwareness; if (QWindowsContext::shcoredll.isValid()) { const HRESULT hr = QWindowsContext::shcoredll.setProcessDpiAwareness(dpiAwareness); - if (FAILED(hr)) { + // E_ACCESSDENIED means set externally (MSVC manifest or external app loading Qt plugin). + // Silence warning in that case unless debug is enabled. + if (FAILED(hr) && (hr != E_ACCESSDENIED || lcQpaWindows().isDebugEnabled())) { qWarning().noquote().nospace() << "SetProcessDpiAwareness(" << dpiAwareness << ") failed: " << QWindowsContext::comErrorString(hr) << ", using " << QWindowsContext::processDpiAwareness(); @@ -843,6 +845,9 @@ QByteArray QWindowsContext::comErrorString(HRESULT hr) case E_UNEXPECTED: result += QByteArrayLiteral("E_UNEXPECTED"); break; + case E_ACCESSDENIED: + result += QByteArrayLiteral("E_ACCESSDENIED"); + break; case CO_E_ALREADYINITIALIZED: result += QByteArrayLiteral("CO_E_ALREADYINITIALIZED"); break; -- cgit v1.2.3 From df9aee21504b18decbd5637ca4ce86c559fa3cc3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 29 Jun 2016 15:02:58 +0200 Subject: Fix URL to ANGLE Point to the README.md of the project; the old URL http://code.google.com/p/angleproject is now redirected to the bugtracker. Change-Id: I293fc150d5b6c08f16effe8921010050faa264b5 Reviewed-by: Maurice Kalinowski --- doc/global/externalsites/external-resources.qdoc | 2 +- src/angle/README.qt | 2 +- src/plugins/platforms/windows/qwindowseglcontext.cpp | 2 +- tools/configure/configureapp.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/global/externalsites/external-resources.qdoc b/doc/global/externalsites/external-resources.qdoc index 3e82dfe814..a7b34af50c 100644 --- a/doc/global/externalsites/external-resources.qdoc +++ b/doc/global/externalsites/external-resources.qdoc @@ -174,7 +174,7 @@ */ /*! - \externalpage http://code.google.com/p/angleproject/ + \externalpage https://chromium.googlesource.com/angle/angle/+/master/README.md \title ANGLE */ diff --git a/src/angle/README.qt b/src/angle/README.qt index ce5b6332bc..2d484a0280 100644 --- a/src/angle/README.qt +++ b/src/angle/README.qt @@ -1,6 +1,6 @@ This is the ANGLE project from: -http://code.google.com/p/angleproject/ +https://chromium.googlesource.com/angle/angle/+/master/README.md The upstream version used here can be found in: diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 9ae1ca8acb..82ac47e99f 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -513,7 +513,7 @@ QSurfaceFormat QWindowsEGLStaticContext::formatFromConfig(EGLDisplay display, EG \list \o Install the Direct X SDK \o Checkout and build ANGLE (SVN repository) as explained here: - \l{http://code.google.com/p/angleproject/wiki/DevSetup}{ANGLE-Project}. + \l{https://chromium.googlesource.com/angle/angle/+/master/README.md} When building for 64bit, de-activate the "WarnAsError" option in every project file (as otherwise integer conversion warnings will break the build). diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 0909ff8aab..f2b54f57f2 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -2009,7 +2009,7 @@ bool Configure::displayHelp() } desc("ANGLE", "yes", "-angle", "Use the ANGLE implementation of OpenGL ES 2.0."); - desc("ANGLE", "no", "-no-angle", "Do not use ANGLE.\nSee http://code.google.com/p/angleproject/\n"); + desc("ANGLE", "no", "-no-angle", "Do not use ANGLE.\nSee https://chromium.googlesource.com/angle/angle/+/master/README.md\n"); // Qt\Windows only options go below here -------------------------------------------------------------------------------- desc("\nQt for Windows only:\n\n"); -- cgit v1.2.3 From 2714d94ff4652e863f2e6005a138a2563d836f07 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 8 Jun 2016 16:19:04 +0200 Subject: Fix tst_QNetworkReply::qtbug45581WrongReplyStatusCode() on Windows The file is read using CRLF line convention on Windows. Task-number: QTBUG-24226 Change-Id: Ie08fa603e29c80a42de4bfbfd1f4237f53c22b98 Reviewed-by: Timur Pocheptsov --- tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 02aca3d6c1..0f2d0873a7 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -7295,7 +7295,11 @@ void tst_QNetworkReply::qtbug45581WrongReplyStatusCode() const QByteArray expectedContent = "" - "\n"; + "" +#ifdef Q_OS_WIN + "\r" +#endif + "\n"; QCOMPARE(reply->readAll(), expectedContent); -- cgit v1.2.3 From db1a6ac357eaaa09690a8310bcb799c678836320 Mon Sep 17 00:00:00 2001 From: Bernhard Scheirle Date: Sat, 18 Jun 2016 14:30:15 +0200 Subject: Fix shortcut handling for level three and above shortcuts Calling `xkb_state_update_mask` with correctly set `depressed_mods` allows xkb to return keys on level three or above (and not the equivalent level one key). To preserve level two shortcuts (return equivalent level one key) `depressed_mods` gets only set, if the pressed key is on level three or above. Example shortcuts which now will work: Shortcut German Layout (de) [AltGr is a level three switch] Ctrl+@ Ctrl+AltGr+Q Shift+1 Shift+1 (as before) Shortcut German Neo Layout (de neo) [1] [AltGr is a level five switch] Left AltGr+S [1] http://neo-layout.org Task-number: QTBUG-53121 Change-Id: I637a01edc9f2f92a5d3e7a24f5051fb1d3ac2f7f Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 1eeb59a665..28de86b8ba 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -973,10 +973,21 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const xkb_layout_index_t lockedLayout = xkb_state_serialize_layout(xkb_state, XKB_STATE_LAYOUT_LOCKED); xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED); xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED); + xkb_mod_mask_t depressedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED); - xkb_state_update_mask(kb_state, 0, latchedMods, lockedMods, 0, 0, lockedLayout); - + xkb_state_update_mask(kb_state, depressedMods, latchedMods, lockedMods, 0, 0, lockedLayout); quint32 keycode = event->nativeScanCode(); + // handle shortcuts for level three and above + xkb_layout_index_t layoutIndex = xkb_state_key_get_layout(kb_state, keycode); + xkb_level_index_t levelIndex = 0; + if (layoutIndex != XKB_LAYOUT_INVALID) { + levelIndex = xkb_state_key_get_level(kb_state, keycode, layoutIndex); + if (levelIndex == XKB_LEVEL_INVALID) + levelIndex = 0; + } + if (levelIndex <= 1) + xkb_state_update_mask(kb_state, 0, latchedMods, lockedMods, 0, 0, lockedLayout); + xkb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, keycode); if (sym == XKB_KEY_NoSymbol) { xkb_state_unref(kb_state); -- cgit v1.2.3 From 7a8330ddf7601608346036e2f120a4497e016ee8 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 22 Jun 2016 14:18:33 +0200 Subject: Fix QDockWidget losing decoration on undocking when GroupedDragging is enabled We should not remember the wrong undocked geometry. If the dockwidget is not floating, the geometry is not relative to the global coordinate, it makes no sense to store it. Task-number: QTBUG-53808 Change-Id: I242467d8da62d7c787eca2c784aeec646236cb44 Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qdockwidget.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index a7e04d3bfc..20f35cb211 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -805,7 +805,8 @@ void QDockWidgetPrivate::endDrag(bool abort) } else { setResizerActive(false); } - undockedGeometry = q->geometry(); + if (q->isFloating()) // Might not be floating when dragging a QDockWidgetGroupWindow + undockedGeometry = q->geometry(); q->activateWindow(); } else { // The tab was not plugged back in the QMainWindow but the QDockWidget cannot -- cgit v1.2.3 From faeaddc1b92f1000a5a1d9d7cdea9276bdfefe26 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 15 Jun 2016 10:01:14 +0200 Subject: QSslSocket::transmit (macOS/iOS) - do not use invalid context 1. QSslSocketBackendPrivate::transmit can invalidate SSL context causing subsequent SSLWrite or SSLRead calls to fail; these report errSecParam (as null context is an invalid parameter) spuriously, when we should rather report the cause of invalidation. The OpenSSL backend can trigger this when it aborts connection during an SSL handshake, on an sslErrors signal. As transmit() emits readReady(), a directly connected slot can trigger the same problem if it aborts or closes. 2. If during peer verification (and in checkSslErrors) we disconnect on sslErrors signal, peer verification must be considered failed and should not continue handshake/set connectionEncrypted. Task-number: QTBUG-52975 Task-number: QTBUG-53906 Change-Id: Iacd3b489a4156e25ef3460ace40d21f34a946bed Reviewed-by: Edward Welbourne --- src/network/ssl/qsslsocket_mac.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 4e090f96cb..9f0359aa47 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -634,7 +634,7 @@ void QSslSocketBackendPrivate::transmit() if (connectionEncrypted && !writeBuffer.isEmpty()) { qint64 totalBytesWritten = 0; - while (writeBuffer.nextDataBlockSize() > 0) { + while (writeBuffer.nextDataBlockSize() > 0 && context) { const size_t nextDataBlockSize = writeBuffer.nextDataBlockSize(); size_t writtenBytes = 0; const OSStatus err = SSLWrite(context, writeBuffer.readPointer(), nextDataBlockSize, &writtenBytes); @@ -668,7 +668,7 @@ void QSslSocketBackendPrivate::transmit() if (connectionEncrypted) { QVarLengthArray data; - while (true) { + while (context) { size_t readBytes = 0; data.resize(4096); const OSStatus err = SSLRead(context, data.data(), data.size(), &readBytes); @@ -1305,7 +1305,10 @@ bool QSslSocketBackendPrivate::verifyPeerTrust() // report errors if (!errors.isEmpty() && !canIgnoreVerify) { sslErrors = errors; - if (!checkSslErrors()) + // checkSslErrors unconditionally emits sslErrors: + // a user's slot can abort/close/disconnect on this + // signal, so we also test the socket's state: + if (!checkSslErrors() || q->state() != QAbstractSocket::ConnectedState) return false; } else { sslErrors.clear(); -- cgit v1.2.3 From ed32af3506c42689001d9b7267897405c02d3c39 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 30 Jun 2016 10:16:35 +0200 Subject: winrt: fix conditional Seems the previous check was a leftover from debugging. Tests still pass and loop checks properly now. Change-Id: Ic12cd49881f6d146687e257794b3028f6c8e874c Reviewed-by: Friedemann Kleint --- src/corelib/io/qsettings_winrt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qsettings_winrt.cpp b/src/corelib/io/qsettings_winrt.cpp index 02c3c7624e..85ef64cbd4 100644 --- a/src/corelib/io/qsettings_winrt.cpp +++ b/src/corelib/io/qsettings_winrt.cpp @@ -86,7 +86,7 @@ static IApplicationDataContainer *subContainer(IApplicationDataContainer *parent if (FAILED(hr)) return 0; - while (SUCCEEDED(S_OK) && current) { + while (SUCCEEDED(hr) && current) { ComPtr item; hr = iterator->get_Current(&item); if (FAILED(hr)) -- cgit v1.2.3 From dfd62a8f36a6461c3f3cad390c8a243829bea0e4 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 30 Jun 2016 10:04:07 +0200 Subject: winrt: Clean up function signature Change-Id: I006d4a2295103c8e4169945dfb451ee55598ec87 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/winrt/qwinrtdrag.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtdrag.cpp b/src/plugins/platforms/winrt/qwinrtdrag.cpp index 2ef50aa4e2..055aacbf56 100644 --- a/src/plugins/platforms/winrt/qwinrtdrag.cpp +++ b/src/plugins/platforms/winrt/qwinrtdrag.cpp @@ -504,8 +504,8 @@ static HRESULT qt_drop(IInspectable *sender, ABI::Windows::UI::Xaml::IDragEventA class QtDragEventHandler##name : public IDragEventHandler \ { \ public: \ - virtual HRESULT STDMETHODCALLTYPE Invoke(IInspectable *sender, \ - ABI::Windows::UI::Xaml::IDragEventArgs *e) \ + STDMETHODIMP Invoke(IInspectable *sender, \ + ABI::Windows::UI::Xaml::IDragEventArgs *e) \ { \ return qt_##func(sender, e);\ } \ -- cgit v1.2.3 From f3df265a38b1ee7b8dab918d669d9bb721f38f74 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 14 Jun 2016 12:26:29 +0200 Subject: QDateTime: early return to make a Q_UNREACHABLE actually true. It could be reached when QT_BOOTSTRAPPED was defined. Change-Id: I632d6f908a3bcbde81a6ebbadcaf2800dfe1449d Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 1719d7f470..fb679e56c5 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2698,7 +2698,7 @@ qint64 QDateTimePrivate::toMSecsSinceEpoch() const case Qt::TimeZone: #ifdef QT_BOOTSTRAPPED - break; + return 0; #else return zoneMSecsToEpochMSecs(m_msecs, m_timeZone); #endif -- cgit v1.2.3 From c376e3fbf0cbeb60be9db8903f9a2998b8311ed6 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Mon, 27 Jun 2016 18:52:30 +0300 Subject: QDir: Remove redundant QString wrapping Change-Id: I8368b137d15509cdec575a17f5dae3c0c343400f Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qdir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index d0527282b5..3004711571 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -686,7 +686,7 @@ QString QDir::filePath(const QString &fileName) const { const QDirPrivate* d = d_ptr.constData(); if (isAbsolutePath(fileName)) - return QString(fileName); + return fileName; QString ret = d->dirEntry.filePath(); if (!fileName.isEmpty()) { -- cgit v1.2.3 From 25db59d7723c3d05ff55104768da31b0a7ce68ee Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 30 Jun 2016 08:48:52 +0200 Subject: Fix QLineEdit not showing clear button on macOS Restore code path returning the resource pixmap for platforms that do not have themes in QCommonStyle. Amends change b657496a0ba326af0688e9935069139c002849cf. Task-number: QTBUG-54425 Change-Id: I764408622b825b86afbe7ccf37e1498d3efb3850 Reviewed-by: Timur Pocheptsov --- src/widgets/styles/qcommonstyle.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 7b0d8eacd5..6bf9d20b47 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -5194,6 +5194,13 @@ static QPixmap cachedPixmapFromXPM(const char * const *xpm) return result; } +#ifndef QT_NO_IMAGEFORMAT_PNG +static inline QString clearText16IconPath() +{ + return QStringLiteral(":/qt-project.org/styles/commonstyle/images/cleartext-16.png"); +} +#endif // !QT_NO_IMAGEFORMAT_PNG + static QIcon clearTextIcon(bool rtl) { const QString directionalThemeName = rtl @@ -5206,7 +5213,7 @@ static QIcon clearTextIcon(bool rtl) QIcon icon; #ifndef QT_NO_IMAGEFORMAT_PNG - QPixmap clearText16(QStringLiteral(":/qt-project.org/styles/commonstyle/images/cleartext-16.png")); + QPixmap clearText16(clearText16IconPath()); Q_ASSERT(!clearText16.size().isEmpty()); icon.addPixmap(clearText16); QPixmap clearText32(QStringLiteral(":/qt-project.org/styles/commonstyle/images/cleartext-32.png")); @@ -5521,6 +5528,8 @@ QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *opti return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-16.png")); case SP_MediaVolumeMuted: return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-muted-16.png")); + case SP_LineEditClearButton: + return QPixmap(clearText16IconPath()); #endif // QT_NO_IMAGEFORMAT_PNG default: break; -- cgit v1.2.3 From d0055e9fd7825f9033b26f9aa421e218e44dadde Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 30 Jun 2016 14:13:48 +0200 Subject: nuke dead expandVariableReferences() overload prototype Change-Id: I0c6fceac0b984e4613932b8507a632dd83d0e79b Reviewed-by: Joerg Bornemann --- qmake/library/qmakeevaluator.h | 1 - 1 file changed, 1 deletion(-) diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index 9560f71587..312f1385fb 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -182,7 +182,6 @@ public: void setTemplate(); ProStringList split_value_list(const QString &vals, const ProFile *source = 0); - ProStringList expandVariableReferences(const ProString &value, int *pos = 0, bool joined = false); ProStringList expandVariableReferences(const ushort *&tokPtr, int sizeHint = 0, bool joined = false); QString currentFileName() const; -- cgit v1.2.3 From 1e662ff1666f0a47eed84ae9e6bc02869aa19f9b Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 1 Jul 2016 08:29:08 +0200 Subject: winrt: Set minimum SDK version to 10586 10586 reflects Update 1, which is the mininum supported version for many months, hence reflext this in the manifest template as well. There are additional features (like drag and drop) which require and even later SDK version. However, they do not reflect the minimum. Change-Id: I6d71dc499c928ed98c8a25283e0b53994317bb00 Reviewed-by: Friedemann Kleint --- mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in index c25d7b77af..fc6bfcebcf 100644 --- a/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +++ b/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in @@ -22,7 +22,7 @@ - $${WINRT_MANIFEST.dependencies} + $${WINRT_MANIFEST.dependencies} -- cgit v1.2.3 From 890edc45d897639f0ef99a561ea033d6ae5781e7 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sun, 5 Jun 2016 20:57:38 +0200 Subject: QSslSocket: improve documentation of the supported protocols MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1) To describe a protocol version we should use an "ordinary" name, not use the values out of the QSsl::SslProtocol enum. 2) Say that we support the latest stable TLS version (1.2, not 1.0). 3) Fix a statement about which protocol is the default one. Change-Id: I18732914d55060a0c3920f7082f986c262a71ded Reviewed-by: André Klitzing Reviewed-by: Richard J. Moore --- src/network/ssl/qsslsocket.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 25a471dda8..c453606262 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -49,7 +49,8 @@ QSslSocket establishes a secure, encrypted TCP connection you can use for transmitting encrypted data. It can operate in both client and server mode, and it supports modern SSL protocols, including - SSLv3 and TLSv1_0. By default, QSslSocket uses TLSv1_0, but you can + SSL 3 and TLS 1.2. By default, QSslSocket uses only SSL protocols + which are considered to be secure (QSsl::SecureProtocols), but you can change the SSL protocol by calling setProtocol() as long as you do it before the handshake has started. -- cgit v1.2.3 From cc42979e4653f8fc543b6968c9ff08f4356fa724 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Wed, 29 Jun 2016 11:54:33 +0200 Subject: NetBSD: add QMAKE_RPATHDIR for standard QMAKE_LIBDIR NetBSD is heavily dependent on using rpath, so we need to add the lib dir QMAKE_LIBDIR and QMAKE_LIBDIR_X11 to QMAKE_RPATHDIR explicitly to avoid linker errors. See http://www.netbsd.org/docs/elf.html for more info. Change-Id: I225143d5e2d9a125060b14e3a8a7953927d63b33 Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- mkspecs/netbsd-g++/qmake.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mkspecs/netbsd-g++/qmake.conf b/mkspecs/netbsd-g++/qmake.conf index 31005d9134..a4b26837ce 100644 --- a/mkspecs/netbsd-g++/qmake.conf +++ b/mkspecs/netbsd-g++/qmake.conf @@ -17,6 +17,9 @@ QMAKE_LIBDIR_X11 = /usr/X11R7/lib QMAKE_INCDIR_OPENGL = /usr/X11R7/include QMAKE_LIBDIR_OPENGL = /usr/X11R7/lib +# NetBSD requires rpath to be used for all lib dirs, see http://www.netbsd.org/docs/elf.html +QMAKE_RPATHDIR += $$QMAKE_LIBDIR $$QMAKE_LIBDIR_X11 + include(../common/gcc-base-unix.conf) include(../common/g++-unix.conf) load(qt_config) -- cgit v1.2.3 From fbe67f06bc4995569a237a40d8d0aef2088acb10 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 30 Jun 2016 11:05:15 +0200 Subject: Diaglib: Build DebugProxyStyle only when QtWidgets are used Change-Id: Iba1ca731ac569db12211a93f65583d73ffcfce91 Reviewed-by: Shawn Rutledge --- tests/manual/diaglib/diaglib.pri | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/manual/diaglib/diaglib.pri b/tests/manual/diaglib/diaglib.pri index 9bcf0317a6..e3e7c3757c 100644 --- a/tests/manual/diaglib/diaglib.pri +++ b/tests/manual/diaglib/diaglib.pri @@ -2,15 +2,13 @@ INCLUDEPATH += $$PWD SOURCES += \ $$PWD/textdump.cpp \ $$PWD/eventfilter.cpp \ - $$PWD/qwindowdump.cpp \ - $$PWD/debugproxystyle.cpp + $$PWD/qwindowdump.cpp HEADERS += \ $$PWD/textdump.h \ $$PWD/eventfilter.h \ $$PWD/qwindowdump.h \ - $$PWD/nativewindowdump.h \ - $$PWD/debugproxystyle.h + $$PWD/nativewindowdump.h win32 { SOURCES += $$PWD/nativewindowdump_win.cpp @@ -24,19 +22,23 @@ greaterThan(QT_MAJOR_VERSION, 4) { contains(QT, widgets) { HEADERS += \ $$PWD/qwidgetdump.h \ + $$PWD/debugproxystyle.h \ $$PWD/logwidget.h SOURCES += \ $$PWD/qwidgetdump.cpp \ + $$PWD/debugproxystyle.cpp \ $$PWD/logwidget.cpp } } else { HEADERS += \ $$PWD/qwidgetdump.h \ + $$PWD/debugproxystyle.h \ $$PWD/logwidget.h SOURCES += \ $$PWD/qwidgetdump.cpp \ + $$PWD/debugproxystyle.cpp \ $$PWD/logwidget.cpp } -- cgit v1.2.3 From c3f645a24ac743e66f4345058983ad877f723a14 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 23 Jun 2016 09:44:58 +0200 Subject: Windows: Add support for the PdmDevicePixelRatioScaled metric Change-Id: If65018a86e386a54f40ee12e81b5137e3412d655 Reviewed-by: Friedemann Kleint Reviewed-by: Andy Shaw --- src/printsupport/kernel/qprintengine_win.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp index 00a8ca7c98..a9d316095c 100644 --- a/src/printsupport/kernel/qprintengine_win.cpp +++ b/src/printsupport/kernel/qprintengine_win.cpp @@ -388,6 +388,9 @@ int QWin32PrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const case QPaintDevice::PdmDevicePixelRatio: val = 1; break; + case QPaintDevice::PdmDevicePixelRatioScaled: + val = 1 * QPaintDevice::devicePixelRatioFScale(); + break; default: qWarning("QPrinter::metric: Invalid metric command"); return 0; -- cgit v1.2.3 From 9964b850ad9c322ab842bbd5941976b3d613f5f6 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 30 May 2016 16:57:00 +0200 Subject: Doc: Improve QJsonDocument::fromJson documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Be explicit on how to check whether parsing succeeds. Change-Id: I44f408cb6e5a830826b84dfb3a8af331f03e58cc Reviewed-by: Topi Reiniö --- src/corelib/json/qjsondocument.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/corelib/json/qjsondocument.cpp b/src/corelib/json/qjsondocument.cpp index 5f8f807cf0..7af7e4080c 100644 --- a/src/corelib/json/qjsondocument.cpp +++ b/src/corelib/json/qjsondocument.cpp @@ -351,16 +351,14 @@ QByteArray QJsonDocument::toJson(JsonFormat format) const #endif /*! - Parses a UTF-8 encoded JSON document and creates a QJsonDocument + Parses \a json as a UTF-8 encoded JSON document, and creates a QJsonDocument from it. - \a json contains the json document to be parsed. + Returns a valid (non-null) QJsonDocument if the parsing succeeds. If it fails, + the returned document will be null, and the optional \a error variable will contain + further details about the error. - The optional \a error variable can be used to pass in a QJsonParseError data - structure that will contain information about possible errors encountered during - parsing. - - \sa toJson(), QJsonParseError + \sa toJson(), QJsonParseError, isNull() */ QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error) { -- cgit v1.2.3 From 3c93286f08a80b6e1821d7d63d361742b25c6578 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Mon, 13 Jun 2016 17:25:34 +0300 Subject: QDataStream: unify deserialization of containers Serialization of the Qt container classes is accomplished by breaking up the data into primitive units. On the receiver side, these units should be read atomically to guarantee integrity of the container. Deserialization procedures for QHash and QMap were already implemented in accordance with this strategy and have the following behavior: - a previously latched error status is saved for the caller. This overrides possible different errors in the current read. This is consistent with the treatment of primitive types. - if an error occurs during the deserialization, the container is cleared. To make the API consistent, this patch adjusts the behavior of QList, QLinkedList, QVector, and QSet deserialization. On the implementation side we accomplish this with a private StreamStateSaver RAII class that consolidates the handling of the stream status for all containers. [ChangeLog][Important Behavior Changes][QtCore][QDataStream] Incomplete reads of Qt containers are now handled same way as for primitive types, meaning that previous errors are latched. Task-number: QTBUG-54022 Change-Id: I5c77257fe2a4637e8a7e6cf3cd43091c8469340e Reviewed-by: Oswald Buddenhagen Reviewed-by: Edward Welbourne --- src/corelib/io/qdatastream.h | 75 ++++++++++++++++------ .../corelib/io/qdatastream/tst_qdatastream.cpp | 50 ++++++++++++++- 2 files changed, 102 insertions(+), 23 deletions(-) diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h index e0a9cccdad..260dd519e3 100644 --- a/src/corelib/io/qdatastream.h +++ b/src/corelib/io/qdatastream.h @@ -194,6 +194,29 @@ private: int readBlock(char *data, int len); }; +namespace QtPrivate { + +class StreamStateSaver +{ +public: + inline StreamStateSaver(QDataStream *s) : stream(s), oldStatus(s->status()) + { + stream->resetStatus(); + } + inline ~StreamStateSaver() + { + if (oldStatus != QDataStream::Ok) { + stream->resetStatus(); + stream->setStatus(oldStatus); + } + } + +private: + QDataStream *stream; + QDataStream::Status oldStatus; +}; + +} // QtPrivate namespace /***************************************************************************** QDataStream inline functions @@ -238,6 +261,8 @@ inline QDataStream &QDataStream::operator<<(quint64 i) template QDataStream& operator>>(QDataStream& s, QList& l) { + QtPrivate::StreamStateSaver stateSaver(&s); + l.clear(); quint32 c; s >> c; @@ -246,10 +271,13 @@ QDataStream& operator>>(QDataStream& s, QList& l) { T t; s >> t; - l.append(t); - if (s.atEnd()) + if (s.status() != QDataStream::Ok) { + l.clear(); break; + } + l.append(t); } + return s; } @@ -265,6 +293,8 @@ QDataStream& operator<<(QDataStream& s, const QList& l) template QDataStream& operator>>(QDataStream& s, QLinkedList& l) { + QtPrivate::StreamStateSaver stateSaver(&s); + l.clear(); quint32 c; s >> c; @@ -272,10 +302,13 @@ QDataStream& operator>>(QDataStream& s, QLinkedList& l) { T t; s >> t; - l.append(t); - if (s.atEnd()) + if (s.status() != QDataStream::Ok) { + l.clear(); break; + } + l.append(t); } + return s; } @@ -292,6 +325,8 @@ QDataStream& operator<<(QDataStream& s, const QLinkedList& l) template QDataStream& operator>>(QDataStream& s, QVector& v) { + QtPrivate::StreamStateSaver stateSaver(&s); + v.clear(); quint32 c; s >> c; @@ -299,8 +334,13 @@ QDataStream& operator>>(QDataStream& s, QVector& v) for(quint32 i = 0; i < c; ++i) { T t; s >> t; + if (s.status() != QDataStream::Ok) { + v.clear(); + break; + } v[i] = t; } + return s; } @@ -316,16 +356,21 @@ QDataStream& operator<<(QDataStream& s, const QVector& v) template QDataStream &operator>>(QDataStream &in, QSet &set) { + QtPrivate::StreamStateSaver stateSaver(&in); + set.clear(); quint32 c; in >> c; for (quint32 i = 0; i < c; ++i) { T t; in >> t; - set << t; - if (in.atEnd()) + if (in.status() != QDataStream::Ok) { + set.clear(); break; + } + set << t; } + return in; } @@ -344,10 +389,9 @@ QDataStream& operator<<(QDataStream &out, const QSet &set) template Q_OUTOFLINE_TEMPLATE QDataStream &operator>>(QDataStream &in, QHash &hash) { - QDataStream::Status oldStatus = in.status(); - in.resetStatus(); - hash.clear(); + QtPrivate::StreamStateSaver stateSaver(&in); + hash.clear(); quint32 n; in >> n; @@ -363,10 +407,6 @@ Q_OUTOFLINE_TEMPLATE QDataStream &operator>>(QDataStream &in, QHash &has if (in.status() != QDataStream::Ok) hash.clear(); - if (oldStatus != QDataStream::Ok) { - in.resetStatus(); - in.setStatus(oldStatus); - } return in; } @@ -390,10 +430,9 @@ template Q_OUTOFLINE_TEMPLATE QDataStream &operator>>(QDataStream &in, QMap &map) #endif { - QDataStream::Status oldStatus = in.status(); - in.resetStatus(); - map.clear(); + QtPrivate::StreamStateSaver stateSaver(&in); + map.clear(); quint32 n; in >> n; @@ -409,10 +448,6 @@ Q_OUTOFLINE_TEMPLATE QDataStream &operator>>(QDataStream &in, QMap &ma } if (in.status() != QDataStream::Ok) map.clear(); - if (oldStatus != QDataStream::Ok) { - in.resetStatus(); - in.setStatus(oldStatus); - } return in; } diff --git a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp index ea4c557574..fefe08db30 100644 --- a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp @@ -2813,10 +2813,11 @@ void tst_QDataStream::status_QHash_QMap() MAP_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x01", 8), QDataStream::ReadPastEnd, QDataStream::ReadPastEnd, StringHash()); } -#define LIST_TEST(byteArray, expectedStatus, expectedList) \ +#define LIST_TEST(byteArray, initialStatus, expectedStatus, expectedList) \ { \ QByteArray ba = byteArray; \ QDataStream stream(&ba, QIODevice::ReadOnly); \ + stream.setStatus(initialStatus); \ stream >> list; \ QCOMPARE((int)stream.status(), (int)expectedStatus); \ QCOMPARE(list.size(), expectedList.size()); \ @@ -2828,6 +2829,7 @@ void tst_QDataStream::status_QHash_QMap() expectedLinkedList << expectedList.at(i); \ QByteArray ba = byteArray; \ QDataStream stream(&ba, QIODevice::ReadOnly); \ + stream.setStatus(initialStatus); \ stream >> linkedList; \ QCOMPARE((int)stream.status(), (int)expectedStatus); \ QCOMPARE(linkedList.size(), expectedLinkedList.size()); \ @@ -2839,6 +2841,7 @@ void tst_QDataStream::status_QHash_QMap() expectedVector << expectedList.at(i); \ QByteArray ba = byteArray; \ QDataStream stream(&ba, QIODevice::ReadOnly); \ + stream.setStatus(initialStatus); \ stream >> vector; \ QCOMPARE((int)stream.status(), (int)expectedStatus); \ QCOMPARE(vector.size(), expectedVector.size()); \ @@ -2854,8 +2857,49 @@ void tst_QDataStream::status_QLinkedList_QList_QVector() List list; Vector vector; - LIST_TEST(QByteArray(), QDataStream::ReadPastEnd, List()); - LIST_TEST(QByteArray("\x00\x00\x00\x00", 4), QDataStream::Ok, List()); + // ok + { + List listWithEmptyString; + listWithEmptyString.append(""); + + List someList; + someList.append("J"); + someList.append("MN"); + + LIST_TEST(QByteArray("\x00\x00\x00\x00", 4), QDataStream::Ok, QDataStream::Ok, List()); + LIST_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00", 8), QDataStream::Ok, QDataStream::Ok, listWithEmptyString); + LIST_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x02\x00J" + "\x00\x00\x00\x04\x00M\x00N", 18), QDataStream::Ok, QDataStream::Ok, someList); + } + + // past end + { + LIST_TEST(QByteArray(), QDataStream::Ok, QDataStream::ReadPastEnd, List()); + LIST_TEST(QByteArray("\x00", 1), QDataStream::Ok, QDataStream::ReadPastEnd, List()); + LIST_TEST(QByteArray("\x00\x00", 2), QDataStream::Ok, QDataStream::ReadPastEnd, List()); + LIST_TEST(QByteArray("\x00\x00\x00", 3), QDataStream::Ok, QDataStream::ReadPastEnd, List()); + LIST_TEST(QByteArray("\x00\x00\x00\x01", 4), QDataStream::Ok, QDataStream::ReadPastEnd, List()); + for (int i = 4; i < 12; ++i) { + LIST_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00", i), QDataStream::Ok, QDataStream::ReadPastEnd, List()); + } + } + + // corrupt data + { + LIST_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x01", 8), QDataStream::Ok, QDataStream::ReadCorruptData, List()); + LIST_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x01\x00J" + "\x00\x00\x00\x02\x00M\x00N", 18), QDataStream::Ok, QDataStream::ReadCorruptData, List()); + } + + // test the previously latched error status is not affected by reading + { + List listWithEmptyString; + listWithEmptyString.append(""); + + LIST_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00", 8), QDataStream::ReadPastEnd, QDataStream::ReadPastEnd, listWithEmptyString); + LIST_TEST(QByteArray("\x00\x00\x00\x01", 4), QDataStream::ReadCorruptData, QDataStream::ReadCorruptData, List()); + LIST_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x01", 8), QDataStream::ReadPastEnd, QDataStream::ReadPastEnd, List()); + } } void tst_QDataStream::streamToAndFromQByteArray() -- cgit v1.2.3 From d9b545152d8cddaa389256e869b994ecf3ce1119 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 17 Jun 2016 12:47:41 -0700 Subject: QFormLayout: Remove internal, unused functions Found by the Intel Compiler 17 Beta on Windows: qformlayout.cpp(68): error #177: function "::FixedColumnMatrix::addRow [with T=QFormLayoutItem *, NumColumns=2]" was declared but never referenced Change-Id: Ib57b52598e2f452985e9fffd1458f6a3c3a609dc Reviewed-by: Giuseppe D'Angelo --- src/widgets/kernel/qformlayout.cpp | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp index 9b346a2c50..d02cb7d6a9 100644 --- a/src/widgets/kernel/qformlayout.cpp +++ b/src/widgets/kernel/qformlayout.cpp @@ -65,12 +65,7 @@ public: T &operator()(int r, int c) { return m_storage[r * NumColumns + c]; } int rowCount() const { return m_storage.size() / NumColumns; } - void addRow(const T &value); void insertRow(int r, const T &value); - void removeRow(int r); - - bool find(const T &value, int *rowPtr, int *colPtr) const ; - int count(const T &value) const { return m_storage.count(value); } // Hmmpf.. Some things are faster that way. const Storage &storage() const { return m_storage; } @@ -81,13 +76,6 @@ private: Storage m_storage; }; -template -void FixedColumnMatrix::addRow(const T &value) -{ - for (int i = 0; i < NumColumns; ++i) - m_storage.append(value); -} - template void FixedColumnMatrix::insertRow(int r, const T &value) { @@ -96,22 +84,6 @@ void FixedColumnMatrix::insertRow(int r, const T &value) m_storage.insert(it, NumColumns, value); } -template -void FixedColumnMatrix::removeRow(int r) -{ - m_storage.remove(r * NumColumns, NumColumns); -} - -template -bool FixedColumnMatrix::find(const T &value, int *rowPtr, int *colPtr) const -{ - const int idx = m_storage.indexOf(value); - if (idx == -1) - return false; - storageIndexToPosition(idx, rowPtr, colPtr); - return true; -} - template void FixedColumnMatrix::storageIndexToPosition(int idx, int *rowPtr, int *colPtr) { -- cgit v1.2.3 From 840729a931a7d3fefbc4b4a8e01f8b1bd69a427e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 21 Jun 2016 14:30:25 -0700 Subject: QDateTime: use the more efficient currentMSecsSinceEpoch() ... instead of creating a QDateTime object. Change-Id: Ib57b52598e2f452985e9fffd145a36911de4fa9a Reviewed-by: Edward Welbourne --- examples/opengl/qopenglwindow/background_renderer.cpp | 2 +- src/corelib/tools/qtimezoneprivate_icu.cpp | 2 +- src/corelib/tools/qtimezoneprivate_mac.mm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/opengl/qopenglwindow/background_renderer.cpp b/examples/opengl/qopenglwindow/background_renderer.cpp index 296044a35a..d57198444e 100644 --- a/examples/opengl/qopenglwindow/background_renderer.cpp +++ b/examples/opengl/qopenglwindow/background_renderer.cpp @@ -180,7 +180,7 @@ void FragmentToy::draw(const QSize &windowSize) m_program->enableAttributeArray("vertexCoord"); m_vertex_buffer.release(); - m_program->setUniformValue("currentTime", (uint) QDateTime::currentDateTime().toMSecsSinceEpoch()); + m_program->setUniformValue("currentTime", (uint) QDateTime::currentMSecsSinceEpoch()); m_program->setUniformValue("windowSize", windowSize); QOpenGLContext::currentContext()->functions()->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); diff --git a/src/corelib/tools/qtimezoneprivate_icu.cpp b/src/corelib/tools/qtimezoneprivate_icu.cpp index a7036808db..c088fe7694 100644 --- a/src/corelib/tools/qtimezoneprivate_icu.cpp +++ b/src/corelib/tools/qtimezoneprivate_icu.cpp @@ -332,7 +332,7 @@ QString QIcuTimeZonePrivate::displayName(QTimeZone::TimeType timeType, { // Return standard offset format name as ICU C api doesn't support it yet if (nameType == QTimeZone::OffsetName) { - const Data nowData = data(QDateTime::currentDateTimeUtc().toMSecsSinceEpoch()); + const Data nowData = data(QDateTime::currentMSecsSinceEpoch()); // We can't use transitions reliably to find out right dst offset // Instead use dst offset api to try get it if needed if (timeType == QTimeZone::DaylightTime) diff --git a/src/corelib/tools/qtimezoneprivate_mac.mm b/src/corelib/tools/qtimezoneprivate_mac.mm index 3a665c2b00..a21a8fd56f 100644 --- a/src/corelib/tools/qtimezoneprivate_mac.mm +++ b/src/corelib/tools/qtimezoneprivate_mac.mm @@ -106,7 +106,7 @@ QString QMacTimeZonePrivate::displayName(QTimeZone::TimeType timeType, { // TODO Mac doesn't support OffsetName yet so use standard offset name if (nameType == QTimeZone::OffsetName) { - const Data nowData = data(QDateTime::currentDateTimeUtc().toMSecsSinceEpoch()); + const Data nowData = data(QDateTime::currentMSecsSinceEpoch()); // TODO Cheat for now, assume if has dst the offset if 1 hour if (timeType == QTimeZone::DaylightTime && hasDaylightTime()) return isoOffsetFormat(nowData.standardTimeOffset + 3600); -- cgit v1.2.3 From 1af4916e11c1251b2957a909f819678e9fd32feb Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 1 Jul 2016 13:49:46 +0200 Subject: QTime: restore Qt3 compatibility in the QDataStream operators A Qt5 program writing a null QTime() using setVersion(QDataStream::Qt_3_3), and then a Qt3 program reading that, would lead to a weird QTime, with isNull=false, isValid=false, hour=1193, minute=2, second=47, ms=295. This commit restores interoperability, by writing out the expected value (0) for a null QTime rather than the -1 value used by Qt4 and Qt5. Change-Id: Icde468a8f6fc9434ef7018296725819b44d672af Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetime.cpp | 14 +++++++++-- .../corelib/io/qdatastream/tst_qdatastream.cpp | 27 +++++++++++++++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index fb679e56c5..e6d0b97836 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -4759,7 +4759,12 @@ QDataStream &operator>>(QDataStream &in, QDate &date) QDataStream &operator<<(QDataStream &out, const QTime &time) { - return out << quint32(time.mds); + if (out.version() >= QDataStream::Qt_4_0) { + return out << quint32(time.mds); + } else { + // Qt3 had no support for reading -1, QTime() was valid and serialized as 0 + return out << quint32(time.isNull() ? 0 : time.mds); + } } /*! @@ -4774,7 +4779,12 @@ QDataStream &operator>>(QDataStream &in, QTime &time) { quint32 ds; in >> ds; - time.mds = int(ds); + if (in.version() >= QDataStream::Qt_4_0) { + time.mds = int(ds); + } else { + // Qt3 would write 0 for a null time + time.mds = (ds == 0) ? QTime::NullTime : int(ds); + } return in; } diff --git a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp index 86fd142036..76650ea9a4 100644 --- a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp @@ -1203,10 +1203,11 @@ static QTime qTimeData(int index) case 57: return QTime(23, 59, 59, 99); case 58: return QTime(23, 59, 59, 100); case 59: return QTime(23, 59, 59, 999); + case 60: return QTime(); } return QTime(0, 0, 0); } -#define MAX_QTIME_DATA 60 +#define MAX_QTIME_DATA 61 void tst_QDataStream::stream_QTime_data() { @@ -3081,6 +3082,30 @@ void tst_QDataStream::compatibility_Qt3() QVERIFY(in_palette.brush(QPalette::Button).style() == Qt::NoBrush); QVERIFY(in_palette.color(QPalette::Light) == Qt::green); } + // QTime() was serialized to (0, 0, 0, 0) in Qt3, not (0xFF, 0xFF, 0xFF, 0xFF) + // This is because in Qt3 a null time was valid, and there was no support for deserializing a value of -1. + { + QByteArray stream; + { + QDataStream out(&stream, QIODevice::WriteOnly); + out.setVersion(QDataStream::Qt_3_3); + out << QTime(); + } + QTime in_time; + { + QDataStream in(stream); + in.setVersion(QDataStream::Qt_3_3); + in >> in_time; + } + QVERIFY(in_time.isNull()); + + quint32 rawValue; + QDataStream in(stream); + in.setVersion(QDataStream::Qt_3_3); + in >> rawValue; + QCOMPARE(rawValue, quint32(0)); + } + } void tst_QDataStream::compatibility_Qt2() -- cgit v1.2.3 From 3d621af54be7b34e6cc6357b48c4d15f911937ee Mon Sep 17 00:00:00 2001 From: Urs Fleisch Date: Sun, 15 May 2016 16:56:40 +0200 Subject: xcb: Send also "text/plain" when a "text/uri-list" is dropped. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will allow dropping of files from Qt applications to applications like Skype, which only accept "text/plain", but not "text/uri-list" or "text/x-moz-url". Task-number: QTBUG-53238 Change-Id: I01bca5c8e20647cedfc9323f542ab07f0cc48658 Reviewed-by: Dmitry Shachnev Reviewed-by: Błażej Szczygieł Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbmime.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbmime.cpp b/src/plugins/platforms/xcb/qxcbmime.cpp index 7fea0688cc..cc90da385c 100644 --- a/src/plugins/platforms/xcb/qxcbmime.cpp +++ b/src/plugins/platforms/xcb/qxcbmime.cpp @@ -125,6 +125,11 @@ bool QXcbMime::mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeDa ret = true; } else if ((a == XCB_ATOM_PIXMAP || a == XCB_ATOM_BITMAP) && mimeData->hasImage()) { ret = true; + } else if (atomName == QLatin1String("text/plain") + && mimeData->hasFormat(QLatin1String("text/uri-list"))) { + // Return URLs also as plain text. + *data = QInternalMimeData::renderDataHelper(atomName, mimeData); + ret = true; } return ret; } @@ -143,8 +148,10 @@ QVector QXcbMime::mimeAtomsForFormat(QXcbConnection *connection, con } // special cases for uris - if (format == QLatin1String("text/uri-list")) + if (format == QLatin1String("text/uri-list")) { atoms.append(connection->internAtom("text/x-moz-url")); + atoms.append(connection->internAtom("text/plain")); + } //special cases for images if (format == QLatin1String("image/ppm")) -- cgit v1.2.3 From 27df6cb32d42c0a4475fc2d11b4c9d53d19fe394 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 27 Jun 2016 14:12:54 +0200 Subject: Fix the QMainWindow context menu when there are floating tabs If QMainWindow::GroupedDragging is enabled and there are QDockWidgetGroupWindow, we should still show actions for these QDockWidgets in the context menu Addresses point 4. of QTBUG-52108 Task-number: QTBUG-52108 Change-Id: I11ae401c4fe15e213b0f26e7579634e2062e953c Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qmainwindow.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp index 1698ca1519..7a9a077e5f 100644 --- a/src/widgets/widgets/qmainwindow.cpp +++ b/src/widgets/widgets/qmainwindow.cpp @@ -1717,10 +1717,20 @@ QMenu *QMainWindow::createPopupMenu() menu = new QMenu(this); for (int i = 0; i < dockwidgets.size(); ++i) { QDockWidget *dockWidget = dockwidgets.at(i); - if (dockWidget->parentWidget() == this - && !d->layout->layoutState.dockAreaLayout.indexOf(dockWidget).isEmpty()) { - menu->addAction(dockwidgets.at(i)->toggleViewAction()); + // filter to find out if we own this QDockWidget + if (dockWidget->parentWidget() == this) { + if (d->layout->layoutState.dockAreaLayout.indexOf(dockWidget).isEmpty()) + continue; + } else if (QDockWidgetGroupWindow *dwgw = + qobject_cast(dockWidget->parentWidget())) { + if (dwgw->parentWidget() != this) + continue; + if (dwgw->layoutInfo()->indexOf(dockWidget).isEmpty()) + continue; + } else { + continue; } + menu->addAction(dockwidgets.at(i)->toggleViewAction()); } menu->addSeparator(); } -- cgit v1.2.3 From 9cb8ca2b5532c7a4bfb175cbe16fd5680d913822 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 24 Jun 2016 15:49:28 +0200 Subject: Allow to drag a QDockWidgetGroupWindow into one of its QDockWidget This fixes the 2. of QTBUG-52108 Change-Id: Id887f470c7822f6b264d6b739e8658d9809f6609 Task-numer: QTBUG-52108 Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qmainwindowlayout.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index 8dc12d853e..6b247d8d11 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -2366,13 +2366,10 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos) QWidget *w = qobject_cast(c); if (!w) continue; - if (w == widget) - continue; - if (!w->isTopLevel() || !w->isVisible() || w->isMinimized()) - continue; if (!qobject_cast(w) && !qobject_cast(w)) continue; - candidates << w; + if (w != widget && w->isTopLevel() && w->isVisible() && !w->isMinimized()) + candidates << w; if (QDockWidgetGroupWindow *group = qobject_cast(w)) { // Sometimes, there are floating QDockWidget that have a QDockWidgetGroupWindow as a parent. foreach (QObject *c, group->children()) { -- cgit v1.2.3 From cf9b445ed471451cd581962887c6fd503cd2bf25 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 30 May 2016 10:30:35 -0300 Subject: Fix the naming of an LLVM tool in common/clang.conf Probably was copied from the gcc equivalent. Change-Id: I87e17314d8b24ae983b1fffd14535b9d7f616a1b Reviewed-by: Oswald Buddenhagen Reviewed-by: Olivier Goffart (Woboq GmbH) --- mkspecs/common/clang.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf index ee9c1b8371..e003b947aa 100644 --- a/mkspecs/common/clang.conf +++ b/mkspecs/common/clang.conf @@ -40,5 +40,5 @@ QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG # Wrapper tools that understand .o/.a files with LLVM bytecode instead of machine code QMAKE_AR_LTCG = llvm-ar cqs -QMAKE_NM_LTCG = gcc-nm -P +QMAKE_NM_LTCG = llvm-nm -P QMAKE_RANLIB_LTCG = true # No need to run, since llvm-ar has "s" -- cgit v1.2.3 From 4f3eb6617331ba2634206064512ae68a4fbd793e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 30 Jun 2016 15:48:52 -0700 Subject: QUrl: Test that we do correctly accept valid schemes ... and reject invalid ones. There was one error: we accepted schemes starting with pluses, dashes and dots. Change-Id: Ie585843cfb684bc3b6e3fffd145cfe12227ec4ad Reviewed-by: David Faure --- src/corelib/io/qurl.cpp | 10 +- tests/auto/corelib/io/qurl/tst_qurl.cpp | 162 +++++++++++++++++++------------- 2 files changed, 101 insertions(+), 71 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index fb2f4ba918..2672de24f2 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -978,10 +978,12 @@ inline bool QUrlPrivate::setScheme(const QString &value, int len, bool doSetErro needsLowercasing = i; continue; } - if (p[i] >= '0' && p[i] <= '9' && i > 0) - continue; - if (p[i] == '+' || p[i] == '-' || p[i] == '.') - continue; + if (i) { + if (p[i] >= '0' && p[i] <= '9') + continue; + if (p[i] == '+' || p[i] == '-' || p[i] == '.') + continue; + } // found something else // don't call setError needlessly: diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index ef210d4a64..eb29646053 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -125,7 +125,8 @@ private slots: void isValid(); void schemeValidator_data(); void schemeValidator(); - void invalidSchemeValidator(); + void setScheme_data(); + void setScheme(); void strictParser_data(); void strictParser(); void tolerantParser(); @@ -2082,87 +2083,114 @@ void tst_QUrl::isValid() void tst_QUrl::schemeValidator_data() { - QTest::addColumn("encodedUrl"); + QTest::addColumn("input"); QTest::addColumn("result"); - QTest::addColumn("toString"); - - QTest::newRow("empty") << QByteArray() << false << QString(); - - // ftp - QTest::newRow("ftp:") << QByteArray("ftp:") << true << QString("ftp:"); - QTest::newRow("ftp://ftp.qt-project.org") - << QByteArray("ftp://ftp.qt-project.org") - << true << QString("ftp://ftp.qt-project.org"); - QTest::newRow("ftp://ftp.qt-project.org/") - << QByteArray("ftp://ftp.qt-project.org/") - << true << QString("ftp://ftp.qt-project.org/"); - QTest::newRow("ftp:/index.html") - << QByteArray("ftp:/index.html") - << false << QString(); - - // mailto - QTest::newRow("mailto:") << QByteArray("mailto:") << true << QString("mailto:"); - QTest::newRow("mailto://smtp.trolltech.com/ole@bull.name") - << QByteArray("mailto://smtp.trolltech.com/ole@bull.name") << false << QString(); - QTest::newRow("mailto:") << QByteArray("mailto:") << true << QString("mailto:"); - QTest::newRow("mailto:ole@bull.name") - << QByteArray("mailto:ole@bull.name") << true << QString("mailto:ole@bull.name"); + QTest::addColumn("scheme"); - // file - QTest::newRow("file:") << QByteArray("file:/etc/passwd") << true << QString("file:///etc/passwd"); + // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + + QTest::newRow("empty") << QString() << false << QString(); + + // uncontroversial ones + QTest::newRow("ftp") << "ftp://ftp.example.com/" << true << "ftp"; + QTest::newRow("http") << "http://www.example.com/" << true << "http"; + QTest::newRow("mailto") << "mailto:smith@example.com" << true << "mailto"; + QTest::newRow("file-1slash") << "file:/etc/passwd" << true << "file"; + QTest::newRow("file-2slashes") << "file://server/etc/passwd" << true << "file"; + QTest::newRow("file-3slashes") << "file:///etc/passwd" << true << "file"; + + QTest::newRow("mailto+subject") << "mailto:smith@example.com?subject=Hello%20World" << true << "mailto"; + QTest::newRow("mailto+host") << "mailto://smtp.example.com/smith@example.com" << true << "mailto"; + + // valid, but unexpected + QTest::newRow("ftp-nohost") << "ftp:/etc/passwd" << true << "ftp"; + QTest::newRow("http-nohost") << "http:/etc/passwd" << true << "http"; + QTest::newRow("mailto-nomail") << "mailto://smtp.example.com" << true << "mailto"; + + // schemes with numbers + QTest::newRow("digits") << "proto2://" << true << "proto2"; + + // schemes with dots, dashes, and pluses + QTest::newRow("svn+ssh") << "svn+ssh://svn.example.com" << true << "svn+ssh"; + QTest::newRow("withdash") << "svn-ssh://svn.example.com" << true << "svn-ssh"; + QTest::newRow("withdots") << "org.qt-project://qt-project.org" << true << "org.qt-project"; + + // lowercasing + QTest::newRow("FTP") << "FTP://ftp.example.com/" << true << "ftp"; + QTest::newRow("HTTP") << "HTTP://www.example.com/" << true << "http"; + QTest::newRow("MAILTO") << "MAILTO:smith@example.com" << true << "mailto"; + QTest::newRow("FILE") << "FILE:/etc/passwd" << true << "file"; + QTest::newRow("SVN+SSH") << "SVN+SSH://svn.example.com" << true << "svn+ssh"; + QTest::newRow("WITHDASH") << "SVN-SSH://svn.example.com" << true << "svn-ssh"; + QTest::newRow("WITHDOTS") << "ORG.QT-PROJECT://qt-project.org" << true << "org.qt-project"; + + // invalid entries + QTest::newRow("start-digit") << "1http://example.com" << false << "1http"; + QTest::newRow("start-plus") << "+ssh://user@example.com" << false << "+ssh"; + QTest::newRow("start-dot") << ".org.example:///" << false << ".org.example"; + QTest::newRow("with-space") << "a b://" << false << "a b"; + QTest::newRow("with-non-ascii") << "\304\245\305\243\305\245\321\200://example.com" << false << "\304\245\305\243\305\245\321\200"; + QTest::newRow("with-control1") << "http\1://example.com" << false << "http\1"; + QTest::newRow("with-control127") << "http\177://example.com" << false << "http\177"; + QTest::newRow("with-null") << QString::fromLatin1("http\0://example.com", 19) << false << QString::fromLatin1("http\0", 5); + + QTest::newRow("percent-encoded") << "%68%74%%74%70://example.com" << false << "%68%74%%74%70"; + + static const char controls[] = "!\"$&'()*,;<=>[\\]^_`{|}~"; + for (size_t i = 0; i < sizeof(controls) - 1; ++i) + QTest::newRow(("with-" + QByteArray(1, controls[i])).constData()) + << QString("pre%1post://example.com/").arg(QLatin1Char(controls[i])) + << false << QString("pre%1post").arg(QLatin1Char(controls[i])); } void tst_QUrl::schemeValidator() { - QFETCH(QByteArray, encodedUrl); + QFETCH(QString, input); QFETCH(bool, result); - QFETCH(QString, toString); - QUrl url = QUrl::fromEncoded(encodedUrl); - QEXPECT_FAIL("ftp:/index.html", "high-level URL validation not reimplemented yet", Abort); - QEXPECT_FAIL("mailto://smtp.trolltech.com/ole@bull.name", "high-level URL validation not reimplemented yet", Abort); + QUrl url(input); QCOMPARE(url.isValid(), result); - if (!result) - QVERIFY(url.toString().isEmpty()); -} + if (result) { + QFETCH(QString, scheme); + QCOMPARE(url.scheme(), scheme); -void tst_QUrl::invalidSchemeValidator() -{ - // test that if scheme does not start with an ALPHA, QUrl::isValid() returns false - { - QUrl url("1http://qt-project.org"); - QVERIFY(url.scheme().isEmpty()); - QVERIFY(url.path().startsWith("1http")); - } - { - QUrl url("http://qt-project.org"); - url.setScheme("111http://qt-project.org"); - QCOMPARE(url.isValid(), false); - QVERIFY(url.toString().isEmpty()); - } - // non-ALPHA character at other positions in the scheme are ok - { - QUrl url("ht111tp://qt-project.org", QUrl::StrictMode); + // reconstruct with just the scheme: + url.setUrl(scheme + ':'); QVERIFY(url.isValid()); - QCOMPARE(url.scheme(), QString("ht111tp")); - QVERIFY(!url.toString().isEmpty()); - } - { - QUrl url("http://qt-project.org"); - url.setScheme("ht123tp://qt-project.org"); - QVERIFY(!url.isValid()); + QCOMPARE(url.scheme(), scheme); + } else { QVERIFY(url.toString().isEmpty()); - url.setScheme("http"); - QVERIFY(url.isValid()); - QVERIFY(!url.toString().isEmpty()); - } - { - QUrl url = QUrl::fromEncoded("ht321tp://qt-project.org", QUrl::StrictMode); - QVERIFY(url.isValid()); - QVERIFY(!url.toString().isEmpty()); } } +void tst_QUrl::setScheme_data() +{ + schemeValidator_data(); + + // a couple more which wouldn't work in parsing a full URL + QTest::newRow("with-slash") << QString() << false << "http/"; + QTest::newRow("with-question") << QString() << false << "http?"; + QTest::newRow("with-hash") << QString() << false << "http#"; +} + +void tst_QUrl::setScheme() +{ + QFETCH(QString, scheme); + QFETCH(bool, result); + QString expectedScheme; + if (result) + expectedScheme = scheme; + + QUrl url; + url.setScheme(scheme); + QCOMPARE(url.isValid(), result); + QCOMPARE(url.scheme(), expectedScheme); + + url.setScheme(scheme.toUpper()); + QCOMPARE(url.isValid(), result); + QCOMPARE(url.scheme(), expectedScheme); +} + void tst_QUrl::strictParser_data() { QTest::addColumn("input"); -- cgit v1.2.3 From 946c1a578a7c1e6acc95ef8095fa8a6ff026334b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 14 Jun 2016 07:49:13 -0700 Subject: Fix build: ftok(3) requires sys/ipc.h Task-number: QTBUG-54069 Change-Id: Ib57b52598e2f452985e9fffd1457fa9c7ad3bac0 Reviewed-by: Giuseppe D'Angelo --- src/corelib/kernel/qcore_unix_p.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 05711354ff..07725b8cd2 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -72,6 +72,10 @@ #include #include +#if !defined(QT_POSIX_IPC) && !defined(QT_NO_SHAREDMEMORY) && !defined(Q_OS_ANDROID) +# include +#endif + #if defined(Q_OS_VXWORKS) # include #endif -- cgit v1.2.3 From 3b5db8f3a6663fd65d74da875a6d22c430c2e4f7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 1 Jul 2016 17:49:26 -0700 Subject: Examples: Fix stringification of the Qt version (QT_VERSION % 0xffff00) is useless for now, as QT_VERSION < 0x1000000 (for now). The author of this code probably meant to use bitwise-AND. But even that is unnecessary as the right shift discards the lower 8 bits anyway. Change-Id: Ie585843cfb684bc3b6e3fffd145d533b05288dfc Reviewed-by: Olivier Goffart (Woboq GmbH) --- examples/network/torrent/connectionmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/network/torrent/connectionmanager.cpp b/examples/network/torrent/connectionmanager.cpp index fa10251749..0e15c226b8 100644 --- a/examples/network/torrent/connectionmanager.cpp +++ b/examples/network/torrent/connectionmanager.cpp @@ -78,7 +78,7 @@ QByteArray ConnectionManager::clientId() const // Generate peer id int startupTime = int(QDateTime::currentDateTime().toTime_t()); - id += QString::asprintf("-QT%04x-", (QT_VERSION % 0xffff00) >> 8).toLatin1(); + id += QString::asprintf("-QT%04x-", QT_VERSION >> 8).toLatin1(); id += QByteArray::number(startupTime, 10); id += QByteArray(20 - id.size(), '-'); } -- cgit v1.2.3 From daade9b90dd39aa844cb683af776b802b0786ba7 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 16 Jun 2016 11:56:42 +0200 Subject: QEventLoop: better describe the exception safety of Qt 1) In general it's unsafe to let exceptions propagate through Qt code, so document that. 2) Add a note that overriding notify() makes sense only in Qt 5, in Qt 6 it's going away. 3) The advice applies also to applications not using QApplication, but just QCoreApplication. Change-Id: I4f6e74c53da757faf2eeaa9de226ceba55c52536 Reviewed-by: Thiago Macieira Reviewed-by: Martin Smith --- src/corelib/kernel/qeventloop.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp index dca25ce968..0ee677d213 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -182,8 +182,10 @@ int QEventLoop::exec(ProcessEventsFlags flags) { if (exceptionCaught) { qWarning("Qt has caught an exception thrown from an event handler. Throwing\n" - "exceptions from an event handler is not supported in Qt. You must\n" - "reimplement QApplication::notify() and catch all exceptions there.\n"); + "exceptions from an event handler is not supported in Qt.\n" + "You must not let any exception whatsoever propagate through Qt code.\n" + "If that is not possible, in Qt 5 you must at least reimplement\n" + "QCoreApplication::notify() and catch all exceptions there.\n"); } locker.relock(); QEventLoop *eventLoop = d->threadData->eventLoops.pop(); -- cgit v1.2.3 From b7744e0b05255fc468db2af215ba94eca4b7757b Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Fri, 1 Jul 2016 10:33:43 +0200 Subject: Replace LLINDEX macro not present on all BSDs with the code FreeBSD < 10 doesn't have the LLINDEX macro either in net/if_dl.h, so besides OpenBSD yet another condition to declare the LLINDEX macro for systems where it isn't present does make it more complicated than replacing its usage with the actual code. Change-Id: I7e8ef3e265564526e05ec3115f9fa765d399f045 Reviewed-by: Thiago Macieira --- src/network/socket/qnativesocketengine_unix.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index e92123e10c..5dfc6480da 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -906,10 +906,7 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_RECVIF && cmsgptr->cmsg_len >= CMSG_LEN(sizeof(sockaddr_dl))) { sockaddr_dl *sdl = reinterpret_cast(CMSG_DATA(cmsgptr)); -# if defined(Q_OS_OPENBSD) -# define LLINDEX(s) ((s)->sdl_index) -# endif - header->ifindex = LLINDEX(sdl); + header->ifindex = sdl->sdl_index; } # endif #endif -- cgit v1.2.3 From 6583720aa4503fce16b44cce7b8d939058abf000 Mon Sep 17 00:00:00 2001 From: Kevin Funk Date: Mon, 4 Jul 2016 19:29:30 +0200 Subject: Revert "CMake: Add imported target for qdoc." This reverts commit dc0ae02ebc8e221f952829230c0301a718a6f10b. qdoc is a binary built inside the qttools repository, thus it should be added to the respective ConfigExtras.cmake.in there instead. Task-number: QTBUG-54446 Change-Id: I182e5889af164a89c68226a91abc4d9962a508ea Reviewed-by: Volker Krause Reviewed-by: Oswald Buddenhagen --- src/corelib/Qt5CoreConfigExtras.cmake.in | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index f492148a50..a5ed8b2ea3 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -46,21 +46,6 @@ if (NOT TARGET Qt5::rcc) ) endif() -if (NOT TARGET Qt5::qdoc) - add_executable(Qt5::qdoc IMPORTED) - -!!IF isEmpty(CMAKE_BIN_DIR_IS_ABSOLUTE) - set(imported_location \"${_qt5Core_install_prefix}/$${CMAKE_BIN_DIR}qdoc$$CMAKE_BIN_SUFFIX\") -!!ELSE - set(imported_location \"$${CMAKE_BIN_DIR}qdoc$$CMAKE_BIN_SUFFIX\") -!!ENDIF - _qt5_Core_check_file_exists(${imported_location}) - - set_target_properties(Qt5::qdoc PROPERTIES - IMPORTED_LOCATION ${imported_location} - ) -endif() - set(Qt5Core_QMAKE_EXECUTABLE Qt5::qmake) set(Qt5Core_MOC_EXECUTABLE Qt5::moc) set(Qt5Core_RCC_EXECUTABLE Qt5::rcc) -- cgit v1.2.3 From a9613ba3f16cd960e222a37d83ba4cbb6810a6d8 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 5 Jul 2016 09:31:44 +0200 Subject: Testlib: generate_expected_output.py: Run in C locale Otherwise, float numbers are formatted using a decimal comma in German, causing huge diffs and failures. Change-Id: Icd85a293d0564cac6be244eb0793611920d0c89c Reviewed-by: Edward Welbourne --- tests/auto/testlib/selftests/generate_expected_output.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/testlib/selftests/generate_expected_output.py b/tests/auto/testlib/selftests/generate_expected_output.py index 83c617fee5..b917dacc78 100755 --- a/tests/auto/testlib/selftests/generate_expected_output.py +++ b/tests/auto/testlib/selftests/generate_expected_output.py @@ -109,6 +109,7 @@ if isWindows: exit() tests = sys.argv[1:] +os.environ['LC_ALL'] = 'C' if len(tests) == 0: tests = subdirs() print("Generating " + str(len(tests)) + " test results for: " + qtver + " in: " + rootPath) -- cgit v1.2.3 From e7d476031474786a2e11ff6d3f9af0d5244f19d8 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 5 Jul 2016 09:41:15 +0200 Subject: Testlib: Format QRegion in QCOMPARE Output regions as a compact list of rectangles: QRegion(2 rectangles, 50x200+100+200, 200x50+10+10) Change-Id: I62e42bd30897a1d31b28e0cbd6afe7fa8ecf2664 Reviewed-by: Edward Welbourne --- src/testlib/qtest_gui.h | 34 ++++++++++ .../auto/testlib/selftests/cmptest/tst_cmptest.cpp | 25 +++++++ .../testlib/selftests/expected_cmptest.lightxml | 77 ++++++++++++++-------- .../testlib/selftests/expected_cmptest.teamcity | 66 +++++++++++-------- tests/auto/testlib/selftests/expected_cmptest.txt | 68 +++++++++++-------- tests/auto/testlib/selftests/expected_cmptest.xml | 77 ++++++++++++++-------- .../testlib/selftests/expected_cmptest.xunitxml | 10 ++- 7 files changed, 243 insertions(+), 114 deletions(-) diff --git a/src/testlib/qtest_gui.h b/src/testlib/qtest_gui.h index 5027aea732..d0d56e7bd0 100644 --- a/src/testlib/qtest_gui.h +++ b/src/testlib/qtest_gui.h @@ -58,6 +58,7 @@ #include #include #include +#include #ifdef QT_WIDGETS_LIB #include @@ -82,6 +83,39 @@ template<> inline char *toString(const QColor &color) return qstrdup(color.name().toLocal8Bit().constData()); } +template<> inline char *toString(const QRegion ®ion) +{ + QByteArray result = "QRegion("; + if (region.isNull()) { + result += "null"; + } else if (region.isEmpty()) { + result += "empty"; + } else { + const QVector &rects = region.rects(); + const int rectCount = rects.size(); + if (rectCount > 1) { + result += QByteArray::number(rectCount); + result += " rectangles, "; + } + for (int i = 0; i < rectCount; ++i) { + if (i) + result += ", "; + const QRect &r = rects.at(i); + result += QByteArray::number(r.width()); + result += 'x'; + result += QByteArray::number(r.height()); + if (r.x() >= 0) + result += '+'; + result += QByteArray::number(r.x()); + if (r.y() >= 0) + result += '+'; + result += QByteArray::number(r.y()); + } + } + result += ')'; + return qstrdup(result.constData()); +} + inline bool qCompare(QIcon const &t1, QIcon const &t2, const char *actual, const char *expected, const char *file, int line) { diff --git a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp index c3229b495e..3586b7f420 100644 --- a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp +++ b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp @@ -141,6 +141,8 @@ private slots: void compareQPixmaps_data(); void compareQImages(); void compareQImages_data(); + void compareQRegion_data(); + void compareQRegion(); #endif void verify(); void verify2(); @@ -409,6 +411,29 @@ void tst_Cmptest::compareQImages() QCOMPARE(opA, opB); } + +void tst_Cmptest::compareQRegion_data() +{ + QTest::addColumn("rA"); + QTest::addColumn("rB"); + const QRect rect1(QPoint(10, 10), QSize(200, 50)); + const QRegion region1(rect1); + QRegion listRegion2; + const QVector list2 = QVector() << QRect(QPoint(100, 200), QSize(50, 200)) << rect1; + listRegion2.setRects(list2.constData(), list2.size()); + QTest::newRow("equal-empty") << QRegion() << QRegion(); + QTest::newRow("1-empty") << region1 << QRegion(); + QTest::newRow("equal") << region1 << region1; + QTest::newRow("different lists") << region1 << listRegion2; +} + +void tst_Cmptest::compareQRegion() +{ + QFETCH(QRegion, rA); + QFETCH(QRegion, rB); + + QCOMPARE(rA, rB); +} #endif // QT_GUI_LIB static int opaqueFunc() diff --git a/tests/auto/testlib/selftests/expected_cmptest.lightxml b/tests/auto/testlib/selftests/expected_cmptest.lightxml index dc4a8a290e..a66413dfa0 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.lightxml +++ b/tests/auto/testlib/selftests/expected_cmptest.lightxml @@ -8,13 +8,13 @@ - + - + @@ -22,7 +22,7 @@ - + @@ -38,7 +38,7 @@ - + - + - + - + ) @@ -74,31 +74,31 @@ - + - + - + - + - + - + @@ -115,7 +115,7 @@ - + @@ -123,7 +123,7 @@ - + @@ -134,13 +134,13 @@ - + - + - + - + @@ -165,13 +165,13 @@ - + - + - + - + - + + + + + + + + + + + + + + + + + + - + - + - + - + diff --git a/tests/auto/testlib/selftests/expected_cmptest.teamcity b/tests/auto/testlib/selftests/expected_cmptest.teamcity index 8bcbfc50a9..925acb37fe 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.teamcity +++ b/tests/auto/testlib/selftests/expected_cmptest.teamcity @@ -2,106 +2,116 @@ ##teamcity[testStarted name='initTestCase()'] ##teamcity[testFinished name='initTestCase()'] ##teamcity[testStarted name='compare_unregistered_enums()'] -##teamcity[testFailed name='compare_unregistered_enums()' message='Failure! |[Loc: tst_cmptest.cpp(156)|]' details='Compared values are not the same'] +##teamcity[testFailed name='compare_unregistered_enums()' message='Failure! |[Loc: tst_cmptest.cpp(158)|]' details='Compared values are not the same'] ##teamcity[testFinished name='compare_unregistered_enums()'] ##teamcity[testStarted name='compare_registered_enums()'] -##teamcity[testFailed name='compare_registered_enums()' message='Failure! |[Loc: tst_cmptest.cpp(162)|]' details='Compared values are not the same|n Actual (Qt::Monday): Monday|n Expected (Qt::Sunday): Sunday'] +##teamcity[testFailed name='compare_registered_enums()' message='Failure! |[Loc: tst_cmptest.cpp(165)|]' details='Compared values are not the same|n Actual (Qt::Monday): Monday|n Expected (Qt::Sunday): Sunday'] ##teamcity[testFinished name='compare_registered_enums()'] ##teamcity[testStarted name='compare_class_enums()'] -##teamcity[testFailed name='compare_class_enums()' message='Failure! |[Loc: tst_cmptest.cpp(168)|]' details='Compared values are not the same|n Actual (MyClassEnum::MyClassEnumValue1): MyClassEnumValue1|n Expected (MyClassEnum::MyClassEnumValue2): MyClassEnumValue2'] +##teamcity[testFailed name='compare_class_enums()' message='Failure! |[Loc: tst_cmptest.cpp(171)|]' details='Compared values are not the same|n Actual (MyClassEnum::MyClassEnumValue1): MyClassEnumValue1|n Expected (MyClassEnum::MyClassEnumValue2): MyClassEnumValue2'] ##teamcity[testFinished name='compare_class_enums()'] ##teamcity[testStarted name='compare_boolfuncs()'] ##teamcity[testFinished name='compare_boolfuncs()'] ##teamcity[testStarted name='compare_pointerfuncs()'] ##teamcity[testFinished name='compare_pointerfuncs()'] ##teamcity[testStarted name='compare_tostring(int, string)'] -##teamcity[testFailed name='compare_tostring(int, string)' message='Failure! |[Loc: tst_cmptest.cpp(239)|]' details='Compared values are not the same|n Actual (actual) : QVariant(int,123)|n Expected (expected): QVariant(QString,hi)'] +##teamcity[testFailed name='compare_tostring(int, string)' message='Failure! |[Loc: tst_cmptest.cpp(242)|]' details='Compared values are not the same|n Actual (actual) : QVariant(int,123)|n Expected (expected): QVariant(QString,hi)'] ##teamcity[testFinished name='compare_tostring(int, string)'] ##teamcity[testStarted name='compare_tostring(both invalid)'] ##teamcity[testFinished name='compare_tostring(both invalid)'] ##teamcity[testStarted name='compare_tostring(null hash, invalid)'] -##teamcity[testFailed name='compare_tostring(null hash, invalid)' message='Failure! |[Loc: tst_cmptest.cpp(239)|]' details='Compared values are not the same|n Actual (actual) : QVariant(QVariantHash)|n Expected (expected): QVariant()'] +##teamcity[testFailed name='compare_tostring(null hash, invalid)' message='Failure! |[Loc: tst_cmptest.cpp(242)|]' details='Compared values are not the same|n Actual (actual) : QVariant(QVariantHash)|n Expected (expected): QVariant()'] ##teamcity[testFinished name='compare_tostring(null hash, invalid)'] ##teamcity[testStarted name='compare_tostring(string, null user type)'] -##teamcity[testFailed name='compare_tostring(string, null user type)' message='Failure! |[Loc: tst_cmptest.cpp(239)|]' details='Compared values are not the same|n Actual (actual) : QVariant(QString,A simple string)|n Expected (expected): QVariant(PhonyClass)'] +##teamcity[testFailed name='compare_tostring(string, null user type)' message='Failure! |[Loc: tst_cmptest.cpp(242)|]' details='Compared values are not the same|n Actual (actual) : QVariant(QString,A simple string)|n Expected (expected): QVariant(PhonyClass)'] ##teamcity[testFinished name='compare_tostring(string, null user type)'] ##teamcity[testStarted name='compare_tostring(both non-null user type)'] -##teamcity[testFailed name='compare_tostring(both non-null user type)' message='Failure! |[Loc: tst_cmptest.cpp(239)|]' details='Compared values are not the same|n Actual (actual) : QVariant(PhonyClass,)|n Expected (expected): QVariant(PhonyClass,)'] +##teamcity[testFailed name='compare_tostring(both non-null user type)' message='Failure! |[Loc: tst_cmptest.cpp(242)|]' details='Compared values are not the same|n Actual (actual) : QVariant(PhonyClass,)|n Expected (expected): QVariant(PhonyClass,)'] ##teamcity[testFinished name='compare_tostring(both non-null user type)'] ##teamcity[testStarted name='compareQStringLists(empty lists)'] ##teamcity[testFinished name='compareQStringLists(empty lists)'] ##teamcity[testStarted name='compareQStringLists(equal lists)'] ##teamcity[testFinished name='compareQStringLists(equal lists)'] ##teamcity[testStarted name='compareQStringLists(last item different)'] -##teamcity[testFailed name='compareQStringLists(last item different)' message='Failure! |[Loc: tst_cmptest.cpp(333)|]' details='Compared lists differ at index 2.|n Actual (opA): "string3"|n Expected (opB): "DIFFERS"'] +##teamcity[testFailed name='compareQStringLists(last item different)' message='Failure! |[Loc: tst_cmptest.cpp(336)|]' details='Compared lists differ at index 2.|n Actual (opA): "string3"|n Expected (opB): "DIFFERS"'] ##teamcity[testFinished name='compareQStringLists(last item different)'] ##teamcity[testStarted name='compareQStringLists(second-last item different)'] -##teamcity[testFailed name='compareQStringLists(second-last item different)' message='Failure! |[Loc: tst_cmptest.cpp(333)|]' details='Compared lists differ at index 2.|n Actual (opA): "string3"|n Expected (opB): "DIFFERS"'] +##teamcity[testFailed name='compareQStringLists(second-last item different)' message='Failure! |[Loc: tst_cmptest.cpp(336)|]' details='Compared lists differ at index 2.|n Actual (opA): "string3"|n Expected (opB): "DIFFERS"'] ##teamcity[testFinished name='compareQStringLists(second-last item different)'] ##teamcity[testStarted name='compareQStringLists(prefix)'] -##teamcity[testFailed name='compareQStringLists(prefix)' message='Failure! |[Loc: tst_cmptest.cpp(333)|]' details='Compared lists have different sizes.|n Actual (opA) size: 2|n Expected (opB) size: 1'] +##teamcity[testFailed name='compareQStringLists(prefix)' message='Failure! |[Loc: tst_cmptest.cpp(336)|]' details='Compared lists have different sizes.|n Actual (opA) size: 2|n Expected (opB) size: 1'] ##teamcity[testFinished name='compareQStringLists(prefix)'] ##teamcity[testStarted name='compareQStringLists(short list second)'] -##teamcity[testFailed name='compareQStringLists(short list second)' message='Failure! |[Loc: tst_cmptest.cpp(333)|]' details='Compared lists have different sizes.|n Actual (opA) size: 12|n Expected (opB) size: 1'] +##teamcity[testFailed name='compareQStringLists(short list second)' message='Failure! |[Loc: tst_cmptest.cpp(336)|]' details='Compared lists have different sizes.|n Actual (opA) size: 12|n Expected (opB) size: 1'] ##teamcity[testFinished name='compareQStringLists(short list second)'] ##teamcity[testStarted name='compareQStringLists(short list first)'] -##teamcity[testFailed name='compareQStringLists(short list first)' message='Failure! |[Loc: tst_cmptest.cpp(333)|]' details='Compared lists have different sizes.|n Actual (opA) size: 1|n Expected (opB) size: 12'] +##teamcity[testFailed name='compareQStringLists(short list first)' message='Failure! |[Loc: tst_cmptest.cpp(336)|]' details='Compared lists have different sizes.|n Actual (opA) size: 1|n Expected (opB) size: 12'] ##teamcity[testFinished name='compareQStringLists(short list first)'] ##teamcity[testStarted name='compareQListInt()'] -##teamcity[testFailed name='compareQListInt()' message='Failure! |[Loc: tst_cmptest.cpp(340)|]' details='Compared lists differ at index 2.|n Actual (int1): 3|n Expected (int2): 4'] +##teamcity[testFailed name='compareQListInt()' message='Failure! |[Loc: tst_cmptest.cpp(343)|]' details='Compared lists differ at index 2.|n Actual (int1): 3|n Expected (int2): 4'] ##teamcity[testFinished name='compareQListInt()'] ##teamcity[testStarted name='compareQListDouble()'] -##teamcity[testFailed name='compareQListDouble()' message='Failure! |[Loc: tst_cmptest.cpp(347)|]' details='Compared lists differ at index 0.|n Actual (double1): 1.5|n Expected (double2): 1'] +##teamcity[testFailed name='compareQListDouble()' message='Failure! |[Loc: tst_cmptest.cpp(350)|]' details='Compared lists differ at index 0.|n Actual (double1): 1.5|n Expected (double2): 1'] ##teamcity[testFinished name='compareQListDouble()'] ##teamcity[testStarted name='compareQColor()'] -##teamcity[testFailed name='compareQColor()' message='Failure! |[Loc: tst_cmptest.cpp(357)|]' details='Compared values are not the same|n Actual (yellow): #ffff00|n Expected (green) : #00ff00'] +##teamcity[testFailed name='compareQColor()' message='Failure! |[Loc: tst_cmptest.cpp(360)|]' details='Compared values are not the same|n Actual (yellow): #ffff00|n Expected (green) : #00ff00'] ##teamcity[testFinished name='compareQColor()'] ##teamcity[testStarted name='compareQPixmaps(both null)'] ##teamcity[testFinished name='compareQPixmaps(both null)'] ##teamcity[testStarted name='compareQPixmaps(one null)'] -##teamcity[testFailed name='compareQPixmaps(one null)' message='Failure! |[Loc: tst_cmptest.cpp(382)|]' details='Compared QPixmaps differ.|n Actual (opA).isNull(): 1|n Expected (opB).isNull(): 0'] +##teamcity[testFailed name='compareQPixmaps(one null)' message='Failure! |[Loc: tst_cmptest.cpp(385)|]' details='Compared QPixmaps differ.|n Actual (opA).isNull(): 1|n Expected (opB).isNull(): 0'] ##teamcity[testFinished name='compareQPixmaps(one null)'] ##teamcity[testStarted name='compareQPixmaps(other null)'] -##teamcity[testFailed name='compareQPixmaps(other null)' message='Failure! |[Loc: tst_cmptest.cpp(382)|]' details='Compared QPixmaps differ.|n Actual (opA).isNull(): 0|n Expected (opB).isNull(): 1'] +##teamcity[testFailed name='compareQPixmaps(other null)' message='Failure! |[Loc: tst_cmptest.cpp(385)|]' details='Compared QPixmaps differ.|n Actual (opA).isNull(): 0|n Expected (opB).isNull(): 1'] ##teamcity[testFinished name='compareQPixmaps(other null)'] ##teamcity[testStarted name='compareQPixmaps(equal)'] ##teamcity[testFinished name='compareQPixmaps(equal)'] ##teamcity[testStarted name='compareQPixmaps(different size)'] -##teamcity[testFailed name='compareQPixmaps(different size)' message='Failure! |[Loc: tst_cmptest.cpp(382)|]' details='Compared QPixmaps differ in size.|n Actual (opA): 11x20|n Expected (opB): 20x20'] +##teamcity[testFailed name='compareQPixmaps(different size)' message='Failure! |[Loc: tst_cmptest.cpp(385)|]' details='Compared QPixmaps differ in size.|n Actual (opA): 11x20|n Expected (opB): 20x20'] ##teamcity[testFinished name='compareQPixmaps(different size)'] ##teamcity[testStarted name='compareQPixmaps(different pixels)'] -##teamcity[testFailed name='compareQPixmaps(different pixels)' message='Failure! |[Loc: tst_cmptest.cpp(382)|]' details='Compared values are not the same'] +##teamcity[testFailed name='compareQPixmaps(different pixels)' message='Failure! |[Loc: tst_cmptest.cpp(385)|]' details='Compared values are not the same'] ##teamcity[testFinished name='compareQPixmaps(different pixels)'] ##teamcity[testStarted name='compareQImages(both null)'] ##teamcity[testFinished name='compareQImages(both null)'] ##teamcity[testStarted name='compareQImages(one null)'] -##teamcity[testFailed name='compareQImages(one null)' message='Failure! |[Loc: tst_cmptest.cpp(409)|]' details='Compared QImages differ.|n Actual (opA).isNull(): 1|n Expected (opB).isNull(): 0'] +##teamcity[testFailed name='compareQImages(one null)' message='Failure! |[Loc: tst_cmptest.cpp(412)|]' details='Compared QImages differ.|n Actual (opA).isNull(): 1|n Expected (opB).isNull(): 0'] ##teamcity[testFinished name='compareQImages(one null)'] ##teamcity[testStarted name='compareQImages(other null)'] -##teamcity[testFailed name='compareQImages(other null)' message='Failure! |[Loc: tst_cmptest.cpp(409)|]' details='Compared QImages differ.|n Actual (opA).isNull(): 0|n Expected (opB).isNull(): 1'] +##teamcity[testFailed name='compareQImages(other null)' message='Failure! |[Loc: tst_cmptest.cpp(412)|]' details='Compared QImages differ.|n Actual (opA).isNull(): 0|n Expected (opB).isNull(): 1'] ##teamcity[testFinished name='compareQImages(other null)'] ##teamcity[testStarted name='compareQImages(equal)'] ##teamcity[testFinished name='compareQImages(equal)'] ##teamcity[testStarted name='compareQImages(different size)'] -##teamcity[testFailed name='compareQImages(different size)' message='Failure! |[Loc: tst_cmptest.cpp(409)|]' details='Compared QImages differ in size.|n Actual (opA): 11x20|n Expected (opB): 20x20'] +##teamcity[testFailed name='compareQImages(different size)' message='Failure! |[Loc: tst_cmptest.cpp(412)|]' details='Compared QImages differ in size.|n Actual (opA): 11x20|n Expected (opB): 20x20'] ##teamcity[testFinished name='compareQImages(different size)'] ##teamcity[testStarted name='compareQImages(different format)'] -##teamcity[testFailed name='compareQImages(different format)' message='Failure! |[Loc: tst_cmptest.cpp(409)|]' details='Compared QImages differ in format.|n Actual (opA): 6|n Expected (opB): 3'] +##teamcity[testFailed name='compareQImages(different format)' message='Failure! |[Loc: tst_cmptest.cpp(412)|]' details='Compared QImages differ in format.|n Actual (opA): 6|n Expected (opB): 3'] ##teamcity[testFinished name='compareQImages(different format)'] ##teamcity[testStarted name='compareQImages(different pixels)'] -##teamcity[testFailed name='compareQImages(different pixels)' message='Failure! |[Loc: tst_cmptest.cpp(409)|]' details='Compared values are not the same'] +##teamcity[testFailed name='compareQImages(different pixels)' message='Failure! |[Loc: tst_cmptest.cpp(412)|]' details='Compared values are not the same'] ##teamcity[testFinished name='compareQImages(different pixels)'] +##teamcity[testStarted name='compareQRegion(equal-empty)'] +##teamcity[testFinished name='compareQRegion(equal-empty)'] +##teamcity[testStarted name='compareQRegion(1-empty)'] +##teamcity[testFailed name='compareQRegion(1-empty)' message='Failure! |[Loc: tst_cmptest.cpp(435)|]' details='Compared values are not the same|n Actual (rA): QRegion(200x50+10+10)|n Expected (rB): QRegion(null)'] +##teamcity[testFinished name='compareQRegion(1-empty)'] +##teamcity[testStarted name='compareQRegion(equal)'] +##teamcity[testFinished name='compareQRegion(equal)'] +##teamcity[testStarted name='compareQRegion(different lists)'] +##teamcity[testFailed name='compareQRegion(different lists)' message='Failure! |[Loc: tst_cmptest.cpp(435)|]' details='Compared values are not the same|n Actual (rA): QRegion(200x50+10+10)|n Expected (rB): QRegion(2 rectangles, 50x200+100+200, 200x50+10+10)'] +##teamcity[testFinished name='compareQRegion(different lists)'] ##teamcity[testStarted name='verify()'] -##teamcity[testFailed name='verify()' message='Failure! |[Loc: tst_cmptest.cpp(421)|]' details='|'opaqueFunc() < 2|' returned FALSE. ()'] +##teamcity[testFailed name='verify()' message='Failure! |[Loc: tst_cmptest.cpp(447)|]' details='|'opaqueFunc() < 2|' returned FALSE. ()'] ##teamcity[testFinished name='verify()'] ##teamcity[testStarted name='verify2()'] -##teamcity[testFailed name='verify2()' message='Failure! |[Loc: tst_cmptest.cpp(427)|]' details='|'opaqueFunc() < 2|' returned FALSE. (42)'] +##teamcity[testFailed name='verify2()' message='Failure! |[Loc: tst_cmptest.cpp(453)|]' details='|'opaqueFunc() < 2|' returned FALSE. (42)'] ##teamcity[testFinished name='verify2()'] ##teamcity[testStarted name='tryVerify()'] -##teamcity[testFailed name='tryVerify()' message='Failure! |[Loc: tst_cmptest.cpp(433)|]' details='|'opaqueFunc() < 2|' returned FALSE. ()'] +##teamcity[testFailed name='tryVerify()' message='Failure! |[Loc: tst_cmptest.cpp(459)|]' details='|'opaqueFunc() < 2|' returned FALSE. ()'] ##teamcity[testFinished name='tryVerify()'] ##teamcity[testStarted name='tryVerify2()'] -##teamcity[testFailed name='tryVerify2()' message='Failure! |[Loc: tst_cmptest.cpp(439)|]' details='|'opaqueFunc() < 2|' returned FALSE. (42)'] +##teamcity[testFailed name='tryVerify2()' message='Failure! |[Loc: tst_cmptest.cpp(465)|]' details='|'opaqueFunc() < 2|' returned FALSE. (42)'] ##teamcity[testFinished name='tryVerify2()'] ##teamcity[testStarted name='cleanupTestCase()'] ##teamcity[testFinished name='cleanupTestCase()'] diff --git a/tests/auto/testlib/selftests/expected_cmptest.txt b/tests/auto/testlib/selftests/expected_cmptest.txt index 276383ce9d..c7094a4113 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.txt +++ b/tests/auto/testlib/selftests/expected_cmptest.txt @@ -2,112 +2,122 @@ Config: Using QtTest library PASS : tst_Cmptest::initTestCase() FAIL! : tst_Cmptest::compare_unregistered_enums() Compared values are not the same - Loc: [tst_cmptest.cpp(156)] + Loc: [tst_cmptest.cpp(158)] FAIL! : tst_Cmptest::compare_registered_enums() Compared values are not the same Actual (Qt::Monday): Monday Expected (Qt::Sunday): Sunday - Loc: [tst_cmptest.cpp(162)] + Loc: [tst_cmptest.cpp(165)] FAIL! : tst_Cmptest::compare_class_enums() Compared values are not the same Actual (MyClassEnum::MyClassEnumValue1): MyClassEnumValue1 Expected (MyClassEnum::MyClassEnumValue2): MyClassEnumValue2 - Loc: [tst_cmptest.cpp(168)] + Loc: [tst_cmptest.cpp(171)] PASS : tst_Cmptest::compare_boolfuncs() PASS : tst_Cmptest::compare_pointerfuncs() FAIL! : tst_Cmptest::compare_tostring(int, string) Compared values are not the same Actual (actual) : QVariant(int,123) Expected (expected): QVariant(QString,hi) - Loc: [tst_cmptest.cpp(239)] + Loc: [tst_cmptest.cpp(242)] PASS : tst_Cmptest::compare_tostring(both invalid) FAIL! : tst_Cmptest::compare_tostring(null hash, invalid) Compared values are not the same Actual (actual) : QVariant(QVariantHash) Expected (expected): QVariant() - Loc: [tst_cmptest.cpp(239)] + Loc: [tst_cmptest.cpp(242)] FAIL! : tst_Cmptest::compare_tostring(string, null user type) Compared values are not the same Actual (actual) : QVariant(QString,A simple string) Expected (expected): QVariant(PhonyClass) - Loc: [tst_cmptest.cpp(239)] + Loc: [tst_cmptest.cpp(242)] FAIL! : tst_Cmptest::compare_tostring(both non-null user type) Compared values are not the same Actual (actual) : QVariant(PhonyClass,) Expected (expected): QVariant(PhonyClass,) - Loc: [tst_cmptest.cpp(239)] + Loc: [tst_cmptest.cpp(242)] PASS : tst_Cmptest::compareQStringLists(empty lists) PASS : tst_Cmptest::compareQStringLists(equal lists) FAIL! : tst_Cmptest::compareQStringLists(last item different) Compared lists differ at index 2. Actual (opA): "string3" Expected (opB): "DIFFERS" - Loc: [tst_cmptest.cpp(333)] + Loc: [tst_cmptest.cpp(336)] FAIL! : tst_Cmptest::compareQStringLists(second-last item different) Compared lists differ at index 2. Actual (opA): "string3" Expected (opB): "DIFFERS" - Loc: [tst_cmptest.cpp(333)] + Loc: [tst_cmptest.cpp(336)] FAIL! : tst_Cmptest::compareQStringLists(prefix) Compared lists have different sizes. Actual (opA) size: 2 Expected (opB) size: 1 - Loc: [tst_cmptest.cpp(333)] + Loc: [tst_cmptest.cpp(336)] FAIL! : tst_Cmptest::compareQStringLists(short list second) Compared lists have different sizes. Actual (opA) size: 12 Expected (opB) size: 1 - Loc: [tst_cmptest.cpp(333)] + Loc: [tst_cmptest.cpp(336)] FAIL! : tst_Cmptest::compareQStringLists(short list first) Compared lists have different sizes. Actual (opA) size: 1 Expected (opB) size: 12 - Loc: [tst_cmptest.cpp(333)] + Loc: [tst_cmptest.cpp(336)] FAIL! : tst_Cmptest::compareQListInt() Compared lists differ at index 2. Actual (int1): 3 Expected (int2): 4 - Loc: [tst_cmptest.cpp(340)] + Loc: [tst_cmptest.cpp(343)] FAIL! : tst_Cmptest::compareQListDouble() Compared lists differ at index 0. Actual (double1): 1.5 Expected (double2): 1 - Loc: [tst_cmptest.cpp(347)] + Loc: [tst_cmptest.cpp(350)] FAIL! : tst_Cmptest::compareQColor() Compared values are not the same Actual (yellow): #ffff00 Expected (green) : #00ff00 - Loc: [tst_cmptest.cpp(357)] + Loc: [tst_cmptest.cpp(360)] PASS : tst_Cmptest::compareQPixmaps(both null) FAIL! : tst_Cmptest::compareQPixmaps(one null) Compared QPixmaps differ. Actual (opA).isNull(): 1 Expected (opB).isNull(): 0 - Loc: [tst_cmptest.cpp(382)] + Loc: [tst_cmptest.cpp(385)] FAIL! : tst_Cmptest::compareQPixmaps(other null) Compared QPixmaps differ. Actual (opA).isNull(): 0 Expected (opB).isNull(): 1 - Loc: [tst_cmptest.cpp(382)] + Loc: [tst_cmptest.cpp(385)] PASS : tst_Cmptest::compareQPixmaps(equal) FAIL! : tst_Cmptest::compareQPixmaps(different size) Compared QPixmaps differ in size. Actual (opA): 11x20 Expected (opB): 20x20 - Loc: [tst_cmptest.cpp(382)] + Loc: [tst_cmptest.cpp(385)] FAIL! : tst_Cmptest::compareQPixmaps(different pixels) Compared values are not the same - Loc: [tst_cmptest.cpp(382)] + Loc: [tst_cmptest.cpp(385)] PASS : tst_Cmptest::compareQImages(both null) FAIL! : tst_Cmptest::compareQImages(one null) Compared QImages differ. Actual (opA).isNull(): 1 Expected (opB).isNull(): 0 - Loc: [tst_cmptest.cpp(409)] + Loc: [tst_cmptest.cpp(412)] FAIL! : tst_Cmptest::compareQImages(other null) Compared QImages differ. Actual (opA).isNull(): 0 Expected (opB).isNull(): 1 - Loc: [tst_cmptest.cpp(409)] + Loc: [tst_cmptest.cpp(412)] PASS : tst_Cmptest::compareQImages(equal) FAIL! : tst_Cmptest::compareQImages(different size) Compared QImages differ in size. Actual (opA): 11x20 Expected (opB): 20x20 - Loc: [tst_cmptest.cpp(409)] + Loc: [tst_cmptest.cpp(412)] FAIL! : tst_Cmptest::compareQImages(different format) Compared QImages differ in format. Actual (opA): 6 Expected (opB): 3 - Loc: [tst_cmptest.cpp(409)] + Loc: [tst_cmptest.cpp(412)] FAIL! : tst_Cmptest::compareQImages(different pixels) Compared values are not the same - Loc: [tst_cmptest.cpp(409)] + Loc: [tst_cmptest.cpp(412)] +PASS : tst_Cmptest::compareQRegion(equal-empty) +FAIL! : tst_Cmptest::compareQRegion(1-empty) Compared values are not the same + Actual (rA): QRegion(200x50+10+10) + Expected (rB): QRegion(null) + Loc: [tst_cmptest.cpp(435)] +PASS : tst_Cmptest::compareQRegion(equal) +FAIL! : tst_Cmptest::compareQRegion(different lists) Compared values are not the same + Actual (rA): QRegion(200x50+10+10) + Expected (rB): QRegion(2 rectangles, 50x200+100+200, 200x50+10+10) + Loc: [tst_cmptest.cpp(435)] FAIL! : tst_Cmptest::verify() 'opaqueFunc() < 2' returned FALSE. () - Loc: [tst_cmptest.cpp(421)] + Loc: [tst_cmptest.cpp(447)] FAIL! : tst_Cmptest::verify2() 'opaqueFunc() < 2' returned FALSE. (42) - Loc: [tst_cmptest.cpp(427)] + Loc: [tst_cmptest.cpp(453)] FAIL! : tst_Cmptest::tryVerify() 'opaqueFunc() < 2' returned FALSE. () - Loc: [tst_cmptest.cpp(433)] + Loc: [tst_cmptest.cpp(459)] FAIL! : tst_Cmptest::tryVerify2() 'opaqueFunc() < 2' returned FALSE. (42) - Loc: [tst_cmptest.cpp(439)] + Loc: [tst_cmptest.cpp(465)] PASS : tst_Cmptest::cleanupTestCase() -Totals: 11 passed, 28 failed, 0 skipped, 0 blacklisted, 247ms +Totals: 13 passed, 30 failed, 0 skipped, 0 blacklisted, 246ms ********* Finished testing of tst_Cmptest ********* diff --git a/tests/auto/testlib/selftests/expected_cmptest.xml b/tests/auto/testlib/selftests/expected_cmptest.xml index ba5bd3dba6..d472840e98 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xml +++ b/tests/auto/testlib/selftests/expected_cmptest.xml @@ -10,13 +10,13 @@ - + - + @@ -24,7 +24,7 @@ - + @@ -40,7 +40,7 @@ - + - + - + - + ) @@ -76,31 +76,31 @@ - + - + - + - + - + - + @@ -117,7 +117,7 @@ - + @@ -125,7 +125,7 @@ - + @@ -136,13 +136,13 @@ - + - + - + - + @@ -167,13 +167,13 @@ - + - + - + - + - + + + + + + + + + + + + + + + + + + - + - + - + - + diff --git a/tests/auto/testlib/selftests/expected_cmptest.xunitxml b/tests/auto/testlib/selftests/expected_cmptest.xunitxml index 0b43fba654..9f1726b0d6 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xunitxml +++ b/tests/auto/testlib/selftests/expected_cmptest.xunitxml @@ -1,5 +1,5 @@ - + @@ -94,6 +94,14 @@ Expected (opB): 3" result="fail"/> + + + + -- cgit v1.2.3 From 5392259ce6df9b9852a8580831cff4139fe2677c Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Mon, 27 Jun 2016 16:40:57 +0300 Subject: QXml: reduce allocations in extractEncodingDecl Replace QString::left() with QString::leftRef(). Use QStringLiteral more. Change-Id: Ibcecc666d034a5e1fe963119483030ab397b16b1 Reviewed-by: Edward Welbourne --- src/xml/sax/qxml.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp index d4c8519d67..fe21bca810 100644 --- a/src/xml/sax/qxml.cpp +++ b/src/xml/sax/qxml.cpp @@ -1295,7 +1295,8 @@ static QString extractEncodingDecl(const QString &text, bool *needMoreText) *needMoreText = false; int l = text.length(); - QString snip = QString::fromLatin1(" 0 && !text.startsWith(snip)) return QString(); -- cgit v1.2.3 From 3a33ee78c9329d772b4794d094bc48444514c101 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 5 Jul 2016 16:30:13 +0300 Subject: Tools: replace QString::trimmed() with QStringRef::trimmed() ... where it's possible. Reduce allocations. Change-Id: I9908d9d65177d116a8a54146274a74edb801543e Reviewed-by: Marc Mutz --- src/tools/uic/cpp/cppwriteincludes.cpp | 3 +-- src/tools/uic/cpp/cppwriteinitialization.cpp | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/tools/uic/cpp/cppwriteincludes.cpp b/src/tools/uic/cpp/cppwriteincludes.cpp index e93e6bb26c..a99d6adf07 100644 --- a/src/tools/uic/cpp/cppwriteincludes.cpp +++ b/src/tools/uic/cpp/cppwriteincludes.cpp @@ -291,9 +291,8 @@ void WriteIncludes::writeHeaders(const OrderedSet &headers, bool global) const StringMap::const_iterator hit = m_oldHeaderToNewHeader.constFind(sit.key()); const bool mapped = hit != m_oldHeaderToNewHeader.constEnd(); const QString header = mapped ? hit.value() : sit.key(); - if (!header.trimmed().isEmpty()) { + if (!QStringRef(&header).trimmed().isEmpty()) m_output << "#include " << openingQuote << header << closingQuote << QLatin1Char('\n'); - } } } diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index 7466da47f3..b996aa8e45 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -2473,10 +2473,8 @@ void WriteInitialization::acceptWidgetScripts(const DomScripts &widgetScripts, D QString script; for (const DomScript *domScript : qAsConst(scripts)) { const QString snippet = domScript->text(); - if (!snippet.isEmpty()) { - script += snippet.trimmed(); - script += QLatin1Char('\n'); - } + if (!snippet.isEmpty()) + script += QStringRef(&snippet).trimmed() + QLatin1Char('\n'); } if (script.isEmpty()) return; -- cgit v1.2.3 From f217894152a29d4be14aaf604ee4230cb40b9c97 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 5 Jul 2016 12:49:03 +0300 Subject: QDateTimeEdit: remove homebrew 'reverse' algorithm Use std::reverse Change-Id: Ia922f3e05e100587f0e7bc91bb1a95679bc03896 Reviewed-by: Marc Mutz --- src/widgets/widgets/qdatetimeedit.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index cfba2cc87f..795f2cedd9 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -52,6 +52,8 @@ #include #include +#include + #ifndef QT_NO_DATETIMEEDIT //#define QDATETIMEEDIT_QDTEDEBUG @@ -861,14 +863,6 @@ QString QDateTimeEdit::displayFormat() const return isRightToLeft() ? d->unreversedFormat : d->displayFormat; } -template static inline C reverse(const C &l) -{ - C ret; - for (int i=l.size() - 1; i>=0; --i) - ret.append(l.at(i)); - return ret; -} - void QDateTimeEdit::setDisplayFormat(const QString &format) { Q_D(QDateTimeEdit); @@ -882,8 +876,8 @@ void QDateTimeEdit::setDisplayFormat(const QString &format) d->displayFormat += d->sectionNode(i).format(); } d->displayFormat += d->separators.at(0); - d->separators = reverse(d->separators); - d->sectionNodes = reverse(d->sectionNodes); + std::reverse(d->separators.begin(), d->separators.end()); + std::reverse(d->sectionNodes.begin(), d->sectionNodes.end()); } d->formatExplicitlySet = true; -- cgit v1.2.3 From b073ba57f821b2e79c553f974d9fba2cbb034ee9 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 5 Jul 2016 12:12:45 +0300 Subject: Widgets: use const (and const APIs) more For CoW types, prefer const methods to avoid needless detach()ing. Change-Id: Ia6cad50a10facf6fd4f73d1390edb8642a0aed32 Reviewed-by: Marc Mutz --- .../graphicsview/qgraphicsanchorlayout_p.cpp | 10 ++-- src/widgets/graphicsview/qgraphicsitem.cpp | 2 +- src/widgets/graphicsview/qgraphicsscene.cpp | 60 +++++++++++----------- src/widgets/graphicsview/qgraphicsview.cpp | 6 +-- src/widgets/itemviews/qcolumnview.cpp | 20 ++++---- src/widgets/itemviews/qdirmodel.cpp | 2 +- src/widgets/itemviews/qlistview.cpp | 6 +-- src/widgets/itemviews/qtreeview.cpp | 8 +-- src/widgets/widgets/qdockarealayout.cpp | 2 +- src/widgets/widgets/qfontcombobox.cpp | 2 +- 10 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp index 53db11d2d7..4c01219d87 100644 --- a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1082,7 +1082,7 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP if (candidates.isEmpty()) after = (beforeSequence == adjacents.last() ? adjacents.first() : adjacents.last()); else - after = (candidates.last() == adjacents.last() ? adjacents.first() : adjacents.last()); + after = (candidates.constLast() == adjacents.last() ? adjacents.first() : adjacents.last()); // ### At this point we assumed that candidates will not contain 'after', this may not hold // when simplifying FLOATing anchors. @@ -1134,9 +1134,9 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP // One restriction we have is to not simplify half of an anchor and let the other half // unsimplified. So we remove center edges before and after the sequence. - const AnchorData *firstAnchor = g.edgeData(beforeSequence, candidates.first()); + const AnchorData *firstAnchor = g.edgeData(beforeSequence, candidates.constFirst()); if (firstAnchor->isCenterAnchor) { - beforeSequence = candidates.first(); + beforeSequence = candidates.constFirst(); candidates.remove(0); // If there's not candidates to be simplified, leave. @@ -1144,9 +1144,9 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP continue; } - const AnchorData *lastAnchor = g.edgeData(candidates.last(), afterSequence); + const AnchorData *lastAnchor = g.edgeData(candidates.constLast(), afterSequence); if (lastAnchor->isCenterAnchor) { - afterSequence = candidates.last(); + afterSequence = candidates.constLast(); candidates.remove(candidates.count() - 1); if (candidates.isEmpty()) diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index db683a4e4d..df81d70742 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -2152,7 +2152,7 @@ bool QGraphicsItem::isBlockedByModalPanel(QGraphicsItem **blockingPanel) const if (!blockingPanel) blockingPanel = &dummy; - QGraphicsScenePrivate *scene_d = d_ptr->scene->d_func(); + const QGraphicsScenePrivate *scene_d = d_ptr->scene->d_func(); if (scene_d->modalPanels.isEmpty()) return false; diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp index cb1d1e68d1..b63686cd77 100644 --- a/src/widgets/graphicsview/qgraphicsscene.cpp +++ b/src/widgets/graphicsview/qgraphicsscene.cpp @@ -940,7 +940,7 @@ void QGraphicsScenePrivate::grabMouse(QGraphicsItem *item, bool implicit) { // Append to list of mouse grabber items, and send a mouse grab event. if (mouseGrabberItems.contains(item)) { - if (mouseGrabberItems.last() == item) { + if (mouseGrabberItems.constLast() == item) { Q_ASSERT(!implicit); if (!lastMouseGrabberItemHasImplicitMouseGrab) { qWarning("QGraphicsItem::grabMouse: already a mouse grabber"); @@ -950,14 +950,14 @@ void QGraphicsScenePrivate::grabMouse(QGraphicsItem *item, bool implicit) } } else { qWarning("QGraphicsItem::grabMouse: already blocked by mouse grabber: %p", - mouseGrabberItems.last()); + mouseGrabberItems.constLast()); } return; } // Send ungrab event to the last grabber. if (!mouseGrabberItems.isEmpty()) { - QGraphicsItem *last = mouseGrabberItems.last(); + QGraphicsItem *last = mouseGrabberItems.constLast(); if (lastMouseGrabberItemHasImplicitMouseGrab) { // Implicit mouse grab is immediately lost. last->ungrabMouse(); @@ -987,12 +987,12 @@ void QGraphicsScenePrivate::ungrabMouse(QGraphicsItem *item, bool itemIsDying) return; } - if (item != mouseGrabberItems.last()) { + if (item != mouseGrabberItems.constLast()) { // Recursively ungrab the next mouse grabber until we reach this item // to ensure state consistency. ungrabMouse(mouseGrabberItems.at(index + 1), itemIsDying); } - if (!popupWidgets.isEmpty() && item == popupWidgets.last()) { + if (!popupWidgets.isEmpty() && item == popupWidgets.constLast()) { // If the item is a popup, go via removePopup to ensure state // consistency and that it gets hidden correctly - beware that // removePopup() reenters this function to continue removing the grab. @@ -1017,7 +1017,7 @@ void QGraphicsScenePrivate::ungrabMouse(QGraphicsItem *item, bool itemIsDying) // items get a GrabMouse event, but this is a rare case with a simple // implementation and it does ensure a consistent state. if (!itemIsDying && !mouseGrabberItems.isEmpty()) { - QGraphicsItem *last = mouseGrabberItems.last(); + QGraphicsItem *last = mouseGrabberItems.constLast(); QEvent event(QEvent::GrabMouse); sendEvent(last, &event); } @@ -1039,11 +1039,11 @@ void QGraphicsScenePrivate::clearMouseGrabber() void QGraphicsScenePrivate::grabKeyboard(QGraphicsItem *item) { if (keyboardGrabberItems.contains(item)) { - if (keyboardGrabberItems.last() == item) + if (keyboardGrabberItems.constLast() == item) qWarning("QGraphicsItem::grabKeyboard: already a keyboard grabber"); else qWarning("QGraphicsItem::grabKeyboard: already blocked by keyboard grabber: %p", - keyboardGrabberItems.last()); + keyboardGrabberItems.constLast()); return; } @@ -1051,7 +1051,7 @@ void QGraphicsScenePrivate::grabKeyboard(QGraphicsItem *item) if (!keyboardGrabberItems.isEmpty()) { // Just send ungrab event to current grabber. QEvent ungrabEvent(QEvent::UngrabKeyboard); - sendEvent(keyboardGrabberItems.last(), &ungrabEvent); + sendEvent(keyboardGrabberItems.constLast(), &ungrabEvent); } keyboardGrabberItems << item; @@ -1071,7 +1071,7 @@ void QGraphicsScenePrivate::ungrabKeyboard(QGraphicsItem *item, bool itemIsDying qWarning("QGraphicsItem::ungrabKeyboard: not a keyboard grabber"); return; } - if (item != keyboardGrabberItems.last()) { + if (item != keyboardGrabberItems.constLast()) { // Recursively ungrab the topmost keyboard grabber until we reach this // item to ensure state consistency. ungrabKeyboard(keyboardGrabberItems.at(index + 1), itemIsDying); @@ -1088,7 +1088,7 @@ void QGraphicsScenePrivate::ungrabKeyboard(QGraphicsItem *item, bool itemIsDying // Send notification about mouse regrab. if (!itemIsDying && !keyboardGrabberItems.isEmpty()) { - QGraphicsItem *last = keyboardGrabberItems.last(); + QGraphicsItem *last = keyboardGrabberItems.constLast(); QEvent event(QEvent::GrabKeyboard); sendEvent(last, &event); } @@ -1100,7 +1100,7 @@ void QGraphicsScenePrivate::ungrabKeyboard(QGraphicsItem *item, bool itemIsDying void QGraphicsScenePrivate::clearKeyboardGrabber() { if (!keyboardGrabberItems.isEmpty()) - ungrabKeyboard(keyboardGrabberItems.first()); + ungrabKeyboard(keyboardGrabberItems.constFirst()); } void QGraphicsScenePrivate::enableMouseTrackingOnViews() @@ -1142,8 +1142,8 @@ void QGraphicsScenePrivate::storeMouseButtonsForMouseGrabber(QGraphicsSceneMouse for (int i = 0x1; i <= 0x10; i <<= 1) { if (event->buttons() & i) { mouseGrabberButtonDownPos.insert(Qt::MouseButton(i), - mouseGrabberItems.last()->d_ptr->genericMapFromScene(event->scenePos(), - event->widget())); + mouseGrabberItems.constLast()->d_ptr->genericMapFromScene(event->scenePos(), + event->widget())); mouseGrabberButtonDownScenePos.insert(Qt::MouseButton(i), event->scenePos()); mouseGrabberButtonDownScreenPos.insert(Qt::MouseButton(i), event->screenPos()); } @@ -1308,7 +1308,7 @@ void QGraphicsScenePrivate::sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent) return; } - QGraphicsItem *item = mouseGrabberItems.last(); + QGraphicsItem *item = mouseGrabberItems.constLast(); if (item->isBlockedByModalPanel()) return; @@ -1335,7 +1335,7 @@ void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mou // Deliver to any existing mouse grabber. if (!mouseGrabberItems.isEmpty()) { - if (mouseGrabberItems.last()->isBlockedByModalPanel()) + if (mouseGrabberItems.constLast()->isBlockedByModalPanel()) return; // The event is ignored by default, but we disregard the event's // accepted state after delivery; the mouse is grabbed, after all. @@ -1401,7 +1401,7 @@ void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mou // Any item will do. if (sceneModality && cachedItemsUnderMouse.isEmpty()) - cachedItemsUnderMouse << modalPanels.first(); + cachedItemsUnderMouse << modalPanels.constFirst(); // Find a mouse grabber by sending mouse press events to all mouse grabber // candidates one at a time, until the event is accepted. It's accepted by @@ -1450,7 +1450,7 @@ void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mou sendMouseEvent(mouseEvent); } - bool dontSendUngrabEvents = mouseGrabberItems.isEmpty() || mouseGrabberItems.last() != item; + bool dontSendUngrabEvents = mouseGrabberItems.isEmpty() || mouseGrabberItems.constLast() != item; if (disabled) { ungrabMouse(item, /* itemIsDying = */ dontSendUngrabEvents); break; @@ -2167,8 +2167,8 @@ QList QGraphicsScene::collidingItems(const QGraphicsItem *item, */ QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform &deviceTransform) const { - QList itemsAtPoint = items(position, Qt::IntersectsItemShape, - Qt::DescendingOrder, deviceTransform); + const QList itemsAtPoint = items(position, Qt::IntersectsItemShape, + Qt::DescendingOrder, deviceTransform); return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first(); } @@ -3771,7 +3771,7 @@ void QGraphicsScene::focusOutEvent(QFocusEvent *focusEvent) // Remove all popups when the scene loses focus. if (!d->popupWidgets.isEmpty()) - d->removePopup(d->popupWidgets.first()); + d->removePopup(d->popupWidgets.constFirst()); } /*! @@ -3868,7 +3868,7 @@ bool QGraphicsScenePrivate::dispatchHoverEvent(QGraphicsSceneHoverEvent *hoverEv // Find the common ancestor item for the new topmost hoverItem and the // last item in the hoverItem list. - QGraphicsItem *commonAncestorItem = (item && !hoverItems.isEmpty()) ? item->commonAncestorItem(hoverItems.last()) : 0; + QGraphicsItem *commonAncestorItem = (item && !hoverItems.isEmpty()) ? item->commonAncestorItem(hoverItems.constLast()) : 0; while (commonAncestorItem && !itemAcceptsHoverEvents_helper(commonAncestorItem)) commonAncestorItem = commonAncestorItem->parentItem(); if (commonAncestorItem && commonAncestorItem->panel() != item->panel()) { @@ -3909,7 +3909,7 @@ bool QGraphicsScenePrivate::dispatchHoverEvent(QGraphicsSceneHoverEvent *hoverEv // Generate a move event for the item itself if (item && !hoverItems.isEmpty() - && item == hoverItems.last()) { + && item == hoverItems.constLast()) { sendHoverEvent(QEvent::GraphicsSceneHoverMove, item, hoverEvent); return true; } @@ -3959,7 +3959,7 @@ void QGraphicsScene::keyPressEvent(QKeyEvent *keyEvent) // ### Merge this function with keyReleaseEvent; they are identical // ### (except this comment). Q_D(QGraphicsScene); - QGraphicsItem *item = !d->keyboardGrabberItems.isEmpty() ? d->keyboardGrabberItems.last() : 0; + QGraphicsItem *item = !d->keyboardGrabberItems.isEmpty() ? d->keyboardGrabberItems.constLast() : 0; if (!item) item = focusItem(); if (item) { @@ -3991,7 +3991,7 @@ void QGraphicsScene::keyReleaseEvent(QKeyEvent *keyEvent) // ### Merge this function with keyPressEvent; they are identical (except // ### this comment). Q_D(QGraphicsScene); - QGraphicsItem *item = !d->keyboardGrabberItems.isEmpty() ? d->keyboardGrabberItems.last() : 0; + QGraphicsItem *item = !d->keyboardGrabberItems.isEmpty() ? d->keyboardGrabberItems.constLast() : 0; if (!item) item = focusItem(); if (item) { @@ -4100,9 +4100,9 @@ void QGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) // Reset the mouse grabber when the last mouse button has been released. if (!mouseEvent->buttons()) { if (!d->mouseGrabberItems.isEmpty()) { - d->lastMouseGrabberItem = d->mouseGrabberItems.last(); + d->lastMouseGrabberItem = d->mouseGrabberItems.constLast(); if (d->lastMouseGrabberItemHasImplicitMouseGrab) - d->mouseGrabberItems.last()->ungrabMouse(); + d->mouseGrabberItems.constLast()->ungrabMouse(); } else { d->lastMouseGrabberItem = 0; } @@ -5901,7 +5901,7 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent) cachedItemsUnderMouse = itemsAtPosition(touchPoint.screenPos().toPoint(), touchPoint.scenePos(), static_cast(sceneTouchEvent->target())); - item = cachedItemsUnderMouse.isEmpty() ? 0 : cachedItemsUnderMouse.first(); + item = cachedItemsUnderMouse.isEmpty() ? 0 : cachedItemsUnderMouse.constFirst(); } if (sceneTouchEvent->device()->type() == QTouchDevice::TouchScreen) { @@ -6012,7 +6012,7 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEve { Q_Q(QGraphicsScene); - if (cachedItemsUnderMouse.isEmpty() || cachedItemsUnderMouse.first() != origin) { + if (cachedItemsUnderMouse.isEmpty() || cachedItemsUnderMouse.constFirst() != origin) { const QTouchEvent::TouchPoint &firstTouchPoint = touchEvent->touchPoints().first(); cachedItemsUnderMouse = itemsAtPosition(firstTouchPoint.screenPos().toPoint(), firstTouchPoint.scenePos(), @@ -6128,7 +6128,7 @@ void QGraphicsScenePrivate::enterModal(QGraphicsItem *panel, QGraphicsItem::Pane } if (!mouseGrabberItems.isEmpty() && lastMouseGrabberItemHasImplicitMouseGrab) { - QGraphicsItem *item = mouseGrabberItems.last(); + QGraphicsItem *item = mouseGrabberItems.constLast(); if (item->isBlockedByModalPanel()) ungrabMouse(item, /*itemIsDying =*/ false); } diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index fc5dbdd80a..442918169a 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -2378,7 +2378,7 @@ QGraphicsItem *QGraphicsView::itemAt(const QPoint &pos) const Q_D(const QGraphicsView); if (!d->scene) return 0; - QList itemsAtPos = items(pos); + const QList itemsAtPos = items(pos); return itemsAtPos.isEmpty() ? 0 : itemsAtPos.first(); } @@ -2865,7 +2865,7 @@ bool QGraphicsView::viewportEvent(QEvent *event) // the mouse grab. // Remove all popups when the scene loses focus. if (!d->scene->d_func()->popupWidgets.isEmpty()) - d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.first()); + d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.constFirst()); QApplication::sendEvent(d->scene, event); break; case QEvent::Show: @@ -2889,7 +2889,7 @@ bool QGraphicsView::viewportEvent(QEvent *event) || (QApplication::activeModalWidget() && QApplication::activeModalWidget() != window()) || (QApplication::activeWindow() != window())) { if (!d->scene->d_func()->popupWidgets.isEmpty()) - d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.first()); + d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.constFirst()); } d->useLastMouseEvent = false; // a hack to pass a viewport pointer to the scene inside the leave event diff --git a/src/widgets/itemviews/qcolumnview.cpp b/src/widgets/itemviews/qcolumnview.cpp index 26173b5e92..6c7c914bc0 100644 --- a/src/widgets/itemviews/qcolumnview.cpp +++ b/src/widgets/itemviews/qcolumnview.cpp @@ -412,9 +412,9 @@ void QColumnViewPrivate::updateScrollbars() // find the total horizontal length of the laid out columns int horizontalLength = 0; if (!columns.isEmpty()) { - horizontalLength = (columns.last()->x() + columns.last()->width()) - columns.first()->x(); + horizontalLength = (columns.constLast()->x() + columns.constLast()->width()) - columns.constFirst()->x(); if (horizontalLength <= 0) // reverse mode - horizontalLength = (columns.first()->x() + columns.first()->width()) - columns.last()->x(); + horizontalLength = (columns.constFirst()->x() + columns.constFirst()->width()) - columns.constLast()->x(); } QSize viewportSize = viewport->size(); @@ -629,7 +629,7 @@ void QColumnViewPrivate::closeColumns(const QModelIndex &parent, bool build) while (!dirsToAppend.isEmpty()) { QAbstractItemView *newView = createColumn(dirsToAppend.takeLast(), true); if (!dirsToAppend.isEmpty()) - newView->setCurrentIndex(dirsToAppend.last()); + newView->setCurrentIndex(dirsToAppend.constLast()); } if (build && !alreadyExists) @@ -713,8 +713,8 @@ QAbstractItemView *QColumnViewPrivate::createColumn(const QModelIndex &index, bo columnSizes.resize(qMax(columnSizes.count(), columns.count() + 1)); columnSizes[columns.count()] = initialWidth; } - if (!columns.isEmpty() && columns.last()->isHidden()) - columns.last()->setVisible(true); + if (!columns.isEmpty() && columns.constLast()->isHidden()) + columns.constLast()->setVisible(true); columns.append(view); doLayout(); @@ -835,7 +835,7 @@ void QColumnViewPrivate::setPreviewWidget(QWidget *widget) { Q_Q(QColumnView); if (previewColumn) { - if (!columns.isEmpty() && columns.last() == previewColumn) + if (!columns.isEmpty() && columns.constLast() == previewColumn) columns.removeLast(); previewColumn->deleteLater(); } @@ -1003,11 +1003,11 @@ void QColumnViewPrivate::_q_changeCurrentColumn() parentColumn->setCurrentIndex(current.parent()); } - if (columns.last()->isHidden()) { - columns.last()->setVisible(true); + if (columns.constLast()->isHidden()) { + columns.constLast()->setVisible(true); } - if (columns.last()->selectionModel()) - columns.last()->selectionModel()->clear(); + if (columns.constLast()->selectionModel()) + columns.constLast()->selectionModel()->clear(); updateScrollbars(); } diff --git a/src/widgets/itemviews/qdirmodel.cpp b/src/widgets/itemviews/qdirmodel.cpp index dfb1d7619e..58e586980f 100644 --- a/src/widgets/itemviews/qdirmodel.cpp +++ b/src/widgets/itemviews/qdirmodel.cpp @@ -885,7 +885,7 @@ QModelIndex QDirModel::index(const QString &path, int column) const #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) if (absolutePath.startsWith(QLatin1String("//"))) { // UNC path - QString host = pathElements.first(); + QString host = pathElements.constFirst(); int r = 0; for (; r < d->root.children.count(); ++r) if (d->root.children.at(r).info.fileName() == host) diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 3303aac6ed..0788e0287a 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -2396,9 +2396,9 @@ QPoint QListModeViewBase::initStaticLayout(const QListViewLayoutInfo &info) } else if (info.wrap) { if (info.flow == QListView::LeftToRight) { x = batchSavedPosition; - y = segmentPositions.last(); + y = segmentPositions.constLast(); } else { // flow == QListView::TopToBottom - x = segmentPositions.last(); + x = segmentPositions.constLast(); y = batchSavedPosition; } } else { // not first and not wrap @@ -2613,7 +2613,7 @@ int QListModeViewBase::perItemScrollingPageSteps(int length, int bounds, bool wr int steps = positions.count() - 1; int max = qMax(length, bounds); int min = qMin(length, bounds); - int pos = min - (max - positions.last()); + int pos = min - (max - positions.constLast()); while (pos >= 0 && steps > 0) { pos -= (positions.at(steps) - positions.at(steps - 1)); diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index b6fd9f8ba8..4ce7da0229 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -2357,10 +2357,10 @@ void QTreeView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl return; } if (!topLeft.isValid() && !d->viewItems.isEmpty()) - topLeft = d->viewItems.first().index; + topLeft = d->viewItems.constFirst().index; if (!bottomRight.isValid() && !d->viewItems.isEmpty()) { const int column = d->header->logicalIndex(d->header->count() - 1); - const QModelIndex index = d->viewItems.last().index; + const QModelIndex index = d->viewItems.constLast().index; bottomRight = index.sibling(index.row(), column); } @@ -2668,9 +2668,9 @@ void QTreeView::selectAll() SelectionMode mode = d->selectionMode; d->executePostedLayout(); //make sure we lay out the items if (mode != SingleSelection && mode != NoSelection && !d->viewItems.isEmpty()) { - const QModelIndex &idx = d->viewItems.last().index; + const QModelIndex &idx = d->viewItems.constLast().index; QModelIndex lastItemIndex = idx.sibling(idx.row(), d->model->columnCount(idx.parent()) - 1); - d->select(d->viewItems.first().index, lastItemIndex, + d->select(d->viewItems.constFirst().index, lastItemIndex, QItemSelectionModel::ClearAndSelect |QItemSelectionModel::Rows); } diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index ed630913e7..fd155bf156 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -3163,7 +3163,7 @@ void QDockAreaLayout::splitDockWidget(QDockWidget *after, QDockWidget *dockWidget, Qt::Orientation orientation) { - QList path = indexOf(after); + const QList path = indexOf(after); if (path.isEmpty()) return; diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp index 1d736c8e96..9bd33409ae 100644 --- a/src/widgets/widgets/qfontcombobox.cpp +++ b/src/widgets/widgets/qfontcombobox.cpp @@ -162,7 +162,7 @@ static QFontDatabase::WritingSystem writingSystemForFont(const QFont &font, bool return QFontDatabase::TraditionalChinese; } - system = writingSystems.last(); + system = writingSystems.constLast(); if (!*hasLatin) { // we need to show something -- cgit v1.2.3 From cddb344f3e24e3a61baf896161618c36a3f0c737 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Thu, 30 Jun 2016 18:45:41 +0300 Subject: QSslSocket: reset connection parameters on disconnect Otherwise socketDescriptor(), localPort(), localAddress(), peerPort(), peerAddress(), and peerName() remain uncleared until close() is called. This could take place when the connection is closed by the remote endpoint or the user calls disconnectFromHost(). After disconnecting, connection parameters are no longer valid, while I/O device is still opened and may have pending data for reading. Usually, the user reads all incoming data and closes the device independently. Change-Id: Ic898851c39137faf64019949910f0d94ebb79df7 Reviewed-by: Edward Welbourne --- src/network/ssl/qsslsocket.cpp | 7 +++++++ tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 591d635162..ccb11de7e0 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -2401,6 +2401,13 @@ void QSslSocketPrivate::_q_disconnectedSlot() #endif disconnected(); emit q->disconnected(); + + q->setLocalPort(0); + q->setLocalAddress(QHostAddress()); + q->setPeerPort(0); + q->setPeerAddress(QHostAddress()); + q->setPeerName(QString()); + cachedSocketDescriptor = -1; } /*! diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 382fbf08a8..6bb502edcb 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -1213,6 +1213,12 @@ void tst_QTcpSocket::connectDisconnectConnectDisconnect() QCOMPARE(socket->state(), QTcpSocket::UnconnectedState); QCOMPARE(socket->socketType(), QTcpSocket::TcpSocket); + QCOMPARE(socket->socketDescriptor(), qintptr(-1)); + QCOMPARE(int(socket->localPort()), 0); + QCOMPARE(socket->localAddress(), QHostAddress()); + QCOMPARE(int(socket->peerPort()), 0); + QCOMPARE(socket->peerAddress(), QHostAddress()); + socket->connectToHost(QtNetworkSettings::serverName(), 143); QVERIFY(socket->waitForReadyRead(10000)); QCOMPARE(QString::fromLatin1(socket->read(4)), QString("* OK")); -- cgit v1.2.3 From 5fcac27359e66295c8cb15608b89599057c46425 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 20 Jun 2016 13:47:05 -0700 Subject: Remove support for MSVC < 2013 in ANGLE I'm also removing win32-msvc20xx mkspecs, so this would be dead code. Change-Id: Ib57b52598e2f452985e9fffd1459e59f142c7a39 Reviewed-by: Maurice Kalinowski Reviewed-by: Oliver Wolff --- src/angle/src/common/common.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/angle/src/common/common.pri b/src/angle/src/common/common.pri index 83cd1e8687..9eae06d410 100644 --- a/src/angle/src/common/common.pri +++ b/src/angle/src/common/common.pri @@ -21,7 +21,7 @@ lib_replace.CONFIG = path QMAKE_PRL_INSTALL_REPLACE += lib_replace # DirectX is included in the Windows 8 Kit, but everything else requires the DX SDK. -winrt|if(msvc:!win32-msvc2005:!win32-msvc2008:!win32-msvc2010) { +winrt|msvc { FXC = fxc.exe } else { DX_DIR = $$(DXSDK_DIR) -- cgit v1.2.3 From b6345a515be9b8649738e812290f03e848f64378 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 20 Jun 2016 17:05:08 -0700 Subject: QStorageInfo: update the algorithm for ignored filesystems on Unix Use the criterion that GNU coreutils' df uses: if the total size of the filesystem is zero, then it's pseudo. After all, if it contains files in a zero-sized volume, it has to be pseudo; if it contains nothing, then it's not very useful anyway. This would have caught most Linux pseudo-fs anyway, but the mount point check beforehand allows us to skip quite a few statfs() syscalls. The new algorithm also solves the following cases which had been mistakenly interpreted: * fuse and ZFS (source devices don't usually start with /) * pseudo-fs that were mounted from a device starting with / (the source device is usually ignored by the OS) This change is not testable automatically. Manual testing shows it still reports the same entries it used to on Linux, plus now shows FUSE (sshfs) mounts. Task-number: QTBUG-54235 Change-Id: Ib57b52598e2f452985e9fffd1459f06dcefcc5c6 Reviewed-by: Shawn Rutledge Reviewed-by: Edward Welbourne --- src/corelib/io/qstorageinfo_unix.cpp | 44 ++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index 0daf041954..ae5c42ffd1 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2014 Ivan Komissarov +** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -153,29 +154,41 @@ static bool isParentOf(const String &parent, const QString &dirName) parent.size() == 1); } -static bool isPseudoFs(const QStorageIterator &it) -{ +static bool shouldIncludeFs(const QStorageIterator &it) +{ + /* + * This function implements a heuristic algorithm to determine whether a + * given mount should be reported to the user. Our objective is to list + * only entries that the end-user would find useful. + * + * We therefore ignore: + * - mounted in /dev, /proc, /sys: special mounts + * (this will catch /sys/fs/cgroup, /proc/sys/fs/binfmt_misc, /dev/pts, + * some of which are tmpfs on Linux) + * - mounted in /var/run or /var/lock: most likely pseudofs + * (on earlier systemd versions, /var/run was a bind-mount of /run, so + * everything would be unnecessarily duplicated) + * - filesystem type is "rootfs": artifact of the root-pivot on some Linux + * initrd + * - if the filesystem total size is zero, it's a pseudo-fs (not checked here). + */ + QString mountDir = it.rootPath(); if (isParentOf(QLatin1String("/dev"), mountDir) || isParentOf(QLatin1String("/proc"), mountDir) || isParentOf(QLatin1String("/sys"), mountDir) || isParentOf(QLatin1String("/var/run"), mountDir) || isParentOf(QLatin1String("/var/lock"), mountDir)) { - return true; + return false; } - QByteArray type = it.fileSystemType(); - if (type == "tmpfs") +#ifdef Q_OS_LINUX + if (it.fileSystemType() == "rootfs") return false; -#if defined(Q_OS_LINUX) - if (type == "rootfs" || type == "rpc_pipefs") - return true; #endif - if (!it.device().startsWith('/')) - return true; - - return false; + // size checking in mountedVolumes() + return true; } #if defined(Q_OS_BSD4) @@ -557,11 +570,14 @@ QList QStorageInfoPrivate::mountedVolumes() QList volumes; while (it.next()) { - if (isPseudoFs(it)) + if (!shouldIncludeFs(it)) continue; const QString mountDir = it.rootPath(); - volumes.append(QStorageInfo(mountDir)); + QStorageInfo info(mountDir); + if (info.bytesTotal() == 0) + continue; + volumes.append(info); } return volumes; -- cgit v1.2.3 From 8f85e82c5dc3d3028828e11ff59b16e3cae2844d Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 4 Jul 2016 08:07:42 +0200 Subject: Windows: Handle theme switching correctly if a palette is set If a palette is set on the application object and the user does something to trigger a theme change, i.e. connects via remote desktop or logs out and in again, then it will cause Qt to render incorrectly. Therefore we should only update the palette from the new theme if we don't have our own already set. Task-number: QTBUG-52962 Change-Id: I4e2288efd82ad98b698cc09f26ad188064ec7b2a Reviewed-by: Giuseppe D'Angelo Reviewed-by: Friedemann Kleint --- src/gui/kernel/qguiapplication.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 834449fec6..dec701a17d 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -3567,7 +3567,8 @@ QPixmap QGuiApplicationPrivate::getPixmapCursor(Qt::CursorShape cshape) void QGuiApplicationPrivate::notifyThemeChanged() { - if (!(applicationResourceFlags & ApplicationPaletteExplicitlySet)) { + if (!(applicationResourceFlags & ApplicationPaletteExplicitlySet) && + !QCoreApplication::testAttribute(Qt::AA_SetPalette)) { clearPalette(); initPalette(); } -- cgit v1.2.3 From 3cc2884c031e0ab1098f59fae9aa6e05f54d36f8 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Mon, 30 May 2016 11:16:19 +0200 Subject: Fix defining QGuiApplication::sync() when QT_NO_SESSIONMANAGER is set sync() is unconditionally declared in the QGuiApplication header, but the definition was under QT_NO_SESSIONMANAGER guards. This commit moves the definition of sync() outside of the QT_NO_SESSIONMANAGER guards, since the sync code has nothing to do with session management. [ChangeLog][QtGui][QGuiApplication] Fixed a bug that would cause QGuiApplication::sync() to be left undefined for Qt builds without session management support. Change-Id: Ieb46f7c90c9193e89469126170117d9df672f4cb Task-number: QTBUG-51703 Reviewed-by: Thiago Macieira --- src/gui/kernel/qguiapplication.cpp | 44 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index dec701a17d..7b05ee562b 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -3275,28 +3275,6 @@ bool QGuiApplication::isSavingSession() const return d->is_saving_session; } -/*! - \since 5.2 - - Function that can be used to sync Qt state with the Window Systems state. - - This function will first empty Qts events by calling QCoreApplication::processEvents(), - then the platform plugin will sync up with the windowsystem, and finally Qts events - will be delived by another call to QCoreApplication::processEvents(); - - This function is timeconsuming and its use is discouraged. -*/ -void QGuiApplication::sync() -{ - QCoreApplication::processEvents(); - if (QGuiApplicationPrivate::platform_integration - && QGuiApplicationPrivate::platform_integration->hasCapability(QPlatformIntegration::SyncState)) { - QGuiApplicationPrivate::platform_integration->sync(); - QCoreApplication::processEvents(); - QWindowSystemInterface::flushWindowSystemEvents(); - } -} - void QGuiApplicationPrivate::commitData() { Q_Q(QGuiApplication); @@ -3321,6 +3299,28 @@ void QGuiApplicationPrivate::saveState() } #endif //QT_NO_SESSIONMANAGER +/*! + \since 5.2 + + Function that can be used to sync Qt state with the Window Systems state. + + This function will first empty Qts events by calling QCoreApplication::processEvents(), + then the platform plugin will sync up with the windowsystem, and finally Qts events + will be delived by another call to QCoreApplication::processEvents(); + + This function is timeconsuming and its use is discouraged. +*/ +void QGuiApplication::sync() +{ + QCoreApplication::processEvents(); + if (QGuiApplicationPrivate::platform_integration + && QGuiApplicationPrivate::platform_integration->hasCapability(QPlatformIntegration::SyncState)) { + QGuiApplicationPrivate::platform_integration->sync(); + QCoreApplication::processEvents(); + QWindowSystemInterface::flushWindowSystemEvents(); + } +} + /*! \property QGuiApplication::layoutDirection \brief the default layout direction for this application -- cgit v1.2.3 From 4927fdb389b9fbc0d5118437274d4fa3c59fc839 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 5 Jul 2016 15:13:44 +0200 Subject: Fix misleading code in QAbstractSpinBox::event() A static_cast never returns nullptr unless its argument already was nullptr. But we dereferenced 'event' already by the time we reach this code, so the if is always true. Fix by removing the temporary variable. Change-Id: Ia869d37eda74f0bcdd616e1f57f429cc86e9e525 Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qabstractspinbox.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index ba4bbe40a8..854befd265 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -751,8 +751,7 @@ bool QAbstractSpinBox::event(QEvent *event) case QEvent::HoverEnter: case QEvent::HoverLeave: case QEvent::HoverMove: - if (const QHoverEvent *he = static_cast(event)) - d->updateHoverControl(he->pos()); + d->updateHoverControl(static_cast(event)->pos()); break; case QEvent::ShortcutOverride: if (d->edit->event(event)) -- cgit v1.2.3 From a91d0dd369313dfa8865f99e590b868146cb4388 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 5 Jul 2016 15:11:43 +0200 Subject: Q_(U)INT64_C is not a type, so don't use it as if it was These expressions only work because they contain no non-parenthesized commas and an int literal is last. Fix by wrapping only the integer literal in Q_(U)INT64_C. Change-Id: I6b8e508b6c7c022f4b3342f65c26aab89ce17702 Reviewed-by: Thiago Macieira --- src/network/kernel/qauthenticator.cpp | 4 ++-- tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index 92d8779cab..1b9c0de6e1 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -1272,10 +1272,10 @@ static QByteArray qEncodeNtlmv2Response(const QAuthenticatorPrivate *ctx, // 369 years, 89 leap years // ((369 * 365) + 89) * 24 * 3600 = 11644473600 - time = Q_UINT64_C(currentTime.toTime_t() + 11644473600); + time = currentTime.toTime_t() + Q_UINT64_C(11644473600); // represented as 100 nano seconds - time = Q_UINT64_C(time * 10000000); + time = time * Q_UINT64_C(10000000); ds << time; } diff --git a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp index 77fc6ad6ae..c978761266 100644 --- a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp +++ b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp @@ -189,9 +189,9 @@ void tst_QRingBuffer::free() ringBuffer.append(QByteArray("01234", 5)); ringBuffer.free(1); - QCOMPARE(ringBuffer.size(), Q_INT64_C(4095 + 2048 + 5)); + QCOMPARE(ringBuffer.size(), Q_INT64_C(4095) + 2048 + 5); ringBuffer.free(4096); - QCOMPARE(ringBuffer.size(), Q_INT64_C(2047 + 5)); + QCOMPARE(ringBuffer.size(), Q_INT64_C(2047) + 5); ringBuffer.free(48); ringBuffer.free(2000); QCOMPARE(ringBuffer.size(), Q_INT64_C(4)); @@ -251,9 +251,9 @@ void tst_QRingBuffer::chop() ringBuffer.reserve(4096); ringBuffer.chop(1); - QCOMPARE(ringBuffer.size(), Q_INT64_C(5 + 2048 + 4095)); + QCOMPARE(ringBuffer.size(), Q_INT64_C(5) + 2048 + 4095); ringBuffer.chop(4096); - QCOMPARE(ringBuffer.size(), Q_INT64_C(5 + 2047)); + QCOMPARE(ringBuffer.size(), Q_INT64_C(5) + 2047); ringBuffer.chop(48); ringBuffer.chop(2000); QCOMPARE(ringBuffer.size(), Q_INT64_C(4)); -- cgit v1.2.3 From 631b143b3f6650b5761ac2c78e7936e1594b6e4f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 1 Jul 2016 17:28:37 +0200 Subject: QComboBox: fix crash on setEditable(false) called from editTextChanged() QLineEdit::setText() emits QLineEdit::textChanged(), which is connected to QComboBox::editTextChanged(). When a user slot connected to editTextChanged() sets QComboBox::editable to false, the line edit will be deleted in setEditable() and when control returns to QComboBoxPrivate::setCurrentIndex(), the formerly non-null 'lineEdit' has changed to nullptr, leading to a nullptr dereference when attempting to set the completionPrefix on lineEdit->completer(). Fix by re-checking 'lineEdit' after returning from the QLineEdit::setText() call. Add a test. Task-number: QTBUG-54191 Change-Id: I94154796cfde73fb490f8471c48b9d6f62825a92 Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qcombobox.cpp | 4 ++-- .../widgets/widgets/qcombobox/tst_qcombobox.cpp | 25 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 2abcd4d3c2..181671c493 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2100,9 +2100,9 @@ void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi) if (lineEdit) { const QString newText = itemText(normalized); if (lineEdit->text() != newText) { - lineEdit->setText(newText); + lineEdit->setText(newText); // may cause lineEdit -> nullptr (QTBUG-54191) #ifndef QT_NO_COMPLETER - if (lineEdit->completer()) + if (lineEdit && lineEdit->completer()) lineEdit->completer()->setCompletionPrefix(newText); #endif } diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index ae516639a6..15bf686699 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -161,6 +161,7 @@ private slots: void itemData(); void task_QTBUG_31146_popupCompletion(); void task_QTBUG_41288_completerChangesCurrentIndex(); + void task_QTBUG_54191_slotOnEditTextChangedSetsComboBoxToReadOnly(); void keyboardSelection(); void setCustomModelAndView(); void updateDelegateOnEditableChange(); @@ -3124,6 +3125,30 @@ void tst_QComboBox::task_QTBUG_41288_completerChangesCurrentIndex() } } +namespace { + struct SetReadOnly { + QComboBox *cb; + explicit SetReadOnly(QComboBox *cb) : cb(cb) {} + void operator()() const + { cb->setEditable(false); } + }; +} + +void tst_QComboBox::task_QTBUG_54191_slotOnEditTextChangedSetsComboBoxToReadOnly() +{ + QComboBox cb; + cb.addItems(QStringList() << "one" << "two"); + cb.setEditable(true); + cb.setCurrentIndex(0); + + connect(&cb, &QComboBox::editTextChanged, + SetReadOnly(&cb)); + + cb.setCurrentIndex(1); + // the real test is that it didn't crash... + QCOMPARE(cb.currentIndex(), 1); +} + void tst_QComboBox::keyboardSelection() { QComboBox comboBox; -- cgit v1.2.3 From 802c31bdbd4cd8d9a94bbd02ad1955d648682be7 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 5 Jul 2016 12:36:58 +0300 Subject: QDateTimeEdit: de-duplicate calls and cache results Change-Id: I32162846f5f412c7563e66015ea371f9a1af7748 Reviewed-by: Edward Welbourne --- src/widgets/widgets/qdatetimeedit.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index 795f2cedd9..b168c98410 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -248,9 +248,10 @@ void QDateTimeEdit::setDateTime(const QDateTime &datetime) Q_D(QDateTimeEdit); if (datetime.isValid()) { d->clearCache(); + const QDate date = datetime.date(); if (!(d->sections & DateSections_Mask)) - setDateRange(datetime.date(), datetime.date()); - d->setValue(QDateTime(datetime.date(), datetime.time(), d->spec), EmitIfChanged); + setDateRange(date, date); + d->setValue(QDateTime(date, datetime.time(), d->spec), EmitIfChanged); } } @@ -1770,15 +1771,18 @@ void QDateTimeEditPrivate::setSelected(int sectionIndex, bool forward) int QDateTimeEditPrivate::sectionAt(int pos) const { - if (pos < separators.first().size()) { + if (pos < separators.first().size()) return (pos == 0 ? FirstSectionIndex : NoSectionIndex); - } else if (displayText().size() - pos < separators.last().size() + 1) { + + const QString text = displayText(); + const int textSize = text.size(); + if (textSize - pos < separators.last().size() + 1) { if (separators.last().size() == 0) { return sectionNodes.count() - 1; } - return (pos == displayText().size() ? LastSectionIndex : NoSectionIndex); + return (pos == textSize ? LastSectionIndex : NoSectionIndex); } - updateCache(value, displayText()); + updateCache(value, text); for (int i=0; i= 0); - if (pos < separators.first().size()) { + if (pos < separators.first().size()) return forward ? 0 : FirstSectionIndex; - } else if (displayText().size() - pos < separators.last().size() + 1) { + + const QString text = displayText(); + if (text.size() - pos < separators.last().size() + 1) return forward ? LastSectionIndex : sectionNodes.size() - 1; - } - updateCache(value, displayText()); + + updateCache(value, text); for (int i=0; i Date: Wed, 29 Jun 2016 16:36:17 -0700 Subject: QCocoaTheme: Remove unreachable code The condition iconType != kGenericApplicationIcon is never false, therefore we will never execute the else statement. Consequently, overlyaIcon will always be null. This was triggered by the deprecation of ProcessSerialNumber related APIs since 10.9. Change-Id: If9eec1d2cc6e7e5b0c5323d4550f0c823a5eb0d8 Reviewed-by: Jake Petroules --- src/plugins/platforms/cocoa/qcocoatheme.mm | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 4b73d0af08..5c41c896b7 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -214,34 +214,14 @@ QPixmap QCocoaTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const } if (iconType != 0) { QPixmap pixmap; - IconRef icon; - IconRef overlayIcon = 0; - if (iconType != kGenericApplicationIcon) { - GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon); - } else { - FSRef fsRef; - ProcessSerialNumber psn = { 0, kCurrentProcess }; - GetProcessBundleLocation(&psn, &fsRef); - GetIconRefFromFileInfo(&fsRef, 0, 0, 0, 0, kIconServicesNormalUsageFlag, &icon, 0); - if (sp == MessageBoxCritical) { - overlayIcon = icon; - GetIconRef(kOnSystemDisk, kSystemIconsCreator, kAlertCautionIcon, &icon); - } - } + IconRef icon = Q_NULLPTR; + GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon); if (icon) { pixmap = qt_mac_convert_iconref(icon, size.width(), size.height()); ReleaseIconRef(icon); } - if (overlayIcon) { - QSizeF littleSize = size / 2; - QPixmap overlayPix = qt_mac_convert_iconref(overlayIcon, littleSize.width(), littleSize.height()); - QPainter painter(&pixmap); - painter.drawPixmap(littleSize.width(), littleSize.height(), overlayPix); - ReleaseIconRef(overlayIcon); - } - return pixmap; } -- cgit v1.2.3 From 16fefc258ec022b0c6828c70741c2c8c43a01f12 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 30 Jun 2016 16:21:59 -0700 Subject: Remove QCoreTextFontEngine::supportsColorGlyphs This is always true on the versions we currently support. Change-Id: I1aecbbd1f41e0f4f03b380358cd762ca00bb1e97 Reviewed-by: Jake Petroules Reviewed-by: Konstantin Ritt --- .../fontdatabases/mac/qcoretextfontdatabase.mm | 3 +-- .../fontdatabases/mac/qfontengine_coretext.mm | 9 ++------- .../fontdatabases/mac/qfontengine_coretext_p.h | 15 --------------- 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 0b9e7a7fe0..566abf2126 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -588,8 +588,7 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo fallbackList.append(familyNameFromPostScriptName(item)); } - if (QCoreTextFontEngine::supportsColorGlyphs()) - fallbackList.append(QLatin1String("Apple Color Emoji")); + fallbackList.append(QLatin1String("Apple Color Emoji")); // Since we are only returning a list of default fonts for the current language, we do not // cover all unicode completely. This was especially an issue for some of the common script diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 703ec3a8b8..7b459584ea 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -218,11 +218,9 @@ void QCoreTextFontEngine::init() synthesisFlags = 0; CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont); -#if defined(Q_OS_IOS) || MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (supportsColorGlyphs() && (traits & kCTFontColorGlyphsTrait)) + if (traits & kCTFontColorGlyphsTrait) glyphFormat = QFontEngine::Format_ARGB; else -#endif glyphFormat = defaultGlyphFormat; if (traits & kCTFontItalicTrait) @@ -648,9 +646,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y); CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &CGSizeZero, 1); } - } -#if defined(Q_OS_IOS) || MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - else if (supportsColorGlyphs()) { + } else { // CGContextSetTextMatrix does not work with color glyphs, so we use // the CTM instead. This means we must translate the CTM as well, to // set the glyph position, instead of using CGContextSetTextPosition. @@ -661,7 +657,6 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition // glyphs in the Apple Color Emoji font, so we use CTFontDrawGlyphs instead. CTFontDrawGlyphs(ctfont, &cgGlyph, &CGPointZero, 1, ctx); } -#endif CGContextRelease(ctx); CGColorSpaceRelease(colorspace); diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index 746c9051a0..0cfa6ed6d3 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -106,21 +106,6 @@ public: QFontEngine::Properties properties() const Q_DECL_OVERRIDE; - static bool supportsColorGlyphs() - { -#if defined(Q_OS_IOS) - return true; -#elif MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - #if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 - return &CTFontDrawGlyphs; - #else - return true; - #endif -#else - return false; -#endif - } - static bool ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length); static QFont::Weight qtWeightFromCFWeight(float value); -- cgit v1.2.3 From 1575f2fc3cf74035716f2dc0c31442d77f136561 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 10 Jun 2016 11:03:44 -0700 Subject: XCB: Update the high DPI scaling in more conditions I don't think fae8ee8b428ae7a406199e504b2d0eedd5059dbd was enough. I've started getting small fonts in Qt Creator under some other circumstances. Change-Id: I1cc7601489634e96833cfffd1456caea823aa84a Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index b5c5028995..29a2cfb57a 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -258,8 +258,8 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) } else { screen = createScreen(virtualDesktop, output, outputInfo.data()); qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled"; - QHighDpiScaling::updateHighDpiScaling(); } + QHighDpiScaling::updateHighDpiScaling(); } } else if (screen) { if (output.crtc == XCB_NONE && output.mode == XCB_NONE) { -- cgit v1.2.3 From abc29084fadf9c7d936fca55d02323090d9986cc Mon Sep 17 00:00:00 2001 From: Roger Maclean Date: Wed, 29 Oct 2014 11:06:20 -0400 Subject: QNX: Ensure invisible 1x1 raster windows are posted. Non-top level raster windows still have screen windows associated with them though they are not intended to be visible. This causes problems if they have children (as they do when QGLWidgets are used) since their children will also not be visible. So, if we have a window with a parent, force them to post but set the transparency to discard so they remain invisible. This allows the example hellogl_es2 to run correctly. Change-Id: I67e24dc59b29ce789376498c2477349fa50020e1 Reviewed-by: Rafael Roquetto --- src/plugins/platforms/qnx/qqnxrasterwindow.cpp | 9 ++++++++- src/plugins/platforms/qnx/qqnxwindow.cpp | 7 ++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp index 933fce0e33..a764bba00e 100644 --- a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp @@ -172,7 +172,7 @@ void QQnxRasterWindow::adjustBufferSize() { // When having a raster window we don't need any buffers, since // Qt will draw to the parent TLW backing store. - const QSize windowSize = window()->parent() ? QSize(1,1) : window()->size(); + const QSize windowSize = window()->parent() ? QSize(0,0) : window()->size(); if (windowSize != bufferSize()) setBufferSize(windowSize); } @@ -188,6 +188,13 @@ void QQnxRasterWindow::resetBuffers() m_currentBufferIndex = -1; m_previousDirty = QRegion(); m_scrolled = QRegion(); + if (window()->parent() && bufferSize() == QSize(1,1)) { + // If we have a parent then we're not really rendering. But if we don't render we'll + // be invisible and any children won't show up. This should be harmless since we're + // rendering into a 1x1 window that has transparency set to discard. + renderBuffer(); + post(QRegion(0,0,1,1)); + } } void QQnxRasterWindow::blitPreviousToCurrent(const QRegion ®ion, int dx, int dy, bool flush) diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 4dc1248bd1..da2929d4c0 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -386,7 +386,12 @@ void QQnxWindow::setBufferSize(const QSize &size) // Set the transparency. According to QNX technical support, setting the window // transparency property should always be done *after* creating the window // buffers in order to guarantee the property is paid attention to. - if (window()->requestedFormat().alphaBufferSize() == 0) { + if (size.isEmpty()) { + // We can't create 0x0 buffers and instead make them 1x1. But to allow these windows to + // still be 'visible' (thus allowing their children to be visible), we need to allow + // them to be posted but still not show up. + val[0] = SCREEN_TRANSPARENCY_DISCARD; + } else if (window()->requestedFormat().alphaBufferSize() == 0) { // To avoid overhead in the composition manager, disable blending // when the underlying window buffer doesn't have an alpha channel. val[0] = SCREEN_TRANSPARENCY_NONE; -- cgit v1.2.3 From 5dc739ba9b09326bf113bb7f4ce9aa45fe671c6b Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 5 Jul 2016 16:25:40 +0300 Subject: Replace QString::trimmed() with QStringRef::trimmed() ... where it's possible. Reduce allocations. Change-Id: I023adfd316f94948fe50749f60bf55748dca56e2 Reviewed-by: Edward Welbourne --- src/gui/text/qtexthtmlparser.cpp | 8 ++++---- src/network/access/qftp.cpp | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 103a208c26..50df8daa5e 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -1418,16 +1418,16 @@ static bool setFloatAttribute(qreal *destination, const QString &value) return ok; } -static void setWidthAttribute(QTextLength *width, QString value) +static void setWidthAttribute(QTextLength *width, const QString &valueStr) { bool ok = false; - qreal realVal = value.toDouble(&ok); + qreal realVal = valueStr.toDouble(&ok); if (ok) { *width = QTextLength(QTextLength::FixedLength, realVal); } else { - value = value.trimmed(); + QStringRef value = QStringRef(&valueStr).trimmed(); if (!value.isEmpty() && value.endsWith(QLatin1Char('%'))) { - value.chop(1); + value.truncate(value.size() - 1); realVal = value.toDouble(&ok); if (ok) *width = QTextLength(QTextLength::PercentageLength, realVal); diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index 19b519243c..7b6f830333 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -2034,7 +2034,7 @@ int QFtp::rename(const QString &oldname, const QString &newname) */ int QFtp::rawCommand(const QString &command) { - QString cmd = command.trimmed() + QLatin1String("\r\n"); + const QString cmd = QStringRef(&command).trimmed() + QLatin1String("\r\n"); return d_func()->addCommand(new QFtpCommand(RawCommand, QStringList(cmd))); } @@ -2253,8 +2253,8 @@ void QFtpPrivate::_q_startNextCommand() // Proxy support, replace the Login argument in place, then fall // through. if (c->command == QFtp::Login && !proxyHost.isEmpty()) { - QString loginString = c->rawCmds.constFirst().trimmed(); - loginString += QLatin1Char('@') + host; + QString loginString; + loginString += QStringRef(&c->rawCmds.constFirst()).trimmed() + QLatin1Char('@') + host; if (port && port != 21) loginString += QLatin1Char(':') + QString::number(port); loginString += QLatin1String("\r\n"); -- cgit v1.2.3 From 3658354a7de9615bdf03b49736fea3ec41cecd77 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Sat, 2 Jul 2016 13:48:45 +0200 Subject: OpenBSD: redefine g++/gcc commands to eg++/egcc to use newer gcc 4.9 On OpenBSD, the system compiler shipped is still gcc 4.2.1 but for proper C++11 support in Qt, QtCreator and Qt-based projects we need to use the compilers provided in ports/packages which have the binaries renamed to eg++/egcc. Therefore, redefine the variables from g++-base.conf to use the newer compilers. Change-Id: Ic8ea1c5d2c2c0263dad5ae85c8c747bcd3985b7d Reviewed-by: Oswald Buddenhagen --- mkspecs/openbsd-g++/qmake.conf | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/mkspecs/openbsd-g++/qmake.conf b/mkspecs/openbsd-g++/qmake.conf index e7ac523486..4232759997 100644 --- a/mkspecs/openbsd-g++/qmake.conf +++ b/mkspecs/openbsd-g++/qmake.conf @@ -20,6 +20,21 @@ QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib include(../common/gcc-base-unix.conf) include(../common/g++-unix.conf) +# System compiler is gcc 4.2.1 up to OpenBSD 6.0. +# For proper C++11 support, we need to use a newer gcc from ports/packages, +# where compiler commands are renamed to egcc/eg++. Therefore, redefine +# mkspecs/common/g++-base.conf compiler commands +QMAKE_CC = egcc + +QMAKE_LINK_C = $$QMAKE_CC +QMAKE_LINK_C_SHLIB = $$QMAKE_CC + +QMAKE_CXX = eg++ + +QMAKE_LINK = $$QMAKE_CXX +QMAKE_LINK_SHLIB = $$QMAKE_CXX + + # Reset g++-unix.conf's NOUNDEF flags as OpenBSD libc can't handle environ QMAKE_LFLAGS_NOUNDEF = -- cgit v1.2.3 From b6c10cf33107309f13c9845495d9d7d4f45f34bf Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Mon, 4 Jul 2016 15:21:19 +0200 Subject: Improve lookup speed for QAccessible::uniqueId When QAccessible::uniqueId was called, it would call QHash::key(), which has linear time performance. This can cause application slowdown if a big number of QAccessibleInterface Ids have to be found. The patch adds an additional QHash to keep track of the inverse relationship from QAccessibleInterface pointers to their Ids. Change-Id: I975e3dc0e6c628e2ea701323d8b87184ad133cfb Task-number: QTBUG-54491 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Frederik Gladhorn --- src/gui/accessible/qaccessible.cpp | 4 ++-- src/gui/accessible/qaccessiblecache.cpp | 9 ++++++++- src/gui/accessible/qaccessiblecache_p.h | 2 ++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 4731e8a240..658e0f26ba 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -755,7 +755,7 @@ void QAccessible::deleteAccessibleInterface(Id id) */ QAccessible::Id QAccessible::uniqueId(QAccessibleInterface *iface) { - Id id = QAccessibleCache::instance()->idToInterface.key(iface); + Id id = QAccessibleCache::instance()->idForInterface(iface); if (!id) id = registerAccessibleInterface(iface); return id; @@ -768,7 +768,7 @@ QAccessible::Id QAccessible::uniqueId(QAccessibleInterface *iface) */ QAccessibleInterface *QAccessible::accessibleInterface(Id id) { - return QAccessibleCache::instance()->idToInterface.value(id); + return QAccessibleCache::instance()->interfaceForId(id); } diff --git a/src/gui/accessible/qaccessiblecache.cpp b/src/gui/accessible/qaccessiblecache.cpp index 0b9366631c..5fae442370 100644 --- a/src/gui/accessible/qaccessiblecache.cpp +++ b/src/gui/accessible/qaccessiblecache.cpp @@ -77,6 +77,11 @@ QAccessibleInterface *QAccessibleCache::interfaceForId(QAccessible::Id id) const return idToInterface.value(id); } +QAccessible::Id QAccessibleCache::idForInterface(QAccessibleInterface *iface) const +{ + return interfaceToId.value(iface); +} + QAccessible::Id QAccessibleCache::insert(QObject *object, QAccessibleInterface *iface) const { Q_ASSERT(iface); @@ -84,7 +89,7 @@ QAccessible::Id QAccessibleCache::insert(QObject *object, QAccessibleInterface * // object might be 0 Q_ASSERT(!objectToId.contains(object)); - Q_ASSERT_X(!idToInterface.values().contains(iface), "", "Accessible interface inserted into cache twice!"); + Q_ASSERT_X(!interfaceToId.contains(iface), "", "Accessible interface inserted into cache twice!"); QAccessible::Id id = acquireId(); QObject *obj = iface->object(); @@ -94,6 +99,7 @@ QAccessible::Id QAccessibleCache::insert(QObject *object, QAccessibleInterface * connect(obj, &QObject::destroyed, this, &QAccessibleCache::objectDestroyed); } idToInterface.insert(id, iface); + interfaceToId.insert(iface, id); return id; } @@ -109,6 +115,7 @@ void QAccessibleCache::objectDestroyed(QObject* obj) void QAccessibleCache::deleteInterface(QAccessible::Id id, QObject *obj) { QAccessibleInterface *iface = idToInterface.take(id); + interfaceToId.take(iface); if (!obj) obj = iface->object(); if (obj) diff --git a/src/gui/accessible/qaccessiblecache_p.h b/src/gui/accessible/qaccessiblecache_p.h index ffaccbca42..bb33ea2cd4 100644 --- a/src/gui/accessible/qaccessiblecache_p.h +++ b/src/gui/accessible/qaccessiblecache_p.h @@ -64,6 +64,7 @@ class Q_GUI_EXPORT QAccessibleCache :public QObject public: static QAccessibleCache *instance(); QAccessibleInterface *interfaceForId(QAccessible::Id id) const; + QAccessible::Id idForInterface(QAccessibleInterface *iface) const; QAccessible::Id insert(QObject *object, QAccessibleInterface *iface) const; void deleteInterface(QAccessible::Id id, QObject *obj = 0); @@ -79,6 +80,7 @@ private: QAccessible::Id acquireId() const; mutable QHash idToInterface; + mutable QHash interfaceToId; mutable QHash objectToId; #ifdef Q_OS_MAC -- cgit v1.2.3 From b36c6bab8db724a59f69e5205e031cccf4520ab7 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Thu, 7 Jul 2016 14:36:38 +0300 Subject: QString: add auto test for chop() Change-Id: I8fc65c65776a64cc92e8cba3993d17746be81ba1 Reviewed-by: Edward Welbourne --- tests/auto/corelib/tools/qstring/tst_qstring.cpp | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index a922e3ad27..601987086d 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -482,6 +482,7 @@ private slots: void sprintf(); void fill(); void truncate(); + void chop(); void constructor(); void constructorQByteArray_data(); void constructorQByteArray(); @@ -1221,6 +1222,31 @@ void tst_QString::truncate() } +void tst_QString::chop() +{ + const QString original("abcd"); + + QString str = original; + str.chop(1); + QCOMPARE(str, QLatin1String("abc")); + + str = original; + str.chop(0); + QCOMPARE(str, original); + + str = original; + str.chop(-1); + QCOMPARE(str, original); + + str = original; + str.chop(original.size()); + QVERIFY(str.isEmpty()); + + str = original; + str.chop(1000); + QVERIFY(str.isEmpty()); +} + void tst_QString::fill() { QString e; -- cgit v1.2.3 From 145d8462e3daa96b49a921fd4a34cf4dc84071d4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 30 Jun 2016 11:14:22 +0200 Subject: Windows QPA: Accept foreign windows when checking for wheel receivers After change 14efcaa3921687129d4dca9b7d5794668a329cd6, foreign windows no longer have a corresponding QWindowsWindow. This should not block wheel events when checking for blocking modal windows. Amends change 14efcaa3921687129d4dca9b7d5794668a329cd6. Task-number: QTBUG-54430 Change-Id: I1ac87445844946bafc214024e27da08c4f884d79 Reviewed-by: Tim Blechmann Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowsmousehandler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index 78fff65d84..b92387d397 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -393,6 +393,8 @@ static bool isValidWheelReceiver(QWindow *candidate) { if (candidate) { const QWindow *toplevel = QWindowsWindow::topLevelOf(candidate); + if (toplevel->type() == Qt::ForeignWindow) + return true; if (const QWindowsWindow *ww = QWindowsWindow::windowsWindowOf(toplevel)) return !ww->testFlag(QWindowsWindow::BlockedByModal); } -- cgit v1.2.3 From c8aa7eda3abfba9004eb70db571c7c537494b7f0 Mon Sep 17 00:00:00 2001 From: Boris Pek Date: Sun, 19 Jun 2016 03:15:43 +0300 Subject: Fix build of the minimal platform plugin for MS Windows when qtbase is configured with -fontconfig and -system-freetype. This fix is necessary after 060e0f6628fd185994911307c59f5355acaaf18f. Used the same approach as in 16864c42d6bc0ee6b3e3fa03123ef5884557ceea. Change-Id: Idece0dc11d89e38266c95de1769be751c06324ef Reviewed-by: Friedemann Kleint --- src/plugins/platforms/minimal/minimal.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/minimal/minimal.pro b/src/plugins/platforms/minimal/minimal.pro index bd6f2d8e6f..3aca27b555 100644 --- a/src/plugins/platforms/minimal/minimal.pro +++ b/src/plugins/platforms/minimal/minimal.pro @@ -11,7 +11,7 @@ HEADERS = qminimalintegration.h \ OTHER_FILES += minimal.json CONFIG += qpa/genericunixfontdatabase -darwin: DEFINES += QT_NO_FONTCONFIG +win32|darwin: DEFINES += QT_NO_FONTCONFIG PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QMinimalIntegrationPlugin -- cgit v1.2.3 From 14c6f80f4b2d8275037ed1fc3c63870e7f21570a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 1 Jul 2016 16:18:41 +0200 Subject: Testlib: Replace QString::arg() formatting by snprintf() Formatting of values needs to be fast since QTestlib always pessimistically formats the values passed to QCOMPARE even if they match. Speeds up tst_qrect by factor 1.5..2. Task-number: QTBUG-38890 Change-Id: I3627db77a305a46c1d51a14c04b88db8018faa60 Reviewed-by: Edward Welbourne --- src/testlib/qtest.h | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index 8da16af91e..a8cc02710e 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -101,37 +101,57 @@ template<> inline char *toString(const QDateTime &dateTime) template<> inline char *toString(const QChar &c) { + const ushort uc = c.unicode(); + if (uc < 128) { + char msg[32] = {'\0'}; + qsnprintf(msg, sizeof(msg), "QChar: '%c' (0x%x)", char(uc), unsigned(uc)); + return qstrdup(msg); + } return qstrdup(qPrintable(QString::fromLatin1("QChar: '%1' (0x%2)").arg(c).arg(QString::number(static_cast(c.unicode()), 16)))); } template<> inline char *toString(const QPoint &p) { - return qstrdup(QString::fromLatin1("QPoint(%1,%2)").arg(p.x()).arg(p.y()).toLatin1().constData()); + char msg[128] = {'\0'}; + qsnprintf(msg, sizeof(msg), "QPoint(%d,%d)", p.x(), p.y()); + return qstrdup(msg); } template<> inline char *toString(const QSize &s) { - return qstrdup(QString::fromLatin1("QSize(%1x%2)").arg(s.width()).arg(s.height()).toLatin1().constData()); + char msg[128] = {'\0'}; + qsnprintf(msg, sizeof(msg), "QSize(%dx%d)", s.width(), s.height()); + return qstrdup(msg); } template<> inline char *toString(const QRect &s) { - return qstrdup(QString::fromLatin1("QRect(%1,%2 %5x%6) (bottomright %3,%4)").arg(s.left()).arg(s.top()).arg(s.right()).arg(s.bottom()).arg(s.width()).arg(s.height()).toLatin1().constData()); + char msg[256] = {'\0'}; + qsnprintf(msg, sizeof(msg), "QRect(%d,%d %dx%d) (bottomright %d,%d)", + s.left(), s.top(), s.width(), s.height(), s.right(), s.bottom()); + return qstrdup(msg); } template<> inline char *toString(const QPointF &p) { - return qstrdup(QString::fromLatin1("QPointF(%1,%2)").arg(p.x()).arg(p.y()).toLatin1().constData()); + char msg[64] = {'\0'}; + qsnprintf(msg, sizeof(msg), "QPointF(%g,%g)", p.x(), p.y()); + return qstrdup(msg); } template<> inline char *toString(const QSizeF &s) { - return qstrdup(QString::fromLatin1("QSizeF(%1x%2)").arg(s.width()).arg(s.height()).toLatin1().constData()); + char msg[64] = {'\0'}; + qsnprintf(msg, sizeof(msg), "QSizeF(%gx%g)", s.width(), s.height()); + return qstrdup(msg); } template<> inline char *toString(const QRectF &s) { - return qstrdup(QString::fromLatin1("QRectF(%1,%2 %5x%6) (bottomright %3,%4)").arg(s.left()).arg(s.top()).arg(s.right()).arg(s.bottom()).arg(s.width()).arg(s.height()).toLatin1().constData()); + char msg[256] = {'\0'}; + qsnprintf(msg, sizeof(msg), "QRectF(%g,%g %gx%g) (bottomright %g,%g)", + s.left(), s.top(), s.width(), s.height(), s.right(), s.bottom()); + return qstrdup(msg); } template<> inline char *toString(const QUrl &uri) -- cgit v1.2.3 From deb2728a8677b275613668d1467b636ed1776282 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 7 Jul 2016 15:23:20 +0200 Subject: [macOS] Check that the screen's index is still valid after updating It is possible for a screen to be disconnected while it is doing an update of the available screens. Therefore before returning the pointer to the screen then it should be rechecked that the index is still within the range of available screens. Change-Id: Iaa08070e79a72cb309d8a24cea786a5dccf6b719 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoaintegration.mm | 4 ++++ src/plugins/platforms/cocoa/qnsview.mm | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 933160b2ca..659c803a19 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -450,6 +450,10 @@ QCocoaScreen *QCocoaIntegration::screenAtIndex(int index) if (index >= mScreens.count()) updateScreens(); + // It is possible that the screen got removed while updateScreens was called + // so we do a sanity check to be certain + if (index >= mScreens.count()) + return 0; return mScreens.at(index); } diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 4e482fb146..913ce08d17 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -469,7 +469,8 @@ QT_WARNING_POP NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen]; if (screenIndex != NSNotFound) { QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex); - QWindowSystemInterface::handleWindowScreenChanged(m_window, cocoaScreen->screen()); + if (cocoaScreen) + QWindowSystemInterface::handleWindowScreenChanged(m_window, cocoaScreen->screen()); m_platformWindow->updateExposedGeometry(); } } -- cgit v1.2.3 From 2788fccd29fba84bca7581778f5bc683736f1d0e Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Wed, 6 Jul 2016 11:32:54 +0300 Subject: Use QStringLiteral more judiciously Replace it with QL1S in QStringBuilder expressions and in overloaded functions. Replace patterns 'QString::number() + QStringLiteral' and 'QStringLiteral + QString::number()' with QString::asprintf. Saves some text size. Change-Id: Ib39b2332264dfc3df04e77f2c101b47a1030cef4 Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/corelib/global/qlogging.cpp | 10 +++++----- src/corelib/io/qfileselector.cpp | 2 +- src/corelib/io/qurl.cpp | 4 ++-- src/corelib/io/qurlidna.cpp | 2 +- src/corelib/tools/qdatetime.cpp | 2 +- src/gui/kernel/qplatformintegrationfactory.cpp | 2 +- src/gui/kernel/qplatformthemefactory.cpp | 2 +- src/gui/text/qtextimagehandler.cpp | 2 +- src/network/ssl/qsslsocket_mac.cpp | 2 +- src/platformsupport/dbustray/qdbustrayicon.cpp | 4 ++-- src/platformsupport/input/tslib/qtslib.cpp | 2 +- .../services/genericunix/qgenericunixservices.cpp | 4 ++-- .../themes/genericunix/qgenericunixthemes.cpp | 14 +++++++------- .../compose/generator/qtablegenerator.cpp | 2 +- .../platforms/eglfs/qeglfsdeviceintegration.cpp | 2 +- src/plugins/platforms/windows/qwindowscontext.cpp | 21 +++++++++++---------- src/plugins/platforms/windows/qwindowsmime.cpp | 2 +- src/plugins/platforms/windows/qwindowsservices.cpp | 7 +++---- .../platforms/windows/qwindowstabletsupport.cpp | 6 +++--- src/plugins/platforms/windows/qwindowstheme.cpp | 2 +- src/plugins/platforms/winrt/qwinrtclipboard.cpp | 2 +- src/testlib/qtest.h | 2 +- src/testlib/qtestcase.cpp | 2 +- src/widgets/accessible/qaccessiblewidgets.cpp | 12 ++++++------ src/winmain/qtmain_winrt.cpp | 2 +- src/xml/sax/qxml.cpp | 3 +-- 26 files changed, 58 insertions(+), 59 deletions(-) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index f2e293c45b..49a8aa0df1 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1123,7 +1123,7 @@ void QMessagePattern::setPattern(const QString &pattern) if (m.hasMatch()) { int depth = m.capturedRef(1).toInt(); if (depth <= 0) - error += QStringLiteral("QT_MESSAGE_PATTERN: %{backtrace} depth must be a number greater than 0\n"); + error += QLatin1String("QT_MESSAGE_PATTERN: %{backtrace} depth must be a number greater than 0\n"); else backtraceDepth = depth; } @@ -1135,7 +1135,7 @@ void QMessagePattern::setPattern(const QString &pattern) backtraceParams.backtraceSeparator = backtraceSeparator; backtraceArgs.append(backtraceParams); #else - error += QStringLiteral("QT_MESSAGE_PATTERN: %{backtrace} is not supported by this Qt build\n"); + error += QLatin1String("QT_MESSAGE_PATTERN: %{backtrace} is not supported by this Qt build\n"); #endif } @@ -1156,7 +1156,7 @@ void QMessagePattern::setPattern(const QString &pattern) else if (lexeme == QLatin1String(endifTokenC)) { tokens[i] = endifTokenC; if (!inIf && !nestedIfError) - error += QStringLiteral("QT_MESSAGE_PATTERN: %{endif} without an %{if-*}\n"); + error += QLatin1String("QT_MESSAGE_PATTERN: %{endif} without an %{if-*}\n"); inIf = false; } else { tokens[i] = emptyTokenC; @@ -1172,9 +1172,9 @@ void QMessagePattern::setPattern(const QString &pattern) } } if (nestedIfError) - error += QStringLiteral("QT_MESSAGE_PATTERN: %{if-*} cannot be nested\n"); + error += QLatin1String("QT_MESSAGE_PATTERN: %{if-*} cannot be nested\n"); else if (inIf) - error += QStringLiteral("QT_MESSAGE_PATTERN: missing %{endif}\n"); + error += QLatin1String("QT_MESSAGE_PATTERN: missing %{endif}\n"); if (!error.isEmpty()) { #if defined(Q_OS_WINCE) || defined(Q_OS_WINRT) OutputDebugString(reinterpret_cast(error.utf16())); diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp index 29ef0f937e..b2f4b6931f 100644 --- a/src/corelib/io/qfileselector.cpp +++ b/src/corelib/io/qfileselector.cpp @@ -387,7 +387,7 @@ QStringList QFileSelectorPrivate::platformSelectors() # endif QString productName = QSysInfo::productType(); # ifdef Q_OS_MACOS - if (productName != QStringLiteral("osx")) + if (productName != QLatin1String("osx")) ret << QStringLiteral("osx"); // compatibility # endif if (productName != QLatin1String("unknown")) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index bd2f9de66c..fd2127bce3 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -819,7 +819,7 @@ static const ushort * const fragmentInUrl = userNameInUrl + 6; static inline void parseDecodedComponent(QString &data) { - data.replace(QLatin1Char('%'), QStringLiteral("%25")); + data.replace(QLatin1Char('%'), QLatin1String("%25")); } static inline QString @@ -1477,7 +1477,7 @@ QString QUrlPrivate::toLocalFile(QUrl::FormattingOptions options) const // magic for shared drive on windows if (!host.isEmpty()) { - tmp = QStringLiteral("//") + host; + tmp = QLatin1String("//") + host; #ifdef Q_OS_WIN // QTBUG-42346, WebDAV is visible as local file on Windows only. if (scheme == webDavScheme()) tmp += webDavSslTag(); diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp index 11b2280cd1..16bb924b17 100644 --- a/src/corelib/io/qurlidna.cpp +++ b/src/corelib/io/qurlidna.cpp @@ -2269,7 +2269,7 @@ Q_AUTOTEST_EXPORT void qt_punycodeEncoder(const QChar *s, int ucLength, QString } // prepend ACE prefix - output->insert(outLen, QStringLiteral("xn--")); + output->insert(outLen, QLatin1String("xn--")); return; } diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index b296361146..a8010af74c 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -3581,7 +3581,7 @@ QString QDateTime::toString(Qt::DateFormat format) const .arg(tm.toString(Qt::TextDate)) .arg(dt.year()); if (timeSpec() != Qt::LocalTime) { - buf += QStringLiteral(" GMT"); + buf += QLatin1String(" GMT"); if (d->m_spec == Qt::OffsetFromUTC) buf += toOffsetString(Qt::TextDate, d->m_offsetFromUtc); } diff --git a/src/gui/kernel/qplatformintegrationfactory.cpp b/src/gui/kernel/qplatformintegrationfactory.cpp index 566d025b28..1e04a673eb 100644 --- a/src/gui/kernel/qplatformintegrationfactory.cpp +++ b/src/gui/kernel/qplatformintegrationfactory.cpp @@ -86,7 +86,7 @@ QStringList QPlatformIntegrationFactory::keys(const QString &platformPluginPath) QCoreApplication::addLibraryPath(platformPluginPath); list = directLoader()->keyMap().values(); if (!list.isEmpty()) { - const QString postFix = QStringLiteral(" (from ") + const QString postFix = QLatin1String(" (from ") + QDir::toNativeSeparators(platformPluginPath) + QLatin1Char(')'); const QStringList::iterator end = list.end(); diff --git a/src/gui/kernel/qplatformthemefactory.cpp b/src/gui/kernel/qplatformthemefactory.cpp index 40ba844e57..223d7344e3 100644 --- a/src/gui/kernel/qplatformthemefactory.cpp +++ b/src/gui/kernel/qplatformthemefactory.cpp @@ -88,7 +88,7 @@ QStringList QPlatformThemeFactory::keys(const QString &platformPluginPath) QCoreApplication::addLibraryPath(platformPluginPath); list += directLoader()->keyMap().values(); if (!list.isEmpty()) { - const QString postFix = QStringLiteral(" (from ") + const QString postFix = QLatin1String(" (from ") + QDir::toNativeSeparators(platformPluginPath) + QLatin1Char(')'); const QStringList::iterator end = list.end(); diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp index acd18994ad..18311ed161 100644 --- a/src/gui/text/qtextimagehandler.cpp +++ b/src/gui/text/qtextimagehandler.cpp @@ -111,7 +111,7 @@ static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format, con doc->addResource(QTextDocument::ImageResource, url, pm); } - if (name.contains(QStringLiteral("@2x"))) + if (name.contains(QLatin1String("@2x"))) pm.setDevicePixelRatio(sourcePixelRatio); return pm; diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 3845a3d455..ba346f77d1 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -468,7 +468,7 @@ long QSslSocketPrivate::sslLibraryVersionNumber() QString QSslSocketPrivate::sslLibraryVersionString() { - return QStringLiteral("Secure Transport, ") + QSysInfo::prettyProductName(); + return QLatin1String("Secure Transport, ") + QSysInfo::prettyProductName(); } long QSslSocketPrivate::sslLibraryBuildVersionNumber() diff --git a/src/platformsupport/dbustray/qdbustrayicon.cpp b/src/platformsupport/dbustray/qdbustrayicon.cpp index 724992f348..da368bf9b7 100644 --- a/src/platformsupport/dbustray/qdbustrayicon.cpp +++ b/src/platformsupport/dbustray/qdbustrayicon.cpp @@ -66,7 +66,7 @@ Q_LOGGING_CATEGORY(qLcTray, "qt.qpa.tray") static const QString KDEItemFormat = QStringLiteral("org.kde.StatusNotifierItem-%1-%2"); static const QString KDEWatcherService = QStringLiteral("org.kde.StatusNotifierWatcher"); -static const QString TempFileTemplate = QDir::tempPath() + QStringLiteral("/qt-trayicon-XXXXXX.png"); +static const QString TempFileTemplate = QDir::tempPath() + QLatin1String("/qt-trayicon-XXXXXX.png"); static const QString XdgNotificationService = QStringLiteral("org.freedesktop.Notifications"); static const QString XdgNotificationPath = QStringLiteral("/org/freedesktop/Notifications"); static const QString DefaultAction = QStringLiteral("default"); @@ -156,7 +156,7 @@ QTemporaryFile *QDBusTrayIcon::tempIcon(const QIcon &icon) QDBusConnection session = QDBusConnection::sessionBus(); uint pid = session.interface()->servicePid(KDEWatcherService).value(); QString processName = QLockFilePrivate::processNameByPid(pid); - necessary = processName.endsWith(QStringLiteral("indicator-application-service")); + necessary = processName.endsWith(QLatin1String("indicator-application-service")); necessity_checked = true; } if (!necessary) diff --git a/src/platformsupport/input/tslib/qtslib.cpp b/src/platformsupport/input/tslib/qtslib.cpp index ed21cc1cef..75ac3c50e0 100644 --- a/src/platformsupport/input/tslib/qtslib.cpp +++ b/src/platformsupport/input/tslib/qtslib.cpp @@ -64,7 +64,7 @@ QTsLibMouseHandler::QTsLibMouseHandler(const QString &key, QByteArray device = qgetenv("TSLIB_TSDEVICE"); - if (specification.startsWith(QStringLiteral("/dev/"))) + if (specification.startsWith(QLatin1String("/dev/"))) device = specification.toLocal8Bit(); if (device.isEmpty()) diff --git a/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/src/platformsupport/services/genericunix/qgenericunixservices.cpp index 727da3132a..5242f00193 100644 --- a/src/platformsupport/services/genericunix/qgenericunixservices.cpp +++ b/src/platformsupport/services/genericunix/qgenericunixservices.cpp @@ -101,7 +101,7 @@ static inline bool detectWebBrowser(const QByteArray &desktop, if (desktop == QByteArray("KDE")) { // Konqueror launcher if (checkExecutable(QStringLiteral("kfmclient"), browser)) { - browser->append(QStringLiteral(" exec")); + browser->append(QLatin1String(" exec")); return true; } } else if (desktop == QByteArray("GNOME")) { @@ -121,7 +121,7 @@ static inline bool launch(const QString &launcher, const QUrl &url) if (debug) qDebug("Launching %s", qPrintable(command)); #if defined(QT_NO_PROCESS) - const bool ok = ::system(qPrintable(command + QStringLiteral(" &"))); + const bool ok = ::system(qPrintable(command + QLatin1String(" &"))); #else const bool ok = QProcess::startDetached(command); #endif diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp index 5e5c931c2c..9abcd04063 100644 --- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp +++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp @@ -170,7 +170,7 @@ QStringList QGenericUnixTheme::xdgIconThemePaths() { QStringList paths; // Add home directory first in search path - const QFileInfo homeIconDir(QDir::homePath() + QStringLiteral("/.icons")); + const QFileInfo homeIconDir(QDir::homePath() + QLatin1String("/.icons")); if (homeIconDir.isDir()) paths.prepend(homeIconDir.absoluteFilePath()); @@ -247,8 +247,8 @@ public: static QString kdeGlobals(const QString &kdeDir, int kdeVersion) { if (kdeVersion > 4) - return kdeDir + QStringLiteral("/kdeglobals"); - return kdeDir + QStringLiteral("/share/config/kdeglobals"); + return kdeDir + QLatin1String("/kdeglobals"); + return kdeDir + QLatin1String("/share/config/kdeglobals"); } void refresh(); @@ -559,22 +559,22 @@ QPlatformTheme *QKdeTheme::createKdeTheme() if (!kdeDirsVar.isEmpty()) kdeDirs += kdeDirsVar.split(QLatin1Char(':'), QString::SkipEmptyParts); - const QString kdeVersionHomePath = QDir::homePath() + QStringLiteral("/.kde") + QLatin1String(kdeVersionBA); + const QString kdeVersionHomePath = QDir::homePath() + QLatin1String("/.kde") + QLatin1String(kdeVersionBA); if (QFileInfo(kdeVersionHomePath).isDir()) kdeDirs += kdeVersionHomePath; - const QString kdeHomePath = QDir::homePath() + QStringLiteral("/.kde"); + const QString kdeHomePath = QDir::homePath() + QLatin1String("/.kde"); if (QFileInfo(kdeHomePath).isDir()) kdeDirs += kdeHomePath; - const QString kdeRcPath = QStringLiteral("/etc/kde") + QLatin1String(kdeVersionBA) + QStringLiteral("rc"); + const QString kdeRcPath = QLatin1String("/etc/kde") + QLatin1String(kdeVersionBA) + QLatin1String("rc"); if (QFileInfo(kdeRcPath).isReadable()) { QSettings kdeSettings(kdeRcPath, QSettings::IniFormat); kdeSettings.beginGroup(QStringLiteral("Directories-default")); kdeDirs += kdeSettings.value(QStringLiteral("prefixes")).toStringList(); } - const QString kdeVersionPrefix = QStringLiteral("/etc/kde") + QLatin1String(kdeVersionBA); + const QString kdeVersionPrefix = QLatin1String("/etc/kde") + QLatin1String(kdeVersionBA); if (QFileInfo(kdeVersionPrefix).isDir()) kdeDirs += kdeVersionPrefix; diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index 52d14e5324..d507751d5e 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -278,7 +278,7 @@ QString TableGenerator::findComposeFile() // check if user’s home directory has a file named .XCompose if (cleanState()) { - QString path = qgetenv("HOME") + QStringLiteral("/.XCompose"); + QString path = qgetenv("HOME") + QLatin1String("/.XCompose"); if (QFile::exists(path)) return path; } diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp index 5cbc5dbdb0..fc41dc5643 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp @@ -79,7 +79,7 @@ QStringList QEGLDeviceIntegrationFactory::keys(const QString &pluginPath) QCoreApplication::addLibraryPath(pluginPath); list = directLoader()->keyMap().values(); if (!list.isEmpty()) { - const QString postFix = QStringLiteral(" (from ") + const QString postFix = QLatin1String(" (from ") + QDir::toNativeSeparators(pluginPath) + QLatin1Char(')'); const QStringList::iterator end = list.end(); diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index fda3f51a48..1cc992dda6 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -509,28 +509,29 @@ QString QWindowsContext::registerWindowClass(const QWindow *w) break; } // Create a unique name for the flag combination - QString cname = QStringLiteral("Qt5QWindow"); + QString cname; + cname += QLatin1String("Qt5QWindow"); switch (type) { case Qt::Tool: - cname += QStringLiteral("Tool"); + cname += QLatin1String("Tool"); break; case Qt::ToolTip: - cname += QStringLiteral("ToolTip"); + cname += QLatin1String("ToolTip"); break; case Qt::Popup: - cname += QStringLiteral("Popup"); + cname += QLatin1String("Popup"); break; default: break; } if (style & CS_DROPSHADOW) - cname += QStringLiteral("DropShadow"); + cname += QLatin1String("DropShadow"); if (style & CS_SAVEBITS) - cname += QStringLiteral("SaveBits"); + cname += QLatin1String("SaveBits"); if (style & CS_OWNDC) - cname += QStringLiteral("OwnDC"); + cname += QLatin1String("OwnDC"); if (icon) - cname += QStringLiteral("Icon"); + cname += QLatin1String("Icon"); return registerWindowClass(cname, qWindowsWndProc, style, GetSysColorBrush(COLOR_WINDOW), icon); } @@ -828,8 +829,8 @@ static inline QString errorMessageFromComError(const _com_error &comError) return result; } if (const WORD wCode = comError.WCode()) - return QStringLiteral("IDispatch error #") + QString::number(wCode); - return QStringLiteral("Unknown error 0x0") + QString::number(comError.Error(), 16); + return QString::asprintf("IDispatch error #%u", uint(wCode)); + return QString::asprintf("Unknown error 0x0%x", uint(comError.Error())); } #endif // !Q_OS_WINCE diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index cb112446fc..b86972996c 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -698,7 +698,7 @@ QVariant QWindowsMimeText::convertToMime(const QString &mime, LPDATAOBJECT pData QByteArray data = getData(CF_UNICODETEXT, pDataObj); if (!data.isEmpty()) { str = QString::fromWCharArray(reinterpret_cast(data.constData())); - str.replace(QStringLiteral("\r\n"), QStringLiteral("\n")); + str.replace(QLatin1String("\r\n"), QLatin1String("\n")); } else { data = getData(CF_TEXT, pDataObj); if (!data.isEmpty()) { diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp index 3c99e3507e..1fee56aeca 100644 --- a/src/plugins/platforms/windows/qwindowsservices.cpp +++ b/src/plugins/platforms/windows/qwindowsservices.cpp @@ -94,9 +94,8 @@ static inline QString mailCommand() keyName = QString::fromWCharArray(command); RegCloseKey(handle); } - if (keyName.isEmpty()) - keyName = QStringLiteral("mailto"); - keyName += QStringLiteral("\\Shell\\Open\\Command"); + const QLatin1String mailto = keyName.isEmpty() ? QLatin1String("mailto") : QLatin1String(); + keyName += mailto + QLatin1String("\\Shell\\Open\\Command"); if (debug) qDebug() << __FUNCTION__ << "keyName=" << keyName; command[0] = 0; @@ -134,7 +133,7 @@ static inline bool launchMail(const QUrl &url) } // Pass the url as the parameter. Should use QProcess::startDetached(), // but that cannot handle a Windows command line [yet]. - command.replace(QStringLiteral("%1"), url.toString(QUrl::FullyEncoded)); + command.replace(QLatin1String("%1"), url.toString(QUrl::FullyEncoded)); if (debug) qDebug() << __FUNCTION__ << "Launching" << command; //start the process diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index 3689978b41..dbc0b0a77a 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -246,11 +246,11 @@ QString QWindowsTabletSupport::description() const .arg(implementationVersion >> 8).arg(implementationVersion & 0xFF) .arg(opts, 0, 16); if (opts & CXO_MESSAGES) - result += QStringLiteral(" CXO_MESSAGES"); + result += QLatin1String(" CXO_MESSAGES"); if (opts & CXO_CSRMESSAGES) - result += QStringLiteral(" CXO_CSRMESSAGES"); + result += QLatin1String(" CXO_CSRMESSAGES"); if (m_tiltSupport) - result += QStringLiteral(" tilt"); + result += QLatin1String(" tilt"); return result; } diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 4bf424f5f6..3947f823d6 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -346,7 +346,7 @@ QWindowsTheme::~QWindowsTheme() static inline QStringList iconThemeSearchPaths() { - const QFileInfo appDir(QCoreApplication::applicationDirPath() + QStringLiteral("/icons")); + const QFileInfo appDir(QCoreApplication::applicationDirPath() + QLatin1String("/icons")); return appDir.isDir() ? QStringList(appDir.absoluteFilePath()) : QStringList(); } diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.cpp b/src/plugins/platforms/winrt/qwinrtclipboard.cpp index aee9fc617d..2811f1f018 100644 --- a/src/plugins/platforms/winrt/qwinrtclipboard.cpp +++ b/src/plugins/platforms/winrt/qwinrtclipboard.cpp @@ -102,7 +102,7 @@ QMimeData *QWinRTClipboard::mimeData(QClipboard::Mode mode) quint32 size; const wchar_t *textStr = result.GetRawBuffer(&size); QString text = QString::fromWCharArray(textStr, size); - text.replace(QStringLiteral("\r\n"), QStringLiteral("\n")); + text.replace(QLatin1String("\r\n"), QLatin1String("\n")); m_mimeData.setText(text); return &m_mimeData; diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index 6ab8d3d96b..85a0d1cc0c 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -144,7 +144,7 @@ template<> inline char *toString(const QRectF &s) template<> inline char *toString(const QUrl &uri) { if (!uri.isValid()) - return qstrdup(qPrintable(QStringLiteral("Invalid URL: ") + uri.errorString())); + return qstrdup(qPrintable(QLatin1String("Invalid URL: ") + uri.errorString())); return qstrdup(uri.toEncoded().constData()); } diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 2231f12e2d..783a0cc4bb 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -926,7 +926,7 @@ bool TestMethods::invokeTest(int index, const char *data, WatchDog *watchDog) co QBenchmarkTestMethodData::current = &benchmarkData; const QByteArray &name = m_methods[index].name(); - QBenchmarkGlobalData::current->context.slotName = QLatin1String(name) + QStringLiteral("()"); + QBenchmarkGlobalData::current->context.slotName = QLatin1String(name) + QLatin1String("()"); char member[512]; QTestTable table; diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp index 2f57fa08ee..95888924fb 100644 --- a/src/widgets/accessible/qaccessiblewidgets.cpp +++ b/src/widgets/accessible/qaccessiblewidgets.cpp @@ -824,12 +824,12 @@ QString QAccessibleTextWidget::attributes(int offset, int *startOffset, int *end AttributeFormatter attrs; QString family = charFormatFont.family(); if (!family.isEmpty()) { - family = family.replace('\\',QStringLiteral("\\\\")); - family = family.replace(':',QStringLiteral("\\:")); - family = family.replace(',',QStringLiteral("\\,")); - family = family.replace('=',QStringLiteral("\\=")); - family = family.replace(';',QStringLiteral("\\;")); - family = family.replace('\"',QStringLiteral("\\\"")); + family = family.replace('\\', QLatin1String("\\\\")); + family = family.replace(':', QLatin1String("\\:")); + family = family.replace(',', QLatin1String("\\,")); + family = family.replace('=', QLatin1String("\\=")); + family = family.replace(';', QLatin1String("\\;")); + family = family.replace('\"', QLatin1String("\\\"")); attrs["font-family"] = QString::fromLatin1("\"%1\"").arg(family); } diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index 1ac0a98cb1..83a7dc800c 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -307,7 +307,7 @@ private: if (develMode) { // Write a PID file to help runner const QString pidFileName = QDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation)) - .absoluteFilePath(QString::number(uint(GetCurrentProcessId())) + QStringLiteral(".pid")); + .absoluteFilePath(QString::asprintf("%u.pid", uint(GetCurrentProcessId()))); CREATEFILE2_EXTENDED_PARAMETERS params = { sizeof(CREATEFILE2_EXTENDED_PARAMETERS), FILE_ATTRIBUTE_NORMAL diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp index fe21bca810..1724076b84 100644 --- a/src/xml/sax/qxml.cpp +++ b/src/xml/sax/qxml.cpp @@ -1295,8 +1295,7 @@ static QString extractEncodingDecl(const QString &text, bool *needMoreText) *needMoreText = false; int l = text.length(); - const QString declStart = QStringLiteral(" 0 && !text.startsWith(snip)) return QString(); -- cgit v1.2.3 From 6bafb9da71044d99a95a591f7872b8b2fd97174a Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Thu, 7 Jul 2016 11:05:07 +0300 Subject: QString: fix incomplete doc of chop() Change-Id: I84de848681e793e68e0c290719a7f961aca48f4e Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 8eadc9330d..3d63a540dd 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -4978,7 +4978,7 @@ void QString::truncate(int pos) Removes \a n characters from the end of the string. If \a n is greater than or equal to size(), the result is an - empty string. + empty string; if \a n is negative, it is equivalent to passing zero. Example: \snippet qstring/main.cpp 15 -- cgit v1.2.3 From 38b09d34210805766afa8bdd6a1ef413447a89ed Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 7 Jul 2016 14:33:30 -0700 Subject: QCocoaMenu: Attach late items to their submenu Because the QMenu::aboutToShow() signal is emitted way after -[QCocoaMenuDelegate menu:updateItem: atIndex:shouldCancel:], we miss the opportunity to attach the submenu to the menu item. The solution is to track the "open" state of the NSMenu. Then, if any submenu item gets added while the NSMenu is open, then we immediately attach the native item to the menu. Change-Id: I1f3a84ed3832520344da07e06cb3483ad6bd4ffd Task-number: QTBUG-54633 Reviewed-by: Jake Petroules --- src/plugins/platforms/cocoa/qcocoamenu.h | 6 +++++- src/plugins/platforms/cocoa/qcocoamenu.mm | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index c975de166d..98b0eb9c54 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -87,6 +87,9 @@ public: void setAttachedItem(NSMenuItem *item); NSMenuItem *attachedItem() const; + bool isOpen() const; + void setIsOpen(bool isOpen); + private: QCocoaMenuItem *itemOrNull(int index) const; void insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem); @@ -94,9 +97,10 @@ private: QList m_menuItems; NSMenu *m_nativeMenu; NSMenuItem *m_attachedItem; + quintptr m_tag; bool m_enabled; bool m_visible; - quintptr m_tag; + bool m_isOpen; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 878c96d33a..155abcc7ea 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -131,12 +131,14 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); - (void) menuWillOpen:(NSMenu*)m { Q_UNUSED(m); + m_menu->setIsOpen(true); emit m_menu->aboutToShow(); } - (void) menuDidClose:(NSMenu*)m { Q_UNUSED(m); + m_menu->setIsOpen(false); // wrong, but it's the best we can do emit m_menu->aboutToHide(); } @@ -251,9 +253,10 @@ QT_BEGIN_NAMESPACE QCocoaMenu::QCocoaMenu() : m_attachedItem(0), + m_tag(0), m_enabled(true), m_visible(true), - m_tag(0) + m_isOpen(false) { QMacAutoReleasePool pool; @@ -324,6 +327,8 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem) item->nsItem().target = m_nativeMenu.delegate; if (!item->menu()) [item->nsItem() setAction:@selector(itemFired:)]; + else if (isOpen() && item->nsItem()) // Someone's adding new items after aboutToShow() was emitted + item->menu()->setAttachedItem(item->nsItem()); if (item->isMerged()) return; @@ -347,6 +352,16 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem) item->setMenuParent(this); } +bool QCocoaMenu::isOpen() const +{ + return m_isOpen; +} + +void QCocoaMenu::setIsOpen(bool isOpen) +{ + m_isOpen = isOpen; +} + void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem) { QMacAutoReleasePool pool; -- cgit v1.2.3 From 9c49d8c41158287d4a7b7b9c950512cab692e6c5 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 8 Jul 2016 12:58:38 +0300 Subject: QSettings: optimize string usage Use QStringBuilder and QString::asprintf more. Use += operator to reserve extra capacity for possible free following append/prepend/+= call. Change-Id: Ia534bec28cb96b688a68a5051a855cda1eb5db4b Reviewed-by: Thiago Macieira Reviewed-by: Marc Mutz --- src/corelib/io/qsettings.cpp | 109 +++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 66 deletions(-) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 6e788d28f4..759f75bd70 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -249,8 +249,7 @@ QString QSettingsPrivate::actualKey(const QString &key) const { QString n = normalizedKey(key); Q_ASSERT_X(!n.isEmpty(), "QSettings", "empty key"); - n.prepend(groupPrefix); - return n; + return groupPrefix + n; } /* @@ -325,10 +324,9 @@ void QSettingsPrivate::processChild(QStringRef key, ChildSpec spec, QStringList void QSettingsPrivate::beginGroupOrArray(const QSettingsGroup &group) { groupStack.push(group); - if (!group.name().isEmpty()) { - groupPrefix += group.name(); - groupPrefix += QLatin1Char('/'); - } + const QString name = group.name(); + if (!name.isEmpty()) + groupPrefix += name + QLatin1Char('/'); } /* @@ -404,9 +402,9 @@ QString QSettingsPrivate::variantToString(const QVariant &v) case QVariant::ByteArray: { QByteArray a = v.toByteArray(); - result = QLatin1String("@ByteArray("); - result += QString::fromLatin1(a.constData(), a.size()); - result += QLatin1Char(')'); + result = QLatin1String("@ByteArray(") + + QLatin1String(a.constData(), a.size()) + + QLatin1Char(')'); break; } @@ -426,33 +424,17 @@ QString QSettingsPrivate::variantToString(const QVariant &v) #ifndef QT_NO_GEOM_VARIANT case QVariant::Rect: { QRect r = qvariant_cast(v); - result += QLatin1String("@Rect("); - result += QString::number(r.x()); - result += QLatin1Char(' '); - result += QString::number(r.y()); - result += QLatin1Char(' '); - result += QString::number(r.width()); - result += QLatin1Char(' '); - result += QString::number(r.height()); - result += QLatin1Char(')'); + result = QString::asprintf("@Rect(%d %d %d %d)", r.x(), r.y(), r.width(), r.height()); break; } case QVariant::Size: { QSize s = qvariant_cast(v); - result += QLatin1String("@Size("); - result += QString::number(s.width()); - result += QLatin1Char(' '); - result += QString::number(s.height()); - result += QLatin1Char(')'); + result = QString::asprintf("@Size(%d %d)", s.width(), s.height()); break; } case QVariant::Point: { QPoint p = qvariant_cast(v); - result += QLatin1String("@Point("); - result += QString::number(p.x()); - result += QLatin1Char(' '); - result += QString::number(p.y()); - result += QLatin1Char(')'); + result = QString::asprintf("@Point(%d %d)", p.x(), p.y()); break; } #endif // !QT_NO_GEOM_VARIANT @@ -475,9 +457,9 @@ QString QSettingsPrivate::variantToString(const QVariant &v) s << v; } - result = QLatin1String(typeSpec); - result += QString::fromLatin1(a.constData(), a.size()); - result += QLatin1Char(')'); + result = QLatin1String(typeSpec) + + QLatin1String(a.constData(), a.size()) + + QLatin1Char(')'); #else Q_ASSERT(!"QSettings: Cannot save custom types without QDataStream support"); #endif @@ -648,8 +630,7 @@ void QSettingsPrivate::iniEscapedString(const QString &str, QByteArray &result, && ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'))) { - result += "\\x"; - result += QByteArray::number(ch, 16); + result += "\\x" + QByteArray::number(ch, 16); continue; } @@ -688,8 +669,7 @@ void QSettingsPrivate::iniEscapedString(const QString &str, QByteArray &result, break; default: if (ch <= 0x1F || (ch >= 0x7F && !useCodec)) { - result += "\\x"; - result += QByteArray::number(ch, 16); + result += "\\x" + QByteArray::number(ch, 16); escapeNextIfDigit = true; #ifndef QT_NO_TEXTCODEC } else if (useCodec) { @@ -1048,10 +1028,33 @@ static inline int pathHashKey(QSettings::Format format, QSettings::Scope scope) return int((uint(format) << 1) | uint(scope == QSettings::SystemScope)); } +#ifndef Q_OS_WIN +static QString make_user_path() +{ + static Q_CONSTEXPR QChar sep = QLatin1Char('/'); +#ifndef QSETTINGS_USE_QSTANDARDPATHS + // Non XDG platforms (OS X, iOS, Android...) have used this code path erroneously + // for some time now. Moving away from that would require migrating existing settings. + QByteArray env = qgetenv("XDG_CONFIG_HOME"); + if (env.isEmpty()) { + return QDir::homePath() + QLatin1String("/.config/"); + } else if (env.startsWith('/')) { + return QFile::decodeName(env) + sep; + } else { + return QDir::homePath() + sep + QFile::decodeName(env) + sep; + } +#else + // When using a proper XDG platform, use QStandardPaths rather than the above hand-written code; + // it makes the use of test mode from unit tests possible. + // Ideally all platforms should use this, but see above for the migration issue. + return QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + sep; +#endif +} +#endif // !Q_OS_WIN + static void initDefaultPaths(QMutexLocker *locker) { PathHash *pathHash = pathHashFunc(); - QString systemPath; locker->unlock(); @@ -1060,8 +1063,7 @@ static void initDefaultPaths(QMutexLocker *locker) avoid a dead-lock, we can't hold the global mutex while calling it. */ - systemPath = QLibraryInfo::location(QLibraryInfo::SettingsPath); - systemPath += QLatin1Char('/'); + QString systemPath = QLibraryInfo::location(QLibraryInfo::SettingsPath) + QLatin1Char('/'); locker->relock(); if (pathHash->isEmpty()) { @@ -1077,38 +1079,14 @@ static void initDefaultPaths(QMutexLocker *locker) pathHash->insert(pathHashKey(QSettings::IniFormat, QSettings::SystemScope), windowsConfigPath(CSIDL_COMMON_APPDATA) + QDir::separator()); #else - -#ifndef QSETTINGS_USE_QSTANDARDPATHS - // Non XDG platforms (OS X, iOS, Android...) have used this code path erroneously - // for some time now. Moving away from that would require migrating existing settings. - QString userPath; - QByteArray env = qgetenv("XDG_CONFIG_HOME"); - if (env.isEmpty()) { - userPath = QDir::homePath(); - userPath += QLatin1Char('/'); - userPath += QLatin1String(".config"); - } else if (env.startsWith('/')) { - userPath = QFile::decodeName(env); - } else { - userPath = QDir::homePath(); - userPath += QLatin1Char('/'); - userPath += QFile::decodeName(env); - } -#else - // When using a proper XDG platform, use QStandardPaths rather than the above hand-written code; - // it makes the use of test mode from unit tests possible. - // Ideally all platforms should use this, but see above for the migration issue. - QString userPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); -#endif - userPath += QLatin1Char('/'); - + const QString userPath = make_user_path(); pathHash->insert(pathHashKey(QSettings::IniFormat, QSettings::UserScope), userPath); pathHash->insert(pathHashKey(QSettings::IniFormat, QSettings::SystemScope), systemPath); #ifndef Q_OS_MAC pathHash->insert(pathHashKey(QSettings::NativeFormat, QSettings::UserScope), userPath); pathHash->insert(pathHashKey(QSettings::NativeFormat, QSettings::SystemScope), systemPath); #endif -#endif +#endif // Q_OS_WIN } } @@ -3496,8 +3474,7 @@ QSettings::Format QSettings::registerFormat(const QString &extension, ReadFunc r return QSettings::InvalidFormat; QConfFileCustomFormat info; - info.extension = QLatin1Char('.'); - info.extension += extension; + info.extension = QLatin1Char('.') + extension; info.readFunc = readFunc; info.writeFunc = writeFunc; info.caseSensitivity = caseSensitivity; -- cgit v1.2.3 From a0bb2fc4061a91edab8222158fd88454f40dab27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Fri, 24 Jun 2016 10:01:01 +0100 Subject: Fix typo in QStyle documentation Change-Id: Id1f65dcc473effbdd0ccd7362b2986382c827ed8 Reviewed-by: Martin Smith --- src/widgets/styles/qstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 97ed8eec3d..6a03d73c72 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -725,7 +725,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, \value State_None Indicates that the widget does not have a state. \value State_Active Indicates that the widget is active. - \value State_AutoRaise Used to indicate if auto-raise appearance should be usd on a tool button. + \value State_AutoRaise Used to indicate if auto-raise appearance should be used on a tool button. \value State_Children Used to indicate if an item view branch has children. \value State_DownArrow Used to indicate if a down arrow should be visible on the widget. \value State_Editing Used to indicate if an editor is opened on the widget. -- cgit v1.2.3 From a2ff5afffa8f8cc10d7e0bbd37a8eebd8c7af25e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 10 Jul 2016 14:48:53 -0700 Subject: Correct indentation in qsettings.cpp Introduced in 9c49d8c41158287d4a7b7b9c950512cab692e6c5, despite my pointing out. Change-Id: Ie585843cfb684bc3b6e3fffd14600c99f7fde591 Reviewed-by: Thiago Macieira Reviewed-by: Anton Kudryavtsev --- src/corelib/io/qsettings.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 759f75bd70..0e5d014c30 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -403,8 +403,8 @@ QString QSettingsPrivate::variantToString(const QVariant &v) case QVariant::ByteArray: { QByteArray a = v.toByteArray(); result = QLatin1String("@ByteArray(") - + QLatin1String(a.constData(), a.size()) - + QLatin1Char(')'); + + QLatin1String(a.constData(), a.size()) + + QLatin1Char(')'); break; } @@ -458,8 +458,8 @@ QString QSettingsPrivate::variantToString(const QVariant &v) } result = QLatin1String(typeSpec) - + QLatin1String(a.constData(), a.size()) - + QLatin1Char(')'); + + QLatin1String(a.constData(), a.size()) + + QLatin1Char(')'); #else Q_ASSERT(!"QSettings: Cannot save custom types without QDataStream support"); #endif -- cgit v1.2.3 From 4f6c6ef65f7f9f44590b2b615aa98f64d04aeddf Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Tue, 5 Jul 2016 12:56:28 +0200 Subject: Doc: added doc for parameter isMask Error message: Undocumented parameter 'isMask' in QIcon::setIsMask() Change-Id: If16d232b6856ff6d5104ac7c32d3b8c0ac4081f9 Reviewed-by: Venugopal Shivashankar --- src/gui/image/qicon.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 0dec4b512d..c65ac7f92d 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -1227,8 +1227,8 @@ bool QIcon::hasThemeIcon(const QString &name) /*! \since 5.6 - Indicate that this icon is a mask image, and hence can potentially - be modified based on where it's displayed. + Indicate that this icon is a mask image(boolean \a isMask), and hence can + potentially be modified based on where it's displayed. \sa isMask() */ void QIcon::setIsMask(bool isMask) -- cgit v1.2.3 From e27c07389bcf8b6c5cc1c356a3ee1759045270a8 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 8 Jul 2016 11:27:50 +0300 Subject: QString: adapt chop() auto test as data-driven test Thiago Macieira asked to do that. Change-Id: I9a07dad7ff2bfebc2f863e0e9f151aab66450bcf Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qstring/tst_qstring.cpp | 37 ++++++++++++------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 601987086d..3bacf5d942 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -482,6 +482,7 @@ private slots: void sprintf(); void fill(); void truncate(); + void chop_data(); void chop(); void constructor(); void constructorQByteArray_data(); @@ -1222,29 +1223,29 @@ void tst_QString::truncate() } -void tst_QString::chop() +void tst_QString::chop_data() { - const QString original("abcd"); - - QString str = original; - str.chop(1); - QCOMPARE(str, QLatin1String("abc")); + QTest::addColumn("input"); + QTest::addColumn("count" ); + QTest::addColumn("result"); - str = original; - str.chop(0); - QCOMPARE(str, original); + const QString original("abcd"); - str = original; - str.chop(-1); - QCOMPARE(str, original); + QTest::newRow("data0") << original << 1 << QString("abc"); + QTest::newRow("data1") << original << 0 << original; + QTest::newRow("data2") << original << -1 << original; + QTest::newRow("data3") << original << original.size() << QString(); + QTest::newRow("data4") << original << 1000 << QString(); +} - str = original; - str.chop(original.size()); - QVERIFY(str.isEmpty()); +void tst_QString::chop() +{ + QFETCH(QString, input); + QFETCH(int, count); + QFETCH(QString, result); - str = original; - str.chop(1000); - QVERIFY(str.isEmpty()); + input.chop(count); + QCOMPARE(input, result); } void tst_QString::fill() -- cgit v1.2.3 From 8cee6864c6718449e3b5bedcd79173391ec188e7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 8 Jul 2016 10:45:51 +0200 Subject: QStringBuilderCommon: drop const from resolved() result type The const qualification prevented toUpper() etc from calling the rvalue overloads of the corresponding QString functions. Since resolved() always returns a non-shared object, the rvalue overloads can re-use the object's capacity for storing their result, saving up to one memory allocation per QStringBuilderCommon::to*() invocation. Change-Id: Ica97fcd906cdd949ffe56055654578b93407e2d3 Reviewed-by: Thiago Macieira --- src/corelib/tools/qstringbuilder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 69bd344f47..fdd1aa3478 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -76,7 +76,7 @@ struct QStringBuilderCommon T toLower() const { return resolved().toLower(); } protected: - const T resolved() const { return *static_cast(this); } + T resolved() const { return *static_cast(this); } }; template -- cgit v1.2.3 From f8dc769655959b290d70a2e66e2c3a625aa813cd Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 27 Jun 2016 14:30:59 +0200 Subject: QMacTimeZonePrivate - correctly initialize m_nstz data-member The default ctor never initializes m_nstz but calls init with [NSTimeZone systemTimeZone].name. Init (re)sets m_nstz _only_ if this ianaId is in [NSTimeZone knownTimeZoneName], which is not guaranteed (a good example is "US/Pacific" that can be returned by systemTimeZoneId() - the similar problem is described in [*]. Set m_nstz to nil in ctor, so if 'init' fails we still have a valid (nil) pointer. [*] http://stackoverflow.com/questions/19819268/convert-ios-localtimezone-to-a-knowntimezone. Task-number: QTBUG-54330 Change-Id: I68917926350aad3158d44a06f06721f25b3fdb74 Reviewed-by: Edward Welbourne --- src/corelib/tools/qtimezoneprivate_mac.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/tools/qtimezoneprivate_mac.mm b/src/corelib/tools/qtimezoneprivate_mac.mm index f316fe0a6d..4e5034516b 100644 --- a/src/corelib/tools/qtimezoneprivate_mac.mm +++ b/src/corelib/tools/qtimezoneprivate_mac.mm @@ -53,6 +53,7 @@ QT_BEGIN_NAMESPACE // Create the system default time zone QMacTimeZonePrivate::QMacTimeZonePrivate() + : m_nstz(0) { init(systemTimeZoneId()); } -- cgit v1.2.3 From 7c279d779b32eb61987fc7d4f1143a1eaa1a1bde Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 7 Jul 2016 12:36:33 +0200 Subject: QWindowsTabletSupport: fix new[]/delete mismatch QScopedPointer deletes with delete, but a pointer returned from new[] needs to be deleted with delete[]. Fix by using QVarLengthArray instead of QScopedPointer(new TCHAR[]). Change-Id: I2f1f252379a9ac1ee919901b5efcec9cec31261e Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowstabletsupport.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index 222551a86f..87f3eff409 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include #include @@ -227,7 +227,7 @@ QString QWindowsTabletSupport::description() const const unsigned size = m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_WINTABID, 0); if (!size) return QString(); - QScopedPointer winTabId(new TCHAR[size + 1]); + QVarLengthArray winTabId(size + 1); m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_WINTABID, winTabId.data()); WORD implementationVersion = 0; m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_IMPLVERSION, &implementationVersion); -- cgit v1.2.3 From 6a7bae9a26aac877bceaf2810328064abc71c768 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 11 Jul 2016 12:11:14 +0200 Subject: QHashFunctions: test for hash equality of null and empty string types In Qt, null QStrings compare equal to empty ones, so add an explicit check that the corresponding hash values are identical, too. Ditto for QByteArray. Change-Id: I190fc95a765305928d9b6b0e4955433865b6b247 Reviewed-by: Thiago Macieira --- .../corelib/tools/qhashfunctions/tst_qhashfunctions.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp index bde9433a24..4d61bc393d 100644 --- a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp +++ b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp @@ -45,6 +45,8 @@ class tst_QHashFunctions : public QObject Q_OBJECT private Q_SLOTS: void qhash(); + void qhash_of_empty_and_null_qstring(); + void qhash_of_empty_and_null_qbytearray(); void fp_qhash_of_zero_is_zero(); void qthash_data(); void qthash(); @@ -117,6 +119,20 @@ void tst_QHashFunctions::qhash() } } +void tst_QHashFunctions::qhash_of_empty_and_null_qstring() +{ + QString null, empty(""); + QCOMPARE(null, empty); + QCOMPARE(qHash(null), qHash(empty)); +} + +void tst_QHashFunctions::qhash_of_empty_and_null_qbytearray() +{ + QByteArray null, empty(""); + QCOMPARE(null, empty); + QCOMPARE(qHash(null), qHash(empty)); +} + void tst_QHashFunctions::fp_qhash_of_zero_is_zero() { QCOMPARE(qHash(-0.0f), 0U); -- cgit v1.2.3 From e6a5be1d81a3f8fce7e55906b4bc84d723e11ac5 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 11 Jul 2016 11:04:52 +0200 Subject: QPair: add test for pair of references std::pair explicitly supports this (cf. std::tie), so check we do, too. Change-Id: Idc3c1739a4bc64a0da120dcf953def7e432f6f71 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qpair/tst_qpair.cpp | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/auto/corelib/tools/qpair/tst_qpair.cpp b/tests/auto/corelib/tools/qpair/tst_qpair.cpp index 076efc5428..94740d74bc 100644 --- a/tests/auto/corelib/tools/qpair/tst_qpair.cpp +++ b/tests/auto/corelib/tools/qpair/tst_qpair.cpp @@ -40,6 +40,7 @@ class tst_QPair : public QObject { Q_OBJECT private Q_SLOTS: + void pairOfReferences(); void testConstexpr(); }; @@ -94,6 +95,35 @@ Q_STATIC_ASSERT(!QTypeInfo::isDummy ); Q_STATIC_ASSERT(!QTypeInfo::isPointer); +void tst_QPair::pairOfReferences() +{ + int i = 0; + QString s; + + QPair p(i, s); + + p.first = 1; + QCOMPARE(i, 1); + + i = 2; + QCOMPARE(p.first, 2); + + p.second = QLatin1String("Hello"); + QCOMPARE(s, QLatin1String("Hello")); + + s = QLatin1String("olleH"); + QCOMPARE(p.second, QLatin1String("olleH")); + + QPair q = p; + q.first = 3; + QCOMPARE(i, 3); + QCOMPARE(p.first, 3); + + q.second = QLatin1String("World"); + QCOMPARE(s, QLatin1String("World")); + QCOMPARE(p.second, QLatin1String("World")); +} + void tst_QPair::testConstexpr() { Q_CONSTEXPR QPair pID = qMakePair(0, 0.0); -- cgit v1.2.3 From 7a2f53647bad30a95692bb2d32a9a080f948a20a Mon Sep 17 00:00:00 2001 From: Takumi ASAKI Date: Mon, 4 Jul 2016 13:55:06 +0900 Subject: Bearer/ConnMan: Fix No such slot Change-Id: Icf403b2e2e86d1cb58fd74c0df054bcc43cf9210 Reviewed-by: Lorn Potter --- src/plugins/bearer/connman/qconnmanservice_linux_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/bearer/connman/qconnmanservice_linux_p.h b/src/plugins/bearer/connman/qconnmanservice_linux_p.h index 1a10a2260a..7292736e2e 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux_p.h +++ b/src/plugins/bearer/connman/qconnmanservice_linux_p.h @@ -211,6 +211,7 @@ protected: private: QVariantMap properties(); QVariantMap propertiesMap; +private Q_SLOTS: void scanReply(QDBusPendingCallWatcher *call); }; -- cgit v1.2.3 From 8ba3fee61030e54ee1bc79c15059170be5bc2add Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Fri, 10 Jun 2016 09:54:09 +0200 Subject: QWindowsOpenGLTester: fall back to built-in blacklist if buglist file cannot be resolved if the environment variable is set, but the buglist file cannot be found, we should fall back to the built-in buglist instead of not using any. Change-Id: I370a1f21238efd155b46f0e7071734f5d3c6c343 Reviewed-by: Laszlo Agocs Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowsopengltester.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index 4ca7f0e413..c24e0ba0ae 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -246,15 +246,16 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c if (!glesOnly && testDesktopGL()) result |= QWindowsOpenGLTester::DesktopGl; - QSet features; const char bugListFileVar[] = "QT_OPENGL_BUGLIST"; + QString buglistFileName = QStringLiteral(":/qt-project.org/windows/openglblacklists/default.json"); + if (qEnvironmentVariableIsSet(bugListFileVar)) { const QString fileName = resolveBugListFile(QFile::decodeName(qgetenv(bugListFileVar))); if (!fileName.isEmpty()) - features = QOpenGLConfig::gpuFeatures(qgpu, fileName); - } else { - features = QOpenGLConfig::gpuFeatures(qgpu, QStringLiteral(":/qt-project.org/windows/openglblacklists/default.json")); + buglistFileName = fileName; } + + QSet features = QOpenGLConfig::gpuFeatures(qgpu, buglistFileName); qCDebug(lcQpaGl) << "GPU features:" << features; if (features.contains(QStringLiteral("disable_desktopgl"))) { // Qt-specific -- cgit v1.2.3 From 7cfdbe510259d186707cce900170f844b6cfd2f4 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Mon, 11 Jul 2016 13:54:26 +0200 Subject: Doc: corrected link to Qt Widgets Examples qwidget.cpp:498: warning: Can't link to 'Qt Examples' Change-Id: I5eed4ac4fd5514a1e1ff7130997df8449d5c5e7f Reviewed-by: Martin Smith --- src/widgets/kernel/qwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index a4830130f1..4d402ca1bd 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -565,7 +565,7 @@ void QWidget::setAutoFillBackground(bool enabled) Composite widgets can also be created by subclassing a standard widget, such as QWidget or QFrame, and adding the necessary layout and child - widgets in the constructor of the subclass. Many of the \l{Qt Examples} + widgets in the constructor of the subclass. Many of the \l{Qt Widgets Examples} {examples provided with Qt} use this approach, and it is also covered in the Qt \l{Tutorials}. -- cgit v1.2.3 From 9a3bcd1c3d4914a9594d80dc0c3812fd88be42c3 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 30 Mar 2016 19:26:29 +0200 Subject: QString::replace(): Commentary clarifications. Also skip doing a += 0 when we had to test whether the relevant rhs was zero anyway (because we want to ++ there instead of +=ing). Change-Id: Ibd5f21eb9aaf410b09c9db8450b2d61618e628fc Reviewed-by: Robin Burchell --- src/corelib/tools/qstring.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 3d63a540dd..68681a90d0 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -2488,19 +2488,19 @@ QString &QString::replace(const QChar *before, int blen, if (index == -1) break; indices[pos++] = index; - index += blen; - // avoid infinite loop - if (!blen) + if (blen) // Step over before: + index += blen; + else // Only count one instance of empty between any two characters: index++; } - if (!pos) + if (!pos) // Nothing to replace break; replace_helper(indices, pos, blen, after, alen); - if (index == -1) + if (index == -1) // Nothing left to replace break; - // index has to be adjusted in case we get back into the loop above. + // The call to replace_helper just moved what index points at: index += pos*(alen-blen); } @@ -2545,14 +2545,14 @@ QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs index++; } } - if (!pos) + if (!pos) // Nothing to replace break; replace_helper(indices, pos, 1, after.constData(), after.d->size); - if (index == -1) + if (index == -1) // Nothing left to replace break; - // index has to be adjusted in case we get back into the loop above. + // The call to replace_helper just moved what index points at: index += pos*(after.d->size - 1); } return *this; -- cgit v1.2.3 From e21bf5e6b390001ac83c403005957ddc8bfc36ae Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 30 Mar 2016 16:01:27 +0200 Subject: QString::replace(): protect sought text and replacement When replacing each copy of one text with a copy of another, we do so in batches of 1024; if we get more than one batch, we need to keep a copy of the sought text and replacement if they're part of the string we're modifying, for use in later batches. Also do the replacements in full batches of 1024, not 1023 (which left the last entry in an array unused); marked some related tests as (un)likely; and move some repeated code out into a pair of little local functions to save duplcation. Those new functions can also serve replace_helper(); and it can shed a const_cast and some conditioning of free() by using them the same way replace() now does. (There was also one place it still used the raw after, rather than the replacement copy; which could have produced errors if memcpy were to exercise its right to assume no overlap in arrays. This error is what prompted me to notice all of the above.) Added tests. The last error proved untestable as my memcpy is in fact as fussy as memmove. The first two tests added were attempts to get a failure out of it. The third did get a failure, but also tripped over the problem in replace() itself. Added to an existing test function and renamed it to generally cover extra tests for replace. Change-Id: I9ba6928c84ece266dbbe52b91e333ea54ab6d95e Reviewed-by: Robin Burchell Reviewed-by: Lars Knoll --- src/corelib/tools/qstring.cpp | 69 +++++++++++++++++------- tests/auto/corelib/tools/qstring/tst_qstring.cpp | 42 ++++++++++++++- 2 files changed, 89 insertions(+), 22 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 68681a90d0..b5119444b7 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -2381,26 +2381,40 @@ QString &QString::replace(const QString &before, const QString &after, Qt::CaseS return replace(before.constData(), before.size(), after.constData(), after.size(), cs); } +namespace { // helpers for replace and its helper: +QChar *textCopy(const QChar *start, int len) +{ + const size_t size = len * sizeof(QChar); + QChar *const copy = static_cast(::malloc(size)); + Q_CHECK_PTR(copy); + ::memcpy(copy, start, size); + return copy; +} + +bool pointsIntoRange(const QChar *ptr, const ushort *base, int len) +{ + const QChar *const start = reinterpret_cast(base); + return start <= ptr && ptr < start + len; +} +} // end namespace + /*! \internal */ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar *after, int alen) { - // copy *after in case it lies inside our own d->data() area - // (which we could possibly invalidate via a realloc or corrupt via memcpy operations.) - QChar *afterBuffer = const_cast(after); - if (after >= reinterpret_cast(d->data()) && after < reinterpret_cast(d->data()) + d->size) { - afterBuffer = static_cast(::malloc(alen*sizeof(QChar))); - Q_CHECK_PTR(afterBuffer); - ::memcpy(afterBuffer, after, alen*sizeof(QChar)); - } + // Copy after if it lies inside our own d->data() area (which we could + // possibly invalidate via a realloc or modify by replacement). + QChar *afterBuffer = 0; + if (pointsIntoRange(after, d->data(), d->size)) // Use copy in place of vulnerable original: + after = afterBuffer = textCopy(after, alen); QT_TRY { if (blen == alen) { // replace in place detach(); for (int i = 0; i < nIndices; ++i) - memcpy(d->data() + indices[i], afterBuffer, alen * sizeof(QChar)); + memcpy(d->data() + indices[i], after, alen * sizeof(QChar)); } else if (alen < blen) { // replace from front detach(); @@ -2416,7 +2430,7 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar to += msize; } if (alen) { - memcpy(d->data() + to, afterBuffer, alen*sizeof(QChar)); + memcpy(d->data() + to, after, alen * sizeof(QChar)); to += alen; } movestart = indices[i] + blen; @@ -2439,17 +2453,15 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar int moveto = insertstart + alen; memmove(d->data() + moveto, d->data() + movestart, (moveend - movestart)*sizeof(QChar)); - memcpy(d->data() + insertstart, afterBuffer, alen*sizeof(QChar)); + memcpy(d->data() + insertstart, after, alen * sizeof(QChar)); moveend = movestart-blen; } } } QT_CATCH(const std::bad_alloc &) { - if (afterBuffer != after) - ::free(afterBuffer); + ::free(afterBuffer); QT_RETHROW; } - if (afterBuffer != after) - ::free(afterBuffer); + ::free(afterBuffer); } /*! @@ -2478,12 +2490,13 @@ QString &QString::replace(const QChar *before, int blen, return *this; QStringMatcher matcher(before, blen, cs); + QChar *beforeBuffer = 0, *afterBuffer = 0; int index = 0; while (1) { uint indices[1024]; uint pos = 0; - while (pos < 1023) { + while (pos < 1024) { index = matcher.indexIn(*this, index); if (index == -1) break; @@ -2496,13 +2509,29 @@ QString &QString::replace(const QChar *before, int blen, if (!pos) // Nothing to replace break; + if (Q_UNLIKELY(index != -1)) { + /* + We're about to change data, that before and after might point + into, and we'll need that data for our next batch of indices. + */ + if (!afterBuffer && pointsIntoRange(after, d->data(), d->size)) + after = afterBuffer = textCopy(after, alen); + + if (!beforeBuffer && pointsIntoRange(before, d->data(), d->size)) { + beforeBuffer = textCopy(before, blen); + matcher = QStringMatcher(beforeBuffer, blen, cs); + } + } + replace_helper(indices, pos, blen, after, alen); - if (index == -1) // Nothing left to replace + if (Q_LIKELY(index == -1)) // Nothing left to replace break; // The call to replace_helper just moved what index points at: index += pos*(alen-blen); } + ::free(afterBuffer); + ::free(beforeBuffer); return *this; } @@ -2533,13 +2562,13 @@ QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs uint indices[1024]; uint pos = 0; if (cs == Qt::CaseSensitive) { - while (pos < 1023 && index < d->size) { + while (pos < 1024 && index < d->size) { if (d->data()[index] == cc) indices[pos++] = index; index++; } } else { - while (pos < 1023 && index < d->size) { + while (pos < 1024 && index < d->size) { if (QChar::toCaseFolded(d->data()[index]) == cc) indices[pos++] = index; index++; @@ -2550,7 +2579,7 @@ QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs replace_helper(indices, pos, 1, after.constData(), after.d->size); - if (index == -1) // Nothing left to replace + if (Q_LIKELY(index == -1)) // Nothing left to replace break; // The call to replace_helper just moved what index points at: index += pos*(after.d->size - 1); diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 3bacf5d942..da6cdddd4f 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -360,7 +360,7 @@ private slots: void replace_qchar_qstring(); void replace_uint_uint_data(); void replace_uint_uint(); - void replace_uint_uint_extra(); + void replace_extra(); void replace_string_data(); void replace_string(); void replace_regexp_data(); @@ -2790,7 +2790,7 @@ void tst_QString::replace_uint_uint() } } -void tst_QString::replace_uint_uint_extra() +void tst_QString::replace_extra() { /* This test is designed to be extremely slow if QString::replace() doesn't optimize the case @@ -2827,6 +2827,44 @@ void tst_QString::replace_uint_uint_extra() QString str5("abcdefghij"); str5.replace(8, 10, str5); QCOMPARE(str5, QString("abcdefghabcdefghij")); + + // Replacements using only part of the string modified: + QString str6("abcdefghij"); + str6.replace(1, 8, str6.constData() + 3, 3); + QCOMPARE(str6, QString("adefj")); + + QString str7("abcdefghibcdefghij"); + str7.replace(str7.constData() + 1, 6, str7.constData() + 2, 3); + QCOMPARE(str7, QString("acdehicdehij")); + + const int many = 1024; + /* + QS::replace(const QChar *, int, const QChar *, int, Qt::CaseSensitivity) + does its replacements in batches of many (please keep in sync with any + changes to batch size), which lead to misbehaviour if ether QChar * array + was part of the data being modified. + */ + QString str8("abcdefg"), ans8("acdeg"); + { + // Make str8 and ans8 repeat themselves many + 1 times: + int i = many; + QString big(str8), small(ans8); + while (i && !(i & 1)) { // Exploit many being a power of 2: + big += big; + small += small; + i >>= 1; + } + while (i-- > 0) { + str8 += big; + ans8 += small; + } + } + str8.replace(str8.constData() + 1, 5, str8.constData() + 2, 3); + // Pre-test the bit where the diff happens, so it gets displayed: + QCOMPARE(str8.mid((many - 3) * 5), ans8.mid((many - 3) * 5)); + // Also check the full values match, of course: + QCOMPARE(str8.size(), ans8.size()); + QCOMPARE(str8, ans8); } void tst_QString::replace_string() -- cgit v1.2.3 From 8beddf8328eb65436790e332b5e0c0760ada0c7d Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 29 Jun 2016 16:27:25 -0700 Subject: QSslSocketBackendPrivate: Remove QString warnings Change-Id: I2ab758fe61ea1ba9b84672ac05ac219b85e3de6a Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslsocket_mac.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 9f0359aa47..8aa9269f4b 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -600,7 +600,7 @@ void QSslSocketBackendPrivate::startClientEncryption() // Error description/code were set, 'error' emitted // by initSslContext, but OpenSSL socket also sets error // emits a signal twice, so ... - setErrorAndEmit(QAbstractSocket::SslInternalError, "Unable to init SSL Context"); + setErrorAndEmit(QAbstractSocket::SslInternalError, QStringLiteral("Unable to init SSL Context")); return; } @@ -613,7 +613,7 @@ void QSslSocketBackendPrivate::startServerEncryption() // Error description/code were set, 'error' emitted // by initSslContext, but OpenSSL socket also sets error // emits a signal twice, so ... - setErrorAndEmit(QAbstractSocket::SslInternalError, "Unable to init SSL Context"); + setErrorAndEmit(QAbstractSocket::SslInternalError, QStringLiteral("Unable to init SSL Context")); return; } @@ -936,7 +936,7 @@ bool QSslSocketBackendPrivate::initSslContext() context.reset(qt_createSecureTransportContext(mode)); if (!context) { - setErrorAndEmit(QAbstractSocket::SslInternalError, "SSLCreateContext failed"); + setErrorAndEmit(QAbstractSocket::SslInternalError, QStringLiteral("SSLCreateContext failed")); return false; } @@ -964,7 +964,7 @@ bool QSslSocketBackendPrivate::initSslContext() if (!setSessionProtocol()) { destroySslContext(); - setErrorAndEmit(QAbstractSocket::SslInternalError, "Failed to set protocol version"); + setErrorAndEmit(QAbstractSocket::SslInternalError, QStringLiteral("Failed to set protocol version")); return false; } @@ -1406,8 +1406,7 @@ bool QSslSocketBackendPrivate::startHandshake() // check protocol version ourselves, as Secure Transport does not enforce // the requested min / max versions. if (!verifySessionProtocol()) { - setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, - "Protocol version mismatch"); + setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, QStringLiteral("Protocol version mismatch")); plainSocket->disconnectFromHost(); return false; } -- cgit v1.2.3 From 49f9328175fe42d00c6e15a8599b1a912bb9863d Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 11 Jul 2016 15:25:02 +0200 Subject: configure.exe: Show error on "-target xp" option The option was removed in dev but should have been removed in 5.7. In order not to complicate merges most of the code that was removed in dev has been kept as is and only the "bare minimum" was removed. Task-number: QTBUG-54674 Change-Id: I5118fe344de014bdcf008cccfe9eca112896d23a Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index bc519663e8..a89e66c377 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -526,6 +526,12 @@ void Configure::parseCmdLine() if (i == argCount) break; const QString option = configCmdLine.at(i); + if (option == "xp") { + cout << "ERROR: option \"-target xp\" is no longer valid" << endl; + dictionary["DONE"] = "error"; + return; + } + if (option != "xp") { cout << "ERROR: invalid argument for -target option" << endl; dictionary["DONE"] = "error"; @@ -1817,9 +1823,6 @@ bool Configure::displayHelp() desc( "-xplatform ", "The operating system and compiler you are cross compiling to.\n"); desc( "", "See the README file for a list of supported operating systems and compilers.\n", false, ' '); - desc("TARGET_OS", "*", "-target", "Set target OS version. Currently the only valid value is 'xp' for targeting Windows XP.\n" - "MSVC >= 2012 targets Windows Vista by default.\n"); - desc( "-sysroot ", "Sets as the target compiler's and qmake's sysroot and also sets pkg-config paths."); desc( "-no-gcc-sysroot", "When using -sysroot, it disables the passing of --sysroot to the compiler.\n"); -- cgit v1.2.3 From 5c46d07a7ce1542301b6e428f9f8d07738e7518f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 12 Jul 2016 12:37:16 +0200 Subject: Optimize QString::insert() When the insertion position is not beyond end(), call resize() instead of expand(), which fills the new size with spaces, which, however would just be overwritten by the following memmove(). Add some Q_UNLIKELY to indicate that we strongly expect the resize() case to be the more common. Change-Id: Iaf3215dd53c2cbd18f2fd8a5f80af8f6844944da Reviewed-by: Edward Welbourne Reviewed-by: Anton Kudryavtsev Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 629a0bc744..9dc7136d2a 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1985,7 +1985,10 @@ QString &QString::insert(int i, QLatin1String str) return *this; int len = str.size(); - expand(qMax(d->size, i) + len - 1); + if (Q_UNLIKELY(i > d->size)) + expand(i + len - 1); + else + resize(d->size + len); ::memmove(d->data() + i + len, d->data() + i, (d->size - i - len) * sizeof(QChar)); qt_from_latin1(d->data() + i, s, uint(len)); @@ -2015,7 +2018,10 @@ QString& QString::insert(int i, const QChar *unicode, int size) return *this; } - expand(qMax(d->size, i) + size - 1); + if (Q_UNLIKELY(i > d->size)) + expand(i + size - 1); + else + resize(d->size + size); ::memmove(d->data() + i + size, d->data() + i, (d->size - i - size) * sizeof(QChar)); memcpy(d->data() + i, s, size * sizeof(QChar)); @@ -2035,7 +2041,10 @@ QString& QString::insert(int i, QChar ch) i += d->size; if (i < 0) return *this; - expand(qMax(i, d->size)); + if (Q_UNLIKELY(i > d->size)) + expand(i); + else + resize(d->size + 1); ::memmove(d->data() + i + 1, d->data() + i, (d->size - i - 1) * sizeof(QChar)); d->data()[i] = ch.unicode(); return *this; -- cgit v1.2.3 From d6177b55eaf2f6545af2e7b70def51940a1f3ab8 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Thu, 7 Jul 2016 13:35:35 +0200 Subject: OpenBSD: add X11R6/lib to QMAKE_RPATHDIR As OpenBSD ships its own X11, linker errors occur when not explicitly adding the X11R6/lib dir to rpath dirs. Change-Id: I75991e9d7de115d2d212a017d9c8f9aa93cecc27 Reviewed-by: Oswald Buddenhagen --- mkspecs/openbsd-g++/qmake.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mkspecs/openbsd-g++/qmake.conf b/mkspecs/openbsd-g++/qmake.conf index 4232759997..6124d31439 100644 --- a/mkspecs/openbsd-g++/qmake.conf +++ b/mkspecs/openbsd-g++/qmake.conf @@ -17,6 +17,8 @@ QMAKE_LIBDIR_X11 = /usr/X11R6/lib QMAKE_INCDIR_OPENGL = /usr/X11R6/include QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib +QMAKE_RPATHDIR += $$QMAKE_LIBDIR_X11 + include(../common/gcc-base-unix.conf) include(../common/g++-unix.conf) -- cgit v1.2.3 From 4397a1b26c244dc4cd0d3826e0c4135ec9003914 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Sat, 9 Jul 2016 10:44:31 +0200 Subject: FreeBSD: move order of includes for compiling The previous patch works for FreeBSD 10 but however not for 9 and 11 due to the order of includes. Move down to fix those compile issues due to unknown types when user.h is included first. Change-Id: Ica3d3ddf335a543c4a473e8b80d1667cb81667cf Reviewed-by: Thiago Macieira --- src/corelib/io/qlockfile_unix.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index eed3158fbe..57c689ac81 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -59,12 +59,12 @@ # include # include #elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) -# if !defined(Q_OS_NETBSD) -# include -# endif # include # include # include +# if !defined(Q_OS_NETBSD) +# include +# endif #endif QT_BEGIN_NAMESPACE -- cgit v1.2.3 From 9131f6e56139924162778c6c0538dda58d839bbb Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 12 Jul 2016 16:02:53 +0200 Subject: QCompleter::setModel(): Restore completion role When setting a QFileSystemModel as model, the completion role is set to QFileSystemModel::FileNameRole. This needs to be reset to the default Qt::EditRole when setting another model. Task-number: QTBUG-54642 Change-Id: Ie78d5d417e008ad05a2f995bdbc218b3ad1bc49c Reviewed-by: Andy Shaw --- src/widgets/util/qcompleter.cpp | 4 ++++ tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp index 55bb51d0a3..a036071893 100644 --- a/src/widgets/util/qcompleter.cpp +++ b/src/widgets/util/qcompleter.cpp @@ -1038,6 +1038,10 @@ void QCompleter::setModel(QAbstractItemModel *model) { Q_D(QCompleter); QAbstractItemModel *oldModel = d->proxy->sourceModel(); +#ifndef QT_NO_FILESYSTEMMODEL + if (qobject_cast(oldModel)) + setCompletionRole(Qt::EditRole); // QTBUG-54642, clear FileNameRole set by QFileSystemModel +#endif d->proxy->setSourceModel(model); if (d->popup) setPopup(d->popup); // set the model and make new connections diff --git a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp index e8ac9aa5d2..86a0bdf901 100644 --- a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp @@ -291,8 +291,8 @@ retry: // Testing get/set functions void tst_QCompleter::getSetCheck() { - QStandardItemModel model(3,3); - QCompleter completer(&model); + QStandardItemModel standardItemModel(3,3); + QCompleter completer(&standardItemModel); // QString QCompleter::completionPrefix() // void QCompleter::setCompletionPrefix(QString) @@ -352,6 +352,21 @@ void tst_QCompleter::getSetCheck() QCOMPARE(completer.wrapAround(), true); // default value completer.setWrapAround(false); QCOMPARE(completer.wrapAround(), false); + +#ifndef QT_NO_FILESYSTEMMODEL + // QTBUG-54642, changing from QFileSystemModel to another model should restore role. + completer.setCompletionRole(Qt::EditRole); + QCOMPARE(completer.completionRole(), static_cast(Qt::EditRole)); // default value + QFileSystemModel fileSystemModel; + completer.setModel(&fileSystemModel); + QCOMPARE(completer.completionRole(), static_cast(QFileSystemModel::FileNameRole)); + completer.setModel(&standardItemModel); + QCOMPARE(completer.completionRole(), static_cast(Qt::EditRole)); + completer.setCompletionRole(Qt::ToolTipRole); + QStandardItemModel standardItemModel2(2, 2); // Do not clobber a custom role when changing models + completer.setModel(&standardItemModel2); + QCOMPARE(completer.completionRole(), static_cast(Qt::ToolTipRole)); +#endif // QT_NO_FILESYSTEMMODEL } void tst_QCompleter::csMatchingOnCsSortedModel_data() -- cgit v1.2.3 From 07d3cbbe8450f870446f4bd2af2ec47baff23dc3 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Mon, 20 Jun 2016 00:11:34 +0200 Subject: Add warning when using pkg-config with a Qt build with it disabled This patch adds a warning that will be shown when link_pkgconfig is used in a project but Qt's configuration has it disabled. This can happen when Qt is built before pkg-config has been installed or if it's not detected. This will avoid user losing time trying to make pkg-config work while Qt just ignores it. Change-Id: Ieeff8dd6784b9430cfebef355855ec1be91bc96e Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt_functions.prf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index 86396958f1..4a1d265a8b 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -250,7 +250,10 @@ defineReplace(pkgConfigExecutable) { } defineTest(packagesExist) { - contains(QT_CONFIG, no-pkg-config):return(false) + contains(QT_CONFIG, no-pkg-config) { + warning("pkg-config disabled, can't check package existence") + return(false) + } # this can't be done in global scope here because qt_functions is loaded # before the .pro is parsed, so if the .pro set PKG_CONFIG, we wouldn't know it -- cgit v1.2.3 From b27d4835c2ae0d8767ca914acb72a4bdcea6fc85 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 29 Jun 2016 15:40:17 +0200 Subject: fix error() not propagating through if() if() would simply "downgrade" a fatal error to a false condition, which is certainly not expected. Change-Id: Ie9c54f2bddf588856498bf795007b341b7c9363a Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 4 ++-- qmake/library/qmakeevaluator.cpp | 9 +++++---- qmake/library/qmakeevaluator.h | 2 +- qmake/project.h | 2 +- tests/auto/tools/qmakelib/evaltest.cpp | 6 ++++++ 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index e200c7c551..d8cd8c5c90 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1221,8 +1221,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( evalError(fL1S("if(condition) requires one argument.")); return ReturnFalse; } - return returnBool(evaluateConditional(args.at(0).toQString(), - m_current.pro->fileName(), m_current.line)); + return evaluateConditional(args.at(0).toQString(), + m_current.pro->fileName(), m_current.line); } case T_CONFIG: { if (args.count() < 1 || args.count() > 2) { diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index e9da45c14d..30f8619bc1 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -1758,13 +1758,14 @@ ProStringList QMakeEvaluator::evaluateExpandFunction( return ProStringList(); } -bool QMakeEvaluator::evaluateConditional(const QString &cond, const QString &where, int line) +QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditional( + const QString &cond, const QString &where, int line) { - bool ret = false; + VisitReturn ret = ReturnFalse; ProFile *pro = m_parser->parsedProBlock(cond, where, line, QMakeParser::TestGrammar); if (pro->isOk()) { m_locationStack.push(m_current); - ret = visitProBlock(pro, pro->tokPtr()) == ReturnTrue; + ret = visitProBlock(pro, pro->tokPtr()); m_current = m_locationStack.pop(); } pro->deref(); @@ -1776,7 +1777,7 @@ void QMakeEvaluator::checkRequirements(const ProStringList &deps) { ProStringList &failed = valuesRef(ProKey("QMAKE_FAILED_REQUIREMENTS")); foreach (const ProString &dep, deps) - if (!evaluateConditional(dep.toQString(), m_current.pro->fileName(), m_current.line)) + if (evaluateConditional(dep.toQString(), m_current.pro->fileName(), m_current.line) != ReturnTrue) failed << dep; } #endif diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index 312f1385fb..7db07b17ba 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -220,7 +220,7 @@ public: ProStringList evaluateBuiltinExpand(int func_t, const ProKey &function, const ProStringList &args); VisitReturn evaluateBuiltinConditional(int func_t, const ProKey &function, const ProStringList &args); - bool evaluateConditional(const QString &cond, const QString &where, int line = -1); + VisitReturn evaluateConditional(const QString &cond, const QString &where, int line = -1); #ifdef PROEVALUATOR_FULL void checkRequirements(const ProStringList &deps); #endif diff --git a/qmake/project.h b/qmake/project.h index 7cd49a457c..2c4883e578 100644 --- a/qmake/project.h +++ b/qmake/project.h @@ -60,7 +60,7 @@ public: ProString expand(const QString &v, const QString &file, int line); QStringList expand(const ProKey &func, const QList &args); bool test(const QString &v, const QString &file, int line) - { m_current.clear(); return evaluateConditional(v, file, line); } + { m_current.clear(); return evaluateConditional(v, file, line) == ReturnTrue; } bool test(const ProKey &func, const QList &args); bool isSet(const ProKey &v) const { return m_valuemapStack.first().contains(v); } diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index beafef5ad2..f172cda865 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -2103,6 +2103,12 @@ void tst_qmakelib::addTestFunctions(const QString &qindir) << "Project ERROR: World, you FAIL!" << false; + QTest::newRow("if(error())") + << "if(error(\\'World, you FAIL!\\')): OK = 1\nOKE = 1" + << "OK = UNDEF\nOKE = UNDEF" + << "Project ERROR: World, you FAIL!" + << false; + QTest::newRow("system()") << "system('" #ifdef Q_OS_WIN -- cgit v1.2.3 From 339b9706ccbed4063a92337c9994731793558b0a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 29 Jun 2016 16:56:57 +0200 Subject: make error() propagate from custom replace functions it didn't, which is rather unexpected. Change-Id: I8cdb7b1490a8c2207809812b93cc65fbe23a1b98 Reviewed-by: Joerg Bornemann --- qmake/library/qmakeevaluator.cpp | 110 ++++++++++++++++++++------------- qmake/library/qmakeevaluator.h | 14 ++--- qmake/project.cpp | 9 +-- tests/auto/tools/qmakelib/evaltest.cpp | 66 ++++++++++++++++++++ 4 files changed, 144 insertions(+), 55 deletions(-) diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 30f8619bc1..1243a77afa 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -409,7 +409,7 @@ static ALWAYS_INLINE void addStrList( } } -void QMakeEvaluator::evaluateExpression( +QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateExpression( const ushort *&tokPtr, ProStringList *ret, bool joined) { debugMsg(2, joined ? "evaluating joined expression" : "evaluating expression"); @@ -459,12 +459,15 @@ void QMakeEvaluator::evaluateExpression( case TokFuncName: { const ProKey &func = pro->getHashStr(tokPtr); debugMsg(2, "function %s", dbgKey(func)); - addStrList(evaluateExpandFunction(func, tokPtr), tok, ret, pending, joined); + ProStringList val; + if (evaluateExpandFunction(func, tokPtr, &val) == ReturnError) + return ReturnError; + addStrList(val, tok, ret, pending, joined); break; } default: debugMsg(2, "evaluated expression => %s", dbgStrList(*ret)); tokPtr--; - return; + return ReturnTrue; } } } @@ -536,7 +539,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( case TokAppendUnique: case TokRemove: case TokReplace: - visitProVariable(tok, curr, tokPtr); + ret = visitProVariable(tok, curr, tokPtr); + if (ret == ReturnError) + break; curr.clear(); continue; case TokBranch: @@ -696,9 +701,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( continue; default: { const ushort *oTokPtr = --tokPtr; - evaluateExpression(tokPtr, &curr, false); - if (tokPtr != oTokPtr) - continue; + ret = evaluateExpression(tokPtr, &curr, false); + if (ret == ReturnError || tokPtr != oTokPtr) + break; } Q_ASSERT_X(false, "visitProBlock", "unexpected item type"); continue; @@ -731,7 +736,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop( int index = 0; ProKey variable; ProStringList oldVarVal; - ProString it_list = expandVariableReferences(exprPtr, 0, true).at(0); + ProStringList it_list_out; + if (expandVariableReferences(exprPtr, 0, &it_list_out, true) == ReturnError) + return ReturnError; + ProString it_list = it_list_out.at(0); if (_variable.isEmpty()) { if (it_list != statics.strever) { evalError(fL1S("Invalid loop expression.")); @@ -828,7 +836,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop( return ret; } -void QMakeEvaluator::visitProVariable( +QMakeEvaluator::VisitReturn QMakeEvaluator::visitProVariable( ushort tok, const ProStringList &curr, const ushort *&tokPtr) { int sizeHint = *tokPtr++; @@ -837,24 +845,26 @@ void QMakeEvaluator::visitProVariable( skipExpression(tokPtr); if (!m_cumulative || !curr.isEmpty()) evalError(fL1S("Left hand side of assignment must expand to exactly one word.")); - return; + return ReturnTrue; } const ProKey &varName = map(curr.first()); if (tok == TokReplace) { // ~= // DEFINES ~= s/a/b/?[gqi] - const ProStringList &varVal = expandVariableReferences(tokPtr, sizeHint, true); + ProStringList varVal; + if (expandVariableReferences(tokPtr, sizeHint, &varVal, true) == ReturnError) + return ReturnError; const QString &val = varVal.at(0).toQString(m_tmp1); if (val.length() < 4 || val.at(0) != QLatin1Char('s')) { evalError(fL1S("The ~= operator can handle only the s/// function.")); - return; + return ReturnTrue; } QChar sep = val.at(1); QStringList func = val.split(sep); if (func.count() < 3 || func.count() > 4) { evalError(fL1S("The s/// function expects 3 or 4 arguments.")); - return; + return ReturnTrue; } bool global = false, quote = false, case_sense = false; @@ -875,7 +885,9 @@ void QMakeEvaluator::visitProVariable( replaceInList(&valuesRef(varName), regexp, replace, global, m_tmp2); debugMsg(2, "replaced %s with %s", dbgQStr(pattern), dbgQStr(replace)); } else { - ProStringList varVal = expandVariableReferences(tokPtr, sizeHint); + ProStringList varVal; + if (expandVariableReferences(tokPtr, sizeHint, &varVal, false) == ReturnError) + return ReturnError; switch (tok) { default: // whatever - cannot happen case TokAssign: // = @@ -923,6 +935,8 @@ void QMakeEvaluator::visitProVariable( else if (varName == statics.strREQUIRES) checkRequirements(values(varName)); #endif + + return ReturnTrue; } void QMakeEvaluator::setTemplate() @@ -1610,18 +1624,18 @@ bool QMakeEvaluator::isActiveConfig(const QString &config, bool regex) return false; } -ProStringList QMakeEvaluator::expandVariableReferences( - const ushort *&tokPtr, int sizeHint, bool joined) +QMakeEvaluator::VisitReturn QMakeEvaluator::expandVariableReferences( + const ushort *&tokPtr, int sizeHint, ProStringList *ret, bool joined) { - ProStringList ret; - ret.reserve(sizeHint); + ret->reserve(sizeHint); forever { - evaluateExpression(tokPtr, &ret, joined); + if (evaluateExpression(tokPtr, ret, joined) == ReturnError) + return ReturnError; switch (*tokPtr) { case TokValueTerminator: case TokFuncTerminator: tokPtr++; - return ret; + return ReturnTrue; case TokArgSeparator: if (joined) { tokPtr++; @@ -1635,28 +1649,28 @@ ProStringList QMakeEvaluator::expandVariableReferences( } } -QList QMakeEvaluator::prepareFunctionArgs(const ushort *&tokPtr) +QMakeEvaluator::VisitReturn QMakeEvaluator::prepareFunctionArgs( + const ushort *&tokPtr, QList *ret) { - QList args_list; if (*tokPtr != TokFuncTerminator) { for (;; tokPtr++) { ProStringList arg; - evaluateExpression(tokPtr, &arg, false); - args_list << arg; + if (evaluateExpression(tokPtr, &arg, false) == ReturnError) + return ReturnError; + *ret << arg; if (*tokPtr == TokFuncTerminator) break; Q_ASSERT(*tokPtr == TokArgSeparator); } } tokPtr++; - return args_list; + return ReturnTrue; } -ProStringList QMakeEvaluator::evaluateFunction( - const ProFunctionDef &func, const QList &argumentsList, VisitReturn *ok) +QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFunction( + const ProFunctionDef &func, const QList &argumentsList, ProStringList *ret) { VisitReturn vr; - ProStringList ret; if (m_valuemapStack.count() >= 100) { evalError(fL1S("Ran into infinite recursion (depth > 100).")); @@ -1675,25 +1689,22 @@ ProStringList QMakeEvaluator::evaluateFunction( vr = visitProBlock(func.pro(), func.tokPtr()); if (vr == ReturnReturn) vr = ReturnTrue; - ret = m_returnValue; + if (vr == ReturnTrue) + *ret = m_returnValue; m_returnValue.clear(); m_current = m_locationStack.pop(); m_valuemapStack.pop(); } - if (ok) - *ok = vr; - if (vr == ReturnTrue) - return ret; - return ProStringList(); + return vr; } QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBoolFunction( const ProFunctionDef &func, const QList &argumentsList, const ProString &function) { - VisitReturn vr; - ProStringList ret = evaluateFunction(func, argumentsList, &vr); + ProStringList ret; + VisitReturn vr = evaluateFunction(func, argumentsList, &ret); if (vr == ReturnTrue) { if (ret.isEmpty()) return ReturnTrue; @@ -1721,13 +1732,18 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction( { if (int func_t = statics.functions.value(func)) { //why don't the builtin functions just use args_list? --Sam - return evaluateBuiltinConditional(func_t, func, expandVariableReferences(tokPtr, 5, true)); + ProStringList args; + if (expandVariableReferences(tokPtr, 5, &args, true) == ReturnError) + return ReturnError; + return evaluateBuiltinConditional(func_t, func, args); } QHash::ConstIterator it = m_functionDefs.testFunctions.constFind(func); if (it != m_functionDefs.testFunctions.constEnd()) { - const QList args = prepareFunctionArgs(tokPtr); + QList args; + if (prepareFunctionArgs(tokPtr, &args) == ReturnError) + return ReturnError; traceMsg("calling %s(%s)", dbgKey(func), dbgStrListList(args)); return evaluateBoolFunction(*it, args, func); } @@ -1737,25 +1753,31 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction( return ReturnFalse; } -ProStringList QMakeEvaluator::evaluateExpandFunction( - const ProKey &func, const ushort *&tokPtr) +QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateExpandFunction( + const ProKey &func, const ushort *&tokPtr, ProStringList *ret) { if (int func_t = statics.expands.value(func)) { //why don't the builtin functions just use args_list? --Sam - return evaluateBuiltinExpand(func_t, func, expandVariableReferences(tokPtr, 5, true)); + ProStringList args; + if (expandVariableReferences(tokPtr, 5, &args, true) == ReturnError) + return ReturnError; + *ret = evaluateBuiltinExpand(func_t, func, args); + return ReturnTrue; } QHash::ConstIterator it = m_functionDefs.replaceFunctions.constFind(func); if (it != m_functionDefs.replaceFunctions.constEnd()) { - const QList args = prepareFunctionArgs(tokPtr); + QList args; + if (prepareFunctionArgs(tokPtr, &args) == ReturnError) + return ReturnError; traceMsg("calling $$%s(%s)", dbgKey(func), dbgStrListList(args)); - return evaluateFunction(*it, args, 0); + return evaluateFunction(*it, args, ret); } skipExpression(tokPtr); evalError(fL1S("'%1' is not a recognized replace function.").arg(func.toQString(m_tmp1))); - return ProStringList(); + return ReturnFalse; } QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditional( diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index 7db07b17ba..9625c8b8df 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -153,7 +153,7 @@ public: { return b ? ReturnTrue : ReturnFalse; } static ALWAYS_INLINE uint getBlockLen(const ushort *&tokPtr); - void evaluateExpression(const ushort *&tokPtr, ProStringList *ret, bool joined); + VisitReturn evaluateExpression(const ushort *&tokPtr, ProStringList *ret, bool joined); static ALWAYS_INLINE void skipStr(const ushort *&tokPtr); static ALWAYS_INLINE void skipHashStr(const ushort *&tokPtr); void skipExpression(const ushort *&tokPtr); @@ -173,7 +173,7 @@ public: VisitReturn visitProLoop(const ProKey &variable, const ushort *exprPtr, const ushort *tokPtr); void visitProFunctionDef(ushort tok, const ProKey &name, const ushort *tokPtr); - void visitProVariable(ushort tok, const ProStringList &curr, const ushort *&tokPtr); + VisitReturn visitProVariable(ushort tok, const ProStringList &curr, const ushort *&tokPtr); ALWAYS_INLINE const ProKey &map(const ProString &var) { return map(var.toKey()); } const ProKey &map(const ProKey &var); @@ -182,7 +182,7 @@ public: void setTemplate(); ProStringList split_value_list(const QString &vals, const ProFile *source = 0); - ProStringList expandVariableReferences(const ushort *&tokPtr, int sizeHint = 0, bool joined = false); + VisitReturn expandVariableReferences(const ushort *&tokPtr, int sizeHint, ProStringList *ret, bool joined); QString currentFileName() const; QString currentDirectory() const; @@ -207,14 +207,14 @@ public: void deprecationWarning(const QString &msg) const { message(QMakeHandler::EvalWarnDeprecated, msg); } - QList prepareFunctionArgs(const ushort *&tokPtr); - ProStringList evaluateFunction(const ProFunctionDef &func, - const QList &argumentsList, VisitReturn *ok); + VisitReturn prepareFunctionArgs(const ushort *&tokPtr, QList *ret); + VisitReturn evaluateFunction(const ProFunctionDef &func, + const QList &argumentsList, ProStringList *ret); VisitReturn evaluateBoolFunction(const ProFunctionDef &func, const QList &argumentsList, const ProString &function); - ProStringList evaluateExpandFunction(const ProKey &function, const ushort *&tokPtr); + VisitReturn evaluateExpandFunction(const ProKey &function, const ushort *&tokPtr, ProStringList *ret); VisitReturn evaluateConditionalFunction(const ProKey &function, const ushort *&tokPtr); ProStringList evaluateBuiltinExpand(int func_t, const ProKey &function, const ProStringList &args); diff --git a/qmake/project.cpp b/qmake/project.cpp index faea6da650..9c06f7ef5d 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -110,9 +110,8 @@ QStringList QMakeProject::expand(const ProKey &func, const QList QHash::ConstIterator it = m_functionDefs.replaceFunctions.constFind(func); if (it != m_functionDefs.replaceFunctions.constEnd()) { - QMakeProject::VisitReturn vr; - ProStringList ret = evaluateFunction(*it, args, &vr); - if (vr == QMakeProject::ReturnError) + ProStringList ret; + if (evaluateFunction(*it, args, &ret) == QMakeProject::ReturnError) exit(3); return ret.toQStringList(); } @@ -130,7 +129,9 @@ ProString QMakeProject::expand(const QString &expr, const QString &where, int li m_current.pro = pro; m_current.line = 0; const ushort *tokPtr = pro->tokPtr(); - ProStringList result = expandVariableReferences(tokPtr, 1, true); + ProStringList result; + if (expandVariableReferences(tokPtr, 1, &result, true) == ReturnError) + exit(3); if (!result.isEmpty()) ret = result.at(0); } diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index f172cda865..b7acf70e88 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -641,6 +641,72 @@ void tst_qmakelib::addControlStructs() << "VAR = final" << "" << true; + + QTest::newRow("error() from replace function (assignment)") + << "defineReplace(func) {\nerror(error)\n}\n" + "VAR = $$func()\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("error() from replace function (replacement)") + << "defineReplace(func) {\nerror(error)\n}\n" + "VAR = $$func()\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("error() from replace function (LHS)") + << "defineReplace(func) {\nerror(error)\nreturn(VAR)\n}\n" + "$$func() = 1\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("error() from replace function (loop variable)") + << "defineReplace(func) {\nerror(error)\nreturn(BLAH)\n}\n" + "for($$func()) {\nVAR = $$BLAH\nbreak()\n}\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("error() from replace function (built-in test arguments)") + << "defineReplace(func) {\nerror(error)\n}\n" + "message($$func()): VAR = 1\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("error() from replace function (built-in replace arguments)") + << "defineReplace(func) {\nerror(error)\n}\n" + "VAR = $$upper($$func())\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("error() from replace function (custom test arguments)") + << "defineReplace(func) {\nerror(error)\n}\n" + "defineTest(custom) {\n}\n" + "custom($$func()): VAR = 1\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("error() from replace function (custom replace arguments)") + << "defineReplace(func) {\nerror(error)\nreturn(1)\n}\n" + "defineReplace(custom) {\nreturn($$1)\n}\n" + "VAR = $$custom($$func(1))\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; } void tst_qmakelib::addReplaceFunctions(const QString &qindir) -- cgit v1.2.3 From 1b4ea11332f74984a62a4cc4597ad49f5b5269dc Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 30 Jun 2016 16:02:29 +0200 Subject: make error() propagate from requires() and REQUIRES= that can make sense if a function which determines the availability of a dependency fails to do so for unexpected reasons. Change-Id: If6cd113df25aee66830c120a2fab067c822a4543 Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 3 ++- qmake/library/qmakeevaluator.cpp | 13 +++++++++---- qmake/library/qmakeevaluator.h | 2 +- tests/auto/tools/qmakelib/evaltest.cpp | 14 ++++++++++++++ 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index d8cd8c5c90..272b0cc30d 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1200,7 +1200,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( return ReturnFalse; case T_REQUIRES: #ifdef PROEVALUATOR_FULL - checkRequirements(args); + if (checkRequirements(args) == ReturnError) + return ReturnError; #endif return ReturnFalse; // Another qmake breakage case T_EVAL: { diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 1243a77afa..a09168876a 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -933,7 +933,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProVariable( } #ifdef PROEVALUATOR_FULL else if (varName == statics.strREQUIRES) - checkRequirements(values(varName)); + return checkRequirements(values(varName)); #endif return ReturnTrue; @@ -1795,12 +1795,17 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditional( } #ifdef PROEVALUATOR_FULL -void QMakeEvaluator::checkRequirements(const ProStringList &deps) +QMakeEvaluator::VisitReturn QMakeEvaluator::checkRequirements(const ProStringList &deps) { ProStringList &failed = valuesRef(ProKey("QMAKE_FAILED_REQUIREMENTS")); - foreach (const ProString &dep, deps) - if (evaluateConditional(dep.toQString(), m_current.pro->fileName(), m_current.line) != ReturnTrue) + foreach (const ProString &dep, deps) { + VisitReturn vr = evaluateConditional(dep.toQString(), m_current.pro->fileName(), m_current.line); + if (vr == ReturnError) + return ReturnError; + if (vr != ReturnTrue) failed << dep; + } + return ReturnTrue; } #endif diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index 9625c8b8df..f370898cc9 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -222,7 +222,7 @@ public: VisitReturn evaluateConditional(const QString &cond, const QString &where, int line = -1); #ifdef PROEVALUATOR_FULL - void checkRequirements(const ProStringList &deps); + VisitReturn checkRequirements(const ProStringList &deps); #endif void updateMkspecPaths(); diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index b7acf70e88..934ee580ed 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -707,6 +707,20 @@ void tst_qmakelib::addControlStructs() << "VAR = UNDEF\nOKE = UNDEF" << "Project ERROR: error" << false; + + QTest::newRow("REQUIRES = error()") + << "REQUIRES = error(error)\n" + "OKE = 1" + << "OKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("requires(error())") + << "requires(error(error))\n" + "OKE = 1" + << "OKE = UNDEF" + << "Project ERROR: error" + << false; } void tst_qmakelib::addReplaceFunctions(const QString &qindir) -- cgit v1.2.3 From dacf3994ba29106132c3a377dba303acdb74daca Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 30 Jun 2016 17:26:01 +0200 Subject: fix custom functions inheriting other functions' arguments Task-number: QTBUG-41830 Change-Id: Iba3eee4975a1ee671b7190e52c0efc9a18147c62 Reviewed-by: Joerg Bornemann Reviewed-by: Lars Knoll Reviewed-by: Oswald Buddenhagen --- qmake/library/qmakeevaluator.cpp | 56 +++++++++++++++++++++++----------- tests/auto/tools/qmakelib/evaltest.cpp | 17 +++++++++++ 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index a09168876a..48bd17e789 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -1809,19 +1809,35 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::checkRequirements(const ProStringLis } #endif +static bool isFunctParam(const ProKey &variableName) +{ + const int len = variableName.size(); + const QChar *data = variableName.constData(); + for (int i = 0; i < len; i++) { + ushort c = data[i].unicode(); + if (c < '0' || c > '9') + return false; + } + return true; +} + ProValueMap *QMakeEvaluator::findValues(const ProKey &variableName, ProValueMap::Iterator *rit) { ProValueMapStack::Iterator vmi = m_valuemapStack.end(); - do { + for (bool first = true; ; first = false) { --vmi; ProValueMap::Iterator it = (*vmi).find(variableName); if (it != (*vmi).end()) { if (it->constBegin() == statics.fakeValue.constBegin()) - return 0; + break; *rit = it; return &(*vmi); } - } while (vmi != m_valuemapStack.begin()); + if (vmi == m_valuemapStack.begin()) + break; + if (first && isFunctParam(variableName)) + break; + } return 0; } @@ -1833,18 +1849,20 @@ ProStringList &QMakeEvaluator::valuesRef(const ProKey &variableName) it->clear(); return *it; } - ProValueMapStack::Iterator vmi = m_valuemapStack.end(); - if (--vmi != m_valuemapStack.begin()) { - do { - --vmi; - ProValueMap::ConstIterator it = (*vmi).constFind(variableName); - if (it != (*vmi).constEnd()) { - ProStringList &ret = m_valuemapStack.top()[variableName]; - if (it->constBegin() != statics.fakeValue.constBegin()) - ret = *it; - return ret; - } - } while (vmi != m_valuemapStack.begin()); + if (!isFunctParam(variableName)) { + ProValueMapStack::Iterator vmi = m_valuemapStack.end(); + if (--vmi != m_valuemapStack.begin()) { + do { + --vmi; + ProValueMap::ConstIterator it = (*vmi).constFind(variableName); + if (it != (*vmi).constEnd()) { + ProStringList &ret = m_valuemapStack.top()[variableName]; + if (it->constBegin() != statics.fakeValue.constBegin()) + ret = *it; + return ret; + } + } while (vmi != m_valuemapStack.begin()); + } } return m_valuemapStack.top()[variableName]; } @@ -1852,7 +1870,7 @@ ProStringList &QMakeEvaluator::valuesRef(const ProKey &variableName) ProStringList QMakeEvaluator::values(const ProKey &variableName) const { ProValueMapStack::ConstIterator vmi = m_valuemapStack.constEnd(); - do { + for (bool first = true; ; first = false) { --vmi; ProValueMap::ConstIterator it = (*vmi).constFind(variableName); if (it != (*vmi).constEnd()) { @@ -1860,7 +1878,11 @@ ProStringList QMakeEvaluator::values(const ProKey &variableName) const break; return *it; } - } while (vmi != m_valuemapStack.constBegin()); + if (vmi == m_valuemapStack.constBegin()) + break; + if (first && isFunctParam(variableName)) + break; + } return ProStringList(); } diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index 934ee580ed..f70ee683e2 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -599,6 +599,23 @@ void tst_qmakelib::addControlStructs() << "" << true; + QTest::newRow("function arguments") + << "defineTest(func) {\n" + "defined(1, var) {\nd1 = 1\nexport(d1)\n}\n" + "defined(3, var) {\nd3 = 1\nexport(d3)\n}\n" + "x1 = $$1\nexport(x1)\n" + "2 += foo\nx2 = $$2\nexport(x2)\n" + "x3 = $$3\nexport(x3)\n" + "4 += foo\nx4 = $$4\nexport(x4)\n" + "x5 = $$5\nexport(x5)\n" + "6 += foo\nx6 = $$6\nexport(x6)\n" + "}\n" + "1 = first\n2 = second\n3 = third\n4 = fourth\nfunc(one, two)" + << "1 = first\n2 = second\n3 = third\n4 = fourth\n5 = UNDEF\n6 = UNDEF\n" + "d1 = 1\nd3 = UNDEF\nx1 = one\nx2 = two foo\nx3 =\nx4 = foo\nx5 =\nx6 = foo" + << "" + << true; + QTest::newRow("ARGC and ARGS") << "defineTest(func) {\n" "export(ARGC)\n" -- cgit v1.2.3 From d459a6b0e0d4f128caceaafe981ecf374bb3e420 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 5 Jul 2016 20:00:17 +0200 Subject: fix calculations of worst-case size requirements for token buffer Change-Id: I3aa4c736acec44f95a0a33c7baae9276568f684f Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- qmake/library/qmakeparser.cpp | 15 +++++++++------ tests/auto/tools/qmakelib/parsertest.cpp | 7 +++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp index 8170eee76c..180fe90878 100644 --- a/qmake/library/qmakeparser.cpp +++ b/qmake/library/qmakeparser.cpp @@ -304,27 +304,30 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra // Worst-case size calculations: // - line marker adds 1 (2-nl) to 1st token of each line // - empty assignment "A=":2 => - // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokAssign(1) + 0(1) + + // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokAssign(1) + size_hint(1) + // TokValueTerminator(1) == 8 (9) // - non-empty assignment "A=B C":5 => - // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokAssign(1) + 2(1) + + // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokAssign(1) + size_hint(1) + // TokLiteral(1) + len(1) + "B"(1) + // TokLiteral(1) + len(1) + "C"(1) + TokValueTerminator(1) == 14 (15) // - variable expansion: "$$f":3 => // TokVariable(1) + hash(2) + len(1) + "f"(1) = 5 // - function expansion: "$$f()":5 => // TokFuncName(1) + hash(2) + len(1) + "f"(1) + TokFuncTerminator(1) = 6 + // - test literal: "X":1 => + // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokCondition(1) = 6 (7) // - scope: "X:":2 => // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokCondition(1) + - // TokBranch(1) + len(2) + ... + len(2) + ... == 10 - // - test: "X():":4 => + // TokBranch(1) + len(2) + ... + len(2) + ... == 11 (12) + // - test call: "X():":4 => // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokTestCall(1) + TokFuncTerminator(1) + - // TokBranch(1) + len(2) + ... + len(2) + ... == 11 + // TokBranch(1) + len(2) + ... + len(2) + ... == 12 (13) // - "for(A,B):":9 => // TokForLoop(1) + hash(2) + len(1) + "A"(1) + // len(2) + TokLiteral(1) + len(1) + "B"(1) + TokValueTerminator(1) + // len(2) + ... + TokTerminator(1) == 14 (15) - tokBuff.reserve((in.size() + 1) * 5); + // One extra for possibly missing trailing newline. + tokBuff.reserve((in.size() + 1) * 7); ushort *tokPtr = (ushort *)tokBuff.constData(); // Current writing position // Expression precompiler buffer. diff --git a/tests/auto/tools/qmakelib/parsertest.cpp b/tests/auto/tools/qmakelib/parsertest.cpp index a7b7431a98..7e6757a2ff 100644 --- a/tests/auto/tools/qmakelib/parsertest.cpp +++ b/tests/auto/tools/qmakelib/parsertest.cpp @@ -1872,6 +1872,13 @@ void tst_qmakelib::addParseAbuse() /* 24 */ /* else branch */ << I(0)) << "in:1: OR operator without prior condition." << false; + + // Token buffer overflow. Verify with Valgrind or asan. + QTest::newRow("QTCREATORBUG-16508") + << "a{b{c{d{" + << TS() + << "in:2: Missing closing brace(s)." + << false; } void tst_qmakelib::proParser_data() -- cgit v1.2.3 From 3c8134958c66f40bb86588aa91b83bf58b5de0c9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 5 Jul 2016 18:07:14 +0200 Subject: fix raw data leak in $$absolute_path() when the file name is empty, the path will be returned verbatim. this must be considered when constructing the return value. Task-number: QTBUG-54550 Change-Id: Ie108ed52275e66a154ef63bd6f7193f55b3e0454 Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 6 +++++- tests/auto/tools/qmakelib/evaltest.cpp | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 272b0cc30d..c1d23295e7 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1027,7 +1027,11 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( QString rstr = QDir::cleanPath( QDir(args.count() > 1 ? args.at(1).toQString(m_tmp2) : currentDirectory()) .absoluteFilePath(args.at(0).toQString(m_tmp1))); - ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0))); + ret << (rstr.isSharedWith(m_tmp1) + ? args.at(0) + : args.count() > 1 && rstr.isSharedWith(m_tmp2) + ? args.at(1) + : ProString(rstr).setSource(args.at(0))); } break; case E_RELATIVE_PATH: diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index f70ee683e2..09482d86d9 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -2482,6 +2482,14 @@ void tst_qmakelib::proEval_data() "Project MESSAGE: assign split joined: word: this is a test:done\n" "Project MESSAGE: assign split quoted: word this is a test done" << true; + + // Raw data leak with empty file name. Verify with Valgrind or asan. + QTest::newRow("QTBUG-54550") + << "FULL = /there/is\n" + "VAR = $$absolute_path(, $$FULL/nothing/here/really)" + << "VAR = /there/is/nothing/here/really" + << "" + << true; } static QString formatValue(const ProStringList &vals) -- cgit v1.2.3 From fc57a6587b75a56b5f2f041c94a7ae656eba54b9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 8 Jul 2016 19:02:59 +0200 Subject: remove redundant condition from private module use warning the whole point of the check is ensuring that the message is printed only once for each sub-project, so !build_pass alone is fully adequate. Change-Id: Ib8f821ead6709efc9bfa935e1d05f8caba02a814 Reviewed-by: Jake Petroules --- mkspecs/features/qt.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 75b84ff6aa..be08a2a051 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -156,7 +156,7 @@ for(ever) { !isEmpty(var_sfx): break() var_sfx = _PRIVATE } -!isEmpty(using_privates):!no_private_qt_headers_warning:if(!debug_and_release|!build_pass) { +!isEmpty(using_privates):!no_private_qt_headers_warning:!build_pass { message("This project is using private headers and will therefore be tied to this specific Qt module build version.") message("Running this project against other versions of the Qt modules may crash at any arbitrary point.") message("This is not a bug, but a result of using Qt internals. You have been warned!") -- cgit v1.2.3 From a42c9cfc285a7b71b971a8aa000ca8d5216592ba Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 8 Jul 2016 19:09:49 +0200 Subject: generalize references to exclusive builds exclusive_builds_post.prf (via default_post.prf) processes debug_and_release into BUILDS, so .prfs which can rely on being executed later (because they are loaded via CONFIG) can rely on BUILDS and related variables. Change-Id: I5677079ad5145bf493af17b4b60347208572fd21 Reviewed-by: Jake Petroules Reviewed-by: Oswald Buddenhagen --- mkspecs/features/file_copies.prf | 3 +-- mkspecs/features/qt_docs_targets.prf | 2 +- mkspecs/features/resources.prf | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/file_copies.prf b/mkspecs/features/file_copies.prf index 6df294212c..4ebf41c78f 100644 --- a/mkspecs/features/file_copies.prf +++ b/mkspecs/features/file_copies.prf @@ -1,8 +1,7 @@ isEmpty(COPIES): return() contains(TEMPLATE, .*subdirs): error("COPIES does not work with TEMPLATE=subdirs") -build_pass:build_all: \ - debug_and_release:debug { +build_pass:build_all:!isEqual(BUILD_PASS, $$first(BUILDS)) { # Avoid that multiple build passes race with each other. # This will fail to copy anything if the user explicitly invokes # only the non-primary build. This is unfixable, as at qmake time diff --git a/mkspecs/features/qt_docs_targets.prf b/mkspecs/features/qt_docs_targets.prf index 1f9e2b0b47..9e96432462 100644 --- a/mkspecs/features/qt_docs_targets.prf +++ b/mkspecs/features/qt_docs_targets.prf @@ -30,7 +30,7 @@ contains(TEMPLATE, subdirs) { for(inst, DOC_TARGETS): \ prepareRecursiveTarget($$inst) } else { - debug_and_release:!build_pass { + !isEmpty(BUILDS):!build_pass { sub = $$first(BUILDS) for(inst, DOC_TARGETS) { $${inst}.CONFIG = recursive diff --git a/mkspecs/features/resources.prf b/mkspecs/features/resources.prf index 1f04c8b0d7..bc548ced05 100644 --- a/mkspecs/features/resources.prf +++ b/mkspecs/features/resources.prf @@ -35,7 +35,7 @@ for(resource, RESOURCES) { resource_file = $$RCC_DIR/qmake_$${resource}.qrc - !debug_and_release|build_pass { + isEmpty(BUILDS)|build_pass { # Collection of files, generate qrc file prefix = $$eval($${resource}.prefix) isEmpty(prefix): \ -- cgit v1.2.3 From 5cbe16be78121b503104f57c4aab03b378823e64 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Thu, 23 Jun 2016 16:16:06 -0700 Subject: Set library strip flags on Apple platforms This was missed in ab599a39313c22fd14cc5466cea5c61bbcdbba8e when QMAKE_STRIP was set as a side effect of adding support for separate debug info. Task-number: QTBUG-54212 Change-Id: I86dd040dbefec4c58879c7d029ed89dd8bad3daf Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- mkspecs/common/mac.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/mkspecs/common/mac.conf b/mkspecs/common/mac.conf index aac9d1b3d7..d267d1f10d 100644 --- a/mkspecs/common/mac.conf +++ b/mkspecs/common/mac.conf @@ -31,6 +31,7 @@ QMAKE_LIBS_THREAD = QMAKE_DSYMUTIL = dsymutil QMAKE_STRIP = strip +QMAKE_STRIPFLAGS_LIB += -S -x QMAKE_AR = ar cq QMAKE_RANLIB = ranlib -s -- cgit v1.2.3 From 1e843b41b6b2ba164615543a5683800d074e60f4 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 17 Mar 2016 15:37:39 +0100 Subject: Mac: Read in the string with QString::fromUtf8() as it is UTF8 encoded Task-number: QTBUG-47358 Change-Id: I50943867d3a57c4db4fe20e55e60d097742e9104 Reviewed-by: Jake Petroules Reviewed-by: jian liang --- src/platformsupport/clipboard/qmacmime.mm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index 317648956c..2e3257cfcf 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -403,9 +403,7 @@ QVariant QMacPasteboardMimeUnicodeText::convertToMime(const QString &mimetype, Q // I can only handle two types (system and unicode) so deal with them that way QVariant ret; if (flavor == QLatin1String("public.utf8-plain-text")) { - ret = QString(QCFString(CFStringCreateWithBytes(kCFAllocatorDefault, - reinterpret_cast(firstData.constData()), - firstData.size(), CFStringGetSystemEncoding(), false))); + ret = QString::fromUtf8(firstData); } else if (flavor == QLatin1String("public.utf16-plain-text")) { ret = QString(reinterpret_cast(firstData.constData()), firstData.size() / sizeof(QChar)); -- cgit v1.2.3 From 21c8a66a152e3184d8f965dc4cf2a1bee234780d Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 11 Jul 2016 13:00:15 -0700 Subject: QCocoaMenuBar: Sync items only when they are attached to a menu Another one of Cocoa's capricious behaviors. Evidence shows that the menu item's submenu property needs to be set before we can set the item's hidden property. We ensure this is the case by getting the NSMenuItem through QCocoaMenu::attachedItem() instead of QCocoaMenuBar::nativeItemForMenu() in QCocoaMenuBar::syncMenu(). Change-Id: Id50356dae5f556fa3d745ba9a5982e5a72bf0ac2 Task-number: QTBUG-54637 Reviewed-by: Jake Petroules Reviewed-by: Jason Haslam --- src/plugins/platforms/cocoa/qcocoamenubar.mm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index a534d2064e..9b03ea17c4 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -173,9 +173,11 @@ void QCocoaMenuBar::syncMenu(QPlatformMenu *menu) } } - NSMenuItem *nativeMenuItem = nativeItemForMenu(cocoaMenu); - nativeMenuItem.title = cocoaMenu->nsMenu().title; - nativeMenuItem.hidden = shouldHide; + if (NSMenuItem *attachedItem = cocoaMenu->attachedItem()) { + // Non-nil attached item means the item's submenu is set + attachedItem.title = cocoaMenu->nsMenu().title; + attachedItem.hidden = shouldHide; + } } NSMenuItem *QCocoaMenuBar::nativeItemForMenu(QCocoaMenu *menu) const -- cgit v1.2.3 From aca0e367be9cdc3b48f09200f4eadbcfe5a574c8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 24 Feb 2016 14:28:17 -0800 Subject: Fix the Q_ATOMIC_xxx_IS_www_NATIVE macros with C++11 When I introduced this code in Qt 5.0, I made INT and POINTER be SOMETIMES_NATIVE, but then later I made the specific sizes be ALWAYS_NATIVE. That doesn't make sense. Instead, use the macros from the C++11 header. Note that the member isXxxxNative() functions should not have been constexpr. That's a defect I introduced in Qt 5.0. Task-number: QTBUG-51315 Change-Id: I0c94a5c2846b48c8aea7ffff1436013e8686c153 Reviewed-by: Lars Knoll --- src/corelib/arch/qatomic_cxx11.h | 187 ++++++++++++++++++++++++++++++++------- 1 file changed, 156 insertions(+), 31 deletions(-) diff --git a/src/corelib/arch/qatomic_cxx11.h b/src/corelib/arch/qatomic_cxx11.h index bb49aae4fb..9658aca37c 100644 --- a/src/corelib/arch/qatomic_cxx11.h +++ b/src/corelib/arch/qatomic_cxx11.h @@ -53,44 +53,168 @@ QT_END_NAMESPACE #pragma qt_sync_stop_processing #endif -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE +/* Attempt to detect whether the atomic operations exist in hardware + * or whether they are emulated by way of a lock. + * + * C++11 29.4 [atomics.lockfree] p1 says + * + * The ATOMIC_..._LOCK_FREE macros indicate the lock-free property of the + * corresponding atomic types, with the signed and unsigned variants grouped + * together. The properties also apply to the corresponding (partial) + * specializations of the atomic template. A value of 0 indicates that the + * types are never lock-free. A value of 1 indicates that the types are + * sometimes lock-free. A value of 2 indicates that the types are always + * lock-free. + * + * We have a problem when the value is 1: we'd need to check at runtime, but + * QAtomicInteger requires a constexpr answer (defect introduced in Qt 5.0). So + * we'll err in the side of caution and say it isn't. + */ + +// ### Qt 6: make non-constexpr (see above) +template struct QAtomicTraits +{ static Q_DECL_CONSTEXPR inline bool isLockFree() Q_DECL_NOTHROW; }; #define Q_ATOMIC_INT32_IS_SUPPORTED -#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_INT32_TEST_AND_SET_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_SOMETIMES_NATIVE +#if ATOMIC_INT_LOCK_FREE == 2 +# define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE + +template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<4>::isLockFree() Q_DECL_NOTHROW +{ return true; } +#elif ATOMIC_INT_LOCK_FREE == 1 +# define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT32_TEST_AND_SET_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<4>::isLockFree() Q_DECL_NOTHROW +{ return false; } +#else +# define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NEVER_NATIVE +# define Q_ATOMIC_INT_TEST_AND_SET_IS_NEVER_NATIVE +# define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NEVER_NATIVE +# define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NEVER_NATIVE +# define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_NEVER_NATIVE +# define Q_ATOMIC_INT32_TEST_AND_SET_IS_NEVER_NATIVE +# define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_NEVER_NATIVE +# define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_NEVER_NATIVE + +template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<4>::isLockFree() Q_DECL_NOTHROW +{ return false; } +#endif -#define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE +#if ATOMIC_POINTER_LOCK_FREE == 2 +# define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +# define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE +# define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE +# define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE +#elif ATOMIC_POINTER_LOCK_FREE == 1 +# define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE +#else +# define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_NEVER_NATIVE +# define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NEVER_NATIVE +# define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NEVER_NATIVE +# define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NEVER_NATIVE +#endif template<> struct QAtomicOpsSupport<1> { enum { IsSupported = 1 }; }; -template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; }; -template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; }; - #define Q_ATOMIC_INT8_IS_SUPPORTED -#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE +#if ATOMIC_CHAR_LOCK_FREE == 2 +# define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE + +template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<1>::isLockFree() Q_DECL_NOTHROW +{ return true; } +#elif ATOMIC_CHAR_LOCK_FREE == 1 +# define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT8_TEST_AND_SET_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<1>::isLockFree() Q_DECL_NOTHROW +{ return false; } +#else +# define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_NEVER_NATIVE +# define Q_ATOMIC_INT8_TEST_AND_SET_IS_NEVER_NATIVE +# define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_NEVER_NATIVE +# define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_NEVER_NATIVE +template <> Q_DECL_CONSTEXPR bool QAtomicTraits<1>::isLockFree() Q_DECL_NOTHROW +{ return false; } +#endif + +template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; }; #define Q_ATOMIC_INT16_IS_SUPPORTED -#define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE +#if ATOMIC_SHORT_LOCK_FREE == 2 +# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE + +template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<2>::isLockFree() Q_DECL_NOTHROW +{ return false; } +#elif ATOMIC_SHORT_LOCK_FREE == 1 +# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT16_TEST_AND_SET_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<2>::isLockFree() Q_DECL_NOTHROW +{ return false; } +#else +# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_NEVER_NATIVE +# define Q_ATOMIC_INT16_TEST_AND_SET_IS_NEVER_NATIVE +# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_NEVER_NATIVE +# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_NEVER_NATIVE + +template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<2>::isLockFree() Q_DECL_NOTHROW +{ return false; } +#endif #ifndef QT_NO_STD_ATOMIC64 +template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; }; # define Q_ATOMIC_INT64_IS_SUPPORTED -# define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE -# define Q_ATOMIC_INT64_TEST_AND_SET_IS_ALWAYS_NATIVE -# define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_ALWAYS_NATIVE -# define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE +# if ATOMIC_LLONG_LOCK_FREE == 2 +# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE + +template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<8>::isLockFree() Q_DECL_NOTHROW +{ return true; } +# elif ATOMIC_LLONG_LOCK_FREE == 1 +# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT16_TEST_AND_SET_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<8>::isLockFree() Q_DECL_NOTHROW +{ return false; } +# else +# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_NEVER_NATIVE +# define Q_ATOMIC_INT16_TEST_AND_SET_IS_NEVER_NATIVE +# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_NEVER_NATIVE +# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_NEVER_NATIVE + +template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<8>::isLockFree() Q_DECL_NOTHROW +{ return false; } +# endif #endif template struct QAtomicOps @@ -133,7 +257,7 @@ template struct QAtomicOps _q_value.store(newValue, std::memory_order_release); } - static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return true; } + static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return isTestAndSetNative(); } static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW { return false; } template static inline bool ref(std::atomic &_q_value) @@ -147,7 +271,8 @@ template struct QAtomicOps return --_q_value != 0; } - static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return false; } + static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW + { return QAtomicTraits::isLockFree(); } static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; } template @@ -186,7 +311,7 @@ template struct QAtomicOps return tmp; } - static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return false; } + static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return isTestAndSetNative(); } static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return false; } template @@ -213,7 +338,7 @@ template struct QAtomicOps return _q_value.exchange(newValue, std::memory_order_acq_rel); } - static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return false; } + static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return isTestAndSetNative(); } static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return false; } template static inline -- cgit v1.2.3 From 5d935dca0c70618af519c5bef2e11b4a1ee03507 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 12 Jul 2016 12:44:01 +0200 Subject: Remove (private) QString::expand(), port to (new) QString::resize(int, QChar) We cannot really remove the function, since it's called from inline code (QCharRef::op=(QChar)), but we can schedule it for removal in Qt 6, and inline it into existing in-tree callers. Change-Id: I3499f101dcb5ae908726b3673bf3526a04408db6 Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.cpp | 17 ++++++----------- src/corelib/tools/qstring.h | 4 +++- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 9dc7136d2a..68d12d85af 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1789,17 +1789,12 @@ void QString::reallocData(uint alloc, bool grow) } } +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) void QString::expand(int i) { - int sz = d->size; - resize(qMax(i + 1, sz)); - if (d->size - 1 > sz) { - ushort *n = d->data() + d->size - 1; - ushort *e = d->data() + sz; - while (n != e) - * --n = ' '; - } + resize(qMax(i + 1, d->size), QLatin1Char(' ')); } +#endif /*! \fn void QString::clear() @@ -1986,7 +1981,7 @@ QString &QString::insert(int i, QLatin1String str) int len = str.size(); if (Q_UNLIKELY(i > d->size)) - expand(i + len - 1); + resize(i + len, QLatin1Char(' ')); else resize(d->size + len); @@ -2019,7 +2014,7 @@ QString& QString::insert(int i, const QChar *unicode, int size) } if (Q_UNLIKELY(i > d->size)) - expand(i + size - 1); + resize(i + size, QLatin1Char(' ')); else resize(d->size + size); @@ -2042,7 +2037,7 @@ QString& QString::insert(int i, QChar ch) if (i < 0) return *this; if (Q_UNLIKELY(i > d->size)) - expand(i); + resize(i + 1, QLatin1Char(' ')); else resize(d->size + 1); ::memmove(d->data() + i + 1, d->data() + i, (d->size - i - 1) * sizeof(QChar)); diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 793a859228..3dda382dd5 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -803,7 +803,9 @@ private: Data *d; void reallocData(uint alloc, bool grow = false); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) void expand(int i); +#endif QString multiArg(int numArgs, const QString **args) const; static int compare_helper(const QChar *data1, int length1, const QChar *data2, int length2, @@ -990,7 +992,7 @@ public: inline operator QChar() const { return i < s.d->size ? s.d->data()[i] : 0; } inline QCharRef &operator=(QChar c) - { if (i >= s.d->size) s.expand(i); else s.detach(); + { if (i >= s.d->size) s.resize(i + 1, QLatin1Char(' ')); else s.detach(); s.d->data()[i] = c.unicode(); return *this; } // An operator= for each QChar cast constructors -- cgit v1.2.3 From d7cb2fd44b7801799401dca343014bbf53ad130c Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 8 Jul 2016 14:10:34 +0200 Subject: QMacStyle::styleHint - test pixmap sizes styleHint for SH_FocusFrame_Mask calls drawControl with a painter created for pixmap. We only test pixmapSize.isValid(), but the size (0,0) is also 'isValid', and we end up with a QPainter with an invalid paintEngine (null) crashing in drawControl. Task-number: QTBUG-54630 Change-Id: I84d1785f04ffb3e608812076a6d1bc36ffb92adc Reviewed-by: Gabriel de Dietrich --- src/widgets/styles/qmacstyle_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 18ba2f45f5..3352c5d589 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -2961,7 +2961,7 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w QImage img; QSize pixmapSize = opt->rect.size(); - if (pixmapSize.isValid()) { + if (!pixmapSize.isEmpty()) { QPixmap pix(pixmapSize); pix.fill(QColor(fillR, fillG, fillB)); QPainter pix_paint(&pix); -- cgit v1.2.3 From a372cf5a80ec1a774f8f624b30b3c8209b800ec8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 16 Jun 2016 16:52:08 -0700 Subject: Enable -WX (warnings are errors) for MSVC 2015 Change-Id: Ib57b52598e2f452985e9fffd1458b565f9bda0f8 Reviewed-by: Kai Koehne --- mkspecs/features/qt_common.prf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf index b060ff604e..b367bc12af 100644 --- a/mkspecs/features/qt_common.prf +++ b/mkspecs/features/qt_common.prf @@ -100,9 +100,9 @@ warnings_are_errors:warning_clean { # Work-around for bug https://code.google.com/p/android/issues/detail?id=58135 android: QMAKE_CXXFLAGS_WARN_ON += -Wno-error=literal-suffix } - } else:msvc { - # enable for MSVC 2012, MSVC 2013 - equals(MSVC_VER, "11.0")|equals(MSVC_VER, "12.0"): QMAKE_CXXFLAGS_WARN_ON += -WX + } else:msvc:!intel_icl { + # enable for MSVC 2012, MSVC 2013, MSVC 2015 + contains(MSVC_VER, "1[124].0"): QMAKE_CXXFLAGS_WARN_ON += -WX } unset(ver) } -- cgit v1.2.3 From 5d8a33a86cb6d852716a9c871576b2f9361a61a1 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 8 Jul 2016 15:44:39 +0200 Subject: [iOS] Blacklist iOS with regards to bgra support A number of devices are indicating that there is a problem with using bgra so instead of blacklisting all of them individually it is best to blacklist them all on the iOS platform. This ensures QQuickItem::grabToImage() will work then. Task-number: QTBUG-45902 Change-Id: I900857cfa996924469aaaeeee8037dc84a4fd575 Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglframebufferobject.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index db7de5e8bf..6fc18b1d01 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -1282,6 +1282,7 @@ static inline QImage qt_gl_read_framebuffer_rgba8(const QSize &size, bool includ const char *ver = reinterpret_cast(funcs->glGetString(GL_VERSION)); // Blacklist GPU chipsets that have problems with their BGRA support. +#ifndef Q_OS_IOS const bool blackListed = (qstrcmp(renderer, "PowerVR Rogue G6200") == 0 && ::strstr(ver, "1.3") != 0) || (qstrcmp(renderer, "Mali-T760") == 0 @@ -1289,7 +1290,9 @@ static inline QImage qt_gl_read_framebuffer_rgba8(const QSize &size, bool includ (qstrcmp(renderer, "Mali-T720") == 0 && ::strstr(ver, "3.1") != 0) || qstrcmp(renderer, "PowerVR SGX 554") == 0; - +#else + const bool blackListed = true; +#endif const bool supports_bgra = has_bgra_ext && !blackListed; if (supports_bgra) { -- cgit v1.2.3 From 120ba68882883c58415cb4ee285b0eba4192e76e Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 14 Jul 2016 10:12:11 +0200 Subject: QReadWriteLock fast path for tryLock without timeout When one tries to lock without a timeout, there is no need to allocate a QReadWriteLockPrivate as we will not wait on it. Change-Id: I37c96a7fbc0c66fbdffe372f6089708cb2466fe3 Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/corelib/thread/qreadwritelock.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp index 5665bf74f6..6302a3a515 100644 --- a/src/corelib/thread/qreadwritelock.cpp +++ b/src/corelib/thread/qreadwritelock.cpp @@ -244,6 +244,9 @@ bool QReadWriteLock::tryLockForRead(int timeout) } if (d == dummyLockedForWrite) { + if (!timeout) + return false; + // locked for write, assign a d_ptr and wait. auto val = QReadWriteLockPrivate::allocate(); val->writerCount = 1; @@ -345,6 +348,9 @@ bool QReadWriteLock::tryLockForWrite(int timeout) } if (isUncontendedLocked(d)) { + if (!timeout) + return false; + // locked for either read or write, assign a d_ptr and wait. auto val = QReadWriteLockPrivate::allocate(); if (d == dummyLockedForWrite) -- cgit v1.2.3 From e46e112eb10850801218bd810ecaeb8fd29f4c34 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 8 Jul 2016 13:51:06 +0300 Subject: Optimize string usage Use QStringBuilder more. Use QL1S directly, without QString construction. Change-Id: Iad844391367681fc1013b9725403d009e7c346e6 Reviewed-by: Edward Welbourne --- src/corelib/kernel/qmetaobject.cpp | 2 +- src/gui/text/qtextdocumentfragment.cpp | 2 +- src/gui/text/qtexthtmlparser.cpp | 4 +- src/network/access/qnetworkaccessftpbackend.cpp | 9 +-- src/tools/uic/cpp/cppwriteinitialization.cpp | 78 +++++++++++-------------- src/widgets/widgets/qspinbox.cpp | 5 +- src/widgets/widgets/qwidgettextcontrol.cpp | 4 +- 7 files changed, 45 insertions(+), 59 deletions(-) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 2f2694f219..f4f75e39e6 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1353,7 +1353,7 @@ static inline QByteArray findMethodCandidates(const QMetaObject *metaObject, con for (int i = 0; i < metaObject->methodCount(); ++i) { const QMetaMethod method = metaObject->method(i); if (method.name() == memberByteArray) - candidateMessage.append(" " + method.methodSignature() + '\n'); + candidateMessage += " " + method.methodSignature() + '\n'; } if (!candidateMessage.isEmpty()) { candidateMessage.prepend("\nCandidates are:\n"); diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp index a1a562c839..5727b34e86 100644 --- a/src/gui/text/qtextdocumentfragment.cpp +++ b/src/gui/text/qtextdocumentfragment.cpp @@ -428,7 +428,7 @@ QTextHtmlImporter::QTextHtmlImporter(QTextDocument *_doc, const QString &_html, QString html = _html; const int startFragmentPos = html.indexOf(QLatin1String("")); if (startFragmentPos != -1) { - QString qt3RichTextHeader(QLatin1String("")); + const QLatin1String qt3RichTextHeader(""); // Hack for Qt3 const bool hasQtRichtextMetaTag = html.contains(qt3RichTextHeader); diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 50df8daa5e..7bca50325c 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -1438,9 +1438,7 @@ static void setWidthAttribute(QTextLength *width, const QString &valueStr) #ifndef QT_NO_CSSPARSER void QTextHtmlParserNode::parseStyleAttribute(const QString &value, const QTextDocument *resourceProvider) { - QString css = value; - css.prepend(QLatin1String("* {")); - css.append(QLatin1Char('}')); + const QString css = QLatin1String("* {") + value + QLatin1Char('}'); QCss::Parser parser(css); QCss::StyleSheet sheet; parser.parse(&sheet, Qt::CaseInsensitive); diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp index 153a33f782..d242bdba82 100644 --- a/src/network/access/qnetworkaccessftpbackend.cpp +++ b/src/network/access/qnetworkaccessftpbackend.cpp @@ -306,8 +306,6 @@ void QNetworkAccessFtpBackend::ftpDone() state = CheckingFeatures; if (operation() == QNetworkAccessManager::GetOperation) { // send help command to find out if server supports "SIZE" and "MDTM" - QString command = url().path(); - command.prepend(QLatin1String("%1 ")); helpId = ftp->rawCommand(QLatin1String("HELP")); // get supported commands } else { ftpDone(); @@ -316,14 +314,13 @@ void QNetworkAccessFtpBackend::ftpDone() state = Statting; if (operation() == QNetworkAccessManager::GetOperation) { // logged in successfully, send the stat requests (if supported) - QString command = url().path(); - command.prepend(QLatin1String("%1 ")); + const QString path = url().path(); if (supportsSize) { ftp->rawCommand(QLatin1String("TYPE I")); - sizeId = ftp->rawCommand(command.arg(QLatin1String("SIZE"))); // get size + sizeId = ftp->rawCommand(QLatin1String("SIZE ") + path); // get size } if (supportsMdtm) - mdtmId = ftp->rawCommand(command.arg(QLatin1String("MDTM"))); // get modified time + mdtmId = ftp->rawCommand(QLatin1String("MDTM ") + path); // get modified time if (!supportsSize && !supportsMdtm) ftpDone(); // no commands sent, move to the next state } else { diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index b996aa8e45..f08de35de2 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -1255,14 +1255,14 @@ void WriteInitialization::writeProperties(const QString &varName, QString setFunction; if (stdset) { - setFunction = QLatin1String("->set"); - setFunction += propertyName.left(1).toUpper(); - setFunction += propertyName.mid(1); - setFunction += QLatin1Char('('); + setFunction = QLatin1String("->set") + + propertyName.left(1).toUpper() + + propertyName.midRef(1) + + QLatin1Char('('); } else { - setFunction = QLatin1String("->setProperty(\""); - setFunction += propertyName; - setFunction += QLatin1String("\", QVariant"); + setFunction += QLatin1String("->setProperty(\"") + + propertyName + + QLatin1String("\", QVariant"); if (p->kind() == DomProperty::Enum) setFunction += QLatin1String("::fromValue"); setFunction += QLatin1Char('('); @@ -1286,9 +1286,9 @@ void WriteInitialization::writeProperties(const QString &varName, if (stdset) propertyValue = fixString(p->elementCstring(), m_dindent); else { - propertyValue = QLatin1String("QByteArray("); - propertyValue += fixString(p->elementCstring(), m_dindent); - propertyValue += QLatin1Char(')'); + propertyValue = QLatin1String("QByteArray(") + + fixString(p->elementCstring(), m_dindent) + + QLatin1Char(')'); } } break; @@ -1304,11 +1304,8 @@ void WriteInitialization::writeProperties(const QString &varName, break; case DomProperty::Enum: propertyValue = p->elementEnum(); - if (!propertyValue.contains(QLatin1String("::"))) { - QString scope = className; - scope += QLatin1String("::"); - propertyValue.prepend(scope); - } + if (!propertyValue.contains(QLatin1String("::"))) + propertyValue = className + QLatin1String("::") + propertyValue; break; case DomProperty::Set: propertyValue = p->elementSet(); @@ -1898,31 +1895,29 @@ QString WriteInitialization::pixCall(const QString &t, const QString &text) cons if (m_option.extractImages) { const QString format = image->elementData()->attributeFormat(); const QString extension = format.left(format.indexOf(QLatin1Char('.'))).toLower(); - QString rc = QLatin1String("QPixmap(QString::fromUtf8(\":/"); - rc += m_generatedClass; - rc += QLatin1String("/images/"); - rc += text; - rc += QLatin1Char('.'); - rc += extension; - rc += QLatin1String("\"))"); - return rc; - } - QString rc = WriteIconInitialization::iconFromDataFunction(); - rc += QLatin1Char('('); - rc += text; - rc += QLatin1String("_ID)"); - return rc; + return QLatin1String("QPixmap(QString::fromUtf8(\":/") + + m_generatedClass + + QLatin1String("/images/") + + text + + QLatin1Char('.') + + extension + + QLatin1String("\"))"); + } + return WriteIconInitialization::iconFromDataFunction() + + QLatin1Char('(') + + text + + QLatin1String("_ID)"); } QString pixFunc = m_uic->pixmapFunction(); if (pixFunc.isEmpty()) pixFunc = QLatin1String("QString::fromUtf8"); - type += QLatin1Char('('); - type += pixFunc; - type += QLatin1Char('('); - type += fixString(text, m_dindent); - type += QLatin1String("))"); + type += QLatin1Char('(') + + pixFunc + + QLatin1Char('(') + + fixString(text, m_dindent) + + QLatin1String("))"); return type; } @@ -2316,23 +2311,20 @@ QString WriteInitialization::trCall(const QString &str, const QString &commentHi if (m_option.translateFunction.isEmpty()) { if (m_option.idBased) { - result = QLatin1String("qtTrId("); + result += QLatin1String("qtTrId("); } else { - result = QLatin1String("QApplication::translate(\""); - result += m_generatedClass; - result += QLatin1Char('"'); - result += QLatin1String(", "); + result += QLatin1String("QApplication::translate(\"") + + m_generatedClass + + QLatin1String("\", "); } } else { - result = m_option.translateFunction; - result += QLatin1Char('('); + result += m_option.translateFunction + QLatin1Char('('); } result += fixString(str, m_dindent); if (!m_option.idBased) { - result += QLatin1String(", "); - result += comment; + result += QLatin1String(", ") + comment; } result += QLatin1Char(')'); diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp index a5c096c3a8..0daa624ae8 100644 --- a/src/widgets/widgets/qspinbox.cpp +++ b/src/widgets/widgets/qspinbox.cpp @@ -479,9 +479,8 @@ QString QSpinBox::textFromValue(int value) const QString str; if (d->displayIntegerBase != 10) { - str = QString::number(qAbs(value), d->displayIntegerBase); - if (value < 0) - str.prepend('-'); + const QLatin1String prefix = value < 0 ? QLatin1String("-") : QLatin1String(); + str = prefix + QString::number(qAbs(value), d->displayIntegerBase); } else { str = locale().toString(value); if (!d->showGroupSeparator && (qAbs(value) >= 1000 || value == INT_MIN)) { diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index 77b5a4830b..d5ecb150a8 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -2641,8 +2641,8 @@ void QWidgetTextControl::insertFromMimeData(const QMimeData *source) #ifndef QT_NO_TEXTHTMLPARSER if (source->hasFormat(QLatin1String("application/x-qrichtext")) && d->acceptRichText) { // x-qrichtext is always UTF-8 (taken from Qt3 since we don't use it anymore). - QString richtext = QString::fromUtf8(source->data(QLatin1String("application/x-qrichtext"))); - richtext.prepend(QLatin1String("")); + const QString richtext = QLatin1String("") + + QString::fromUtf8(source->data(QLatin1String("application/x-qrichtext"))); fragment = QTextDocumentFragment::fromHtml(richtext, d->doc); hasData = true; } else if (source->hasHtml() && d->acceptRichText) { -- cgit v1.2.3 From 6bb0bc73c809d1defdcedc31c4c464a129d3de4d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 14 Jul 2016 09:35:50 +0200 Subject: QWindowsTheme: Fix the available file icon sizes Previously, QWindowsTheme had a hardcoded list of of available file icon sizes. As the sizes depend on the Windows display scale factor, this can lead to undesired scaling of icons. Maintain an array of the standard sizes against which the sizes are matched; refresh in display change. Task-number: QTBUG-54561 Change-Id: If36de2f30c8a230cc7bd8eeb4dfc9f201aeda5e4 Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowscontext.cpp | 3 ++ src/plugins/platforms/windows/qwindowstheme.cpp | 49 +++++++++++++++++------ src/plugins/platforms/windows/qwindowstheme.h | 5 +++ 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 39054b6a64..b6118431d3 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -41,6 +41,7 @@ #include "qwindowsmime.h" #include "qwindowsinputcontext.h" #include "qwindowstabletsupport.h" +#include "qwindowstheme.h" #include #ifndef QT_NO_ACCESSIBILITY # include "accessible/qwindowsaccessibility.h" @@ -1007,6 +1008,8 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, #endif case QtWindows::DisplayChangedEvent: return d->m_screenManager.handleDisplayChange(wParam, lParam); + if (QWindowsTheme *t = QWindowsTheme::instance()) + t->displayChanged(); case QtWindows::SettingChangedEvent: return d->m_screenManager.handleScreenChanges(); default: diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index f673ce5c25..ce0c69f9ed 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -329,6 +329,7 @@ QWindowsTheme::QWindowsTheme() std::fill(m_fonts, m_fonts + NFonts, static_cast(0)); std::fill(m_palettes, m_palettes + NPalettes, static_cast(0)); refresh(); + refreshIconPixmapSizes(); } QWindowsTheme::~QWindowsTheme() @@ -394,16 +395,8 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const return QVariant(int(WindowsKeyboardScheme)); case UiEffects: return QVariant(uiEffects()); - case IconPixmapSizes: { - QList sizes; - sizes << 16 << 32; -#ifdef USE_IIMAGELIST - sizes << 48; // sHIL_EXTRALARGE - if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) - sizes << 256; // SHIL_JUMBO -#endif // USE_IIMAGELIST - return QVariant::fromValue(sizes); - } + case IconPixmapSizes: + return m_fileIconSizes; case DialogSnapToDefaultButton: return QVariant(booleanSystemParametersInfo(SPI_GETSNAPTODEFBUTTON, false)); case ContextMenuOnMouseRelease: @@ -473,6 +466,15 @@ void QWindowsTheme::refreshFonts() #endif // !Q_OS_WINCE } +enum FileIconSize { + // Standard icons obtainable via shGetFileInfo(), SHGFI_SMALLICON, SHGFI_LARGEICON + SmallFileIcon, LargeFileIcon, + // Larger icons obtainable via SHGetImageList() + ExtraLargeFileIcon, + JumboFileIcon, // Vista onwards + FileIconSizeCount +}; + bool QWindowsTheme::usePlatformNativeDialog(DialogType type) const { return QWindowsDialogs::useHelper(type); @@ -489,6 +491,27 @@ void QWindowsTheme::windowsThemeChanged(QWindow * window) QWindowSystemInterface::handleThemeChange(window); } +static int fileIconSizes[FileIconSizeCount]; + +void QWindowsTheme::refreshIconPixmapSizes() +{ + // Standard sizes: 16, 32, 48, 256 + fileIconSizes[SmallFileIcon] = GetSystemMetrics(SM_CXSMICON); // corresponds to SHGFI_SMALLICON); + fileIconSizes[LargeFileIcon] = GetSystemMetrics(SM_CXICON); // corresponds to SHGFI_LARGEICON + fileIconSizes[ExtraLargeFileIcon] = + fileIconSizes[LargeFileIcon] + fileIconSizes[LargeFileIcon] / 2; + fileIconSizes[JumboFileIcon] = 8 * fileIconSizes[LargeFileIcon]; // empirical, has not been observed to work + QList sizes; + sizes << fileIconSizes[SmallFileIcon] << fileIconSizes[LargeFileIcon]; +#ifdef USE_IIMAGELIST + sizes << fileIconSizes[ExtraLargeFileIcon]; // sHIL_EXTRALARGE + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) + sizes << fileIconSizes[JumboFileIcon]; // SHIL_JUMBO +#endif // USE_IIMAGELIST + qCDebug(lcQpaWindows) << __FUNCTION__ << sizes; + m_fileIconSizes = QVariant::fromValue(sizes); +} + // Defined in qpixmap_win.cpp Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon); @@ -706,10 +729,12 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s QPixmap pixmap; const QString filePath = QDir::toNativeSeparators(fileInfo.filePath()); const int width = int(size.width()); - const int iconSize = width > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON; + const int iconSize = width > fileIconSizes[SmallFileIcon] ? SHGFI_LARGEICON : SHGFI_SMALLICON; const int requestedImageListSize = #ifdef USE_IIMAGELIST - width > 48 ? sHIL_JUMBO : (width > 32 ? sHIL_EXTRALARGE : 0); + width > fileIconSizes[ExtraLargeFileIcon] + ? sHIL_JUMBO + : (width > fileIconSizes[LargeFileIcon] ? sHIL_EXTRALARGE : 0); #else 0; #endif // !USE_IIMAGELIST diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h index cacde98601..aafcf320aa 100644 --- a/src/plugins/platforms/windows/qwindowstheme.h +++ b/src/plugins/platforms/windows/qwindowstheme.h @@ -37,6 +37,8 @@ #include "qwindowsthreadpoolrunner.h" #include +#include + QT_BEGIN_NAMESPACE class QWindow; @@ -62,6 +64,7 @@ public: QPlatformTheme::IconOptions iconOptions = 0) const Q_DECL_OVERRIDE; void windowsThemeChanged(QWindow *window); + void displayChanged() { refreshIconPixmapSizes(); } static const char *name; @@ -71,11 +74,13 @@ private: void refreshPalettes(); void clearFonts(); void refreshFonts(); + void refreshIconPixmapSizes(); static QWindowsTheme *m_instance; QPalette *m_palettes[NPalettes]; QFont *m_fonts[NFonts]; mutable QWindowsThreadPoolRunner m_threadPoolRunner; + QVariant m_fileIconSizes; }; QT_END_NAMESPACE -- cgit v1.2.3 From 9a00ae8e24a03b25476cc6200bddf4c8fc510733 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 14 Jul 2016 15:00:23 +0200 Subject: Windows QPA: Add warning to setHasBorderInFullScreen() Emit a warning when the function is called before show() as it does not have any effect in that case. Amends change 69839e55c13000ee9bf8d8e9d74b70096a92ae51. Task-number: QTBUG-41309 Change-Id: I7c2bb21735d8e41d525c5e00213b0e278ae5c774 Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowswindow.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 9c6cb53365..e4888d6b87 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2402,9 +2402,10 @@ void QWindowsWindow::aboutToMakeCurrent() void QWindowsWindow::setHasBorderInFullScreenStatic(QWindow *window, bool border) { - if (!window->handle()) - return; - static_cast(window->handle())->setHasBorderInFullScreen(border); + if (QPlatformWindow *handle = window->handle()) + static_cast(handle)->setHasBorderInFullScreen(border); + else + qWarning("%s invoked without window handle; call has no effect.", Q_FUNC_INFO); } void QWindowsWindow::setHasBorderInFullScreen(bool border) -- cgit v1.2.3 From 34de4f6a157ac10a434b719f41a06b4293023b29 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 7 Jul 2016 12:08:31 +0200 Subject: moc: Fix a crash with malformed input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not increment 'data' past the buffer in case of invalid token. Remove the left over qDebug so we can make a test. Task-number: QTBUG-54609 Change-Id: I8f0dd3381fbdea3f07d3c05c9a44a16d92538117 Reviewed-by: Jędrzej Nowacki --- src/tools/moc/preprocessor.cpp | 8 ++++---- tests/auto/tools/moc/tst_moc.cpp | 9 ++++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index bfe61d0895..2b04b678fa 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -188,7 +188,8 @@ Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocesso token = keywords[state].ident; if (token == NOTOKEN) { - ++data; + if (*data) + ++data; // an error really, but let's ignore this input // to not confuse moc later. However in pre-processor // only mode let's continue. @@ -361,7 +362,6 @@ Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocesso ++data; continue; } - int nextindex = pp_keywords[state].next; int next = 0; if (*data == pp_keywords[state].defchar) @@ -380,7 +380,8 @@ Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocesso switch (token) { case NOTOKEN: - ++data; + if (*data) + ++data; break; case PP_DEFINE: mode = PrepareDefine; @@ -1251,7 +1252,6 @@ void Preprocessor::parseDefineArguments(Macro *m) error("missing ')' in macro argument list"); break; } else if (!is_identifier(l.constData(), l.length())) { - qDebug() << l; error("Unexpected character in macro argument list."); } } diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index b3f9a9f85f..9d2b883112 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -1935,6 +1935,13 @@ void tst_Moc::warnings_data() << 1 << QString("IGNORE_ALL_STDOUT") << QString(":2: Error: Macro invoked with too few parameters for a use of '#'"); + + QTest::newRow("QTBUG-54609: crash on invalid input") + << QByteArray::fromBase64("EAkJCQkJbGFzcyBjbGFzcyBiYWkcV2kgTUEKcGYjZGVmaW5lIE1BKFEs/4D/FoQ=") + << QStringList() + << 1 + << QString("IGNORE_ALL_STDOUT") + << QString(":-1: Error: Unexpected character in macro argument list."); } void tst_Moc::warnings() @@ -1950,7 +1957,7 @@ void tst_Moc::warnings() #ifdef Q_CC_MSVC // for some reasons, moc compiled with MSVC uses a different output format - QRegExp lineNumberRe(":(\\d+):"); + QRegExp lineNumberRe(":(-?\\d+):"); lineNumberRe.setMinimal(true); expectedStdErr.replace(lineNumberRe, "(\\1):"); #endif -- cgit v1.2.3 From 89765ced6e9ce7e20aa1090439869509f86a070a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 14 Jul 2016 16:19:42 +0200 Subject: Windows: Add a workaround for render-to-texture widgets for translucent windows Do not attempt to switch from translucent GL windows (emulated by DWM blur behind) to translucent raster windows (using layered windows) as this produces warnings from UpdateLayeredWindowIndirect() failing. Task-number: QTBUG-54734 Change-Id: Ie05126c5cb091a00f17b88a74b287c90aa2dfebd Reviewed-by: Joni Poikelin Reviewed-by: Laszlo Agocs --- src/widgets/kernel/qwidgetbackingstore.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 7473dd1dfb..3f62e7913f 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1018,9 +1018,11 @@ static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget) // The Windows compositor handles fullscreen OpenGL window specially. Besides // having trouble with popups, it also has issues with flip-flopping between // OpenGL-based and normal flushing. Therefore, stick with GL for fullscreen -// windows. (QTBUG-53515) +// windows (QTBUG-53515). Similary, translucent windows should not switch to +// layered native windows (QTBUG-54734). #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE) || tlw->windowState().testFlag(Qt::WindowFullScreen) + || tlw->testAttribute(Qt::WA_TranslucentBackground) #endif ) { -- cgit v1.2.3 From 178ab885626bcd67507fde7f67f65c1872ac3be3 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 19 May 2016 18:06:59 +0200 Subject: PathStrokeRenderer::initializePoints(): use float division The (example) code used a real to hold 360 / 7, which is of course 51, discarding the 3/7 that was most likely meant to be kept. Noticed by Coverity (CID 22364). Use 360.0 instead of 360 to get more accurate results. Change-Id: Ifdfbb932589d8ea728710e8b656af651c9f8a7d2 Reviewed-by: Marc Mutz --- examples/widgets/painting/pathstroke/pathstroke.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/widgets/painting/pathstroke/pathstroke.cpp b/examples/widgets/painting/pathstroke/pathstroke.cpp index d93dcfe386..db3c6f946b 100644 --- a/examples/widgets/painting/pathstroke/pathstroke.cpp +++ b/examples/widgets/painting/pathstroke/pathstroke.cpp @@ -477,7 +477,7 @@ void PathStrokeRenderer::initializePoints() m_vectors.clear(); QMatrix m; - qreal rot = 360 / count; + qreal rot = 360.0 / count; QPointF center(width() / 2, height() / 2); QMatrix vm; vm.shear(2, -1); -- cgit v1.2.3 From 337a7e96b62a2c05e9470f93f7f46dce7b75691f Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 8 Jul 2016 13:21:20 +0300 Subject: QStandardItem: use reserve() to optimize memory allocation Change-Id: I09df41f6beaaeecc818f11a01206e9e4583fd93f Reviewed-by: Marc Mutz --- src/gui/itemmodels/qstandarditemmodel.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp index 3861eb8b40..7b8d8ae2b7 100644 --- a/src/gui/itemmodels/qstandarditemmodel.cpp +++ b/src/gui/itemmodels/qstandarditemmodel.cpp @@ -1844,7 +1844,9 @@ QList QStandardItem::takeColumn(int column) d->model->d_func()->columnsAboutToBeRemoved(this, column, column); QList items; - for (int row = d->rowCount() - 1; row >= 0; --row) { + const int rowCount = d->rowCount(); + items.reserve(rowCount); + for (int row = rowCount - 1; row >= 0; --row) { int index = d->childIndex(row, column); QStandardItem *ch = d->children.at(index); if (ch) -- cgit v1.2.3 From 13c198cedb169327d5fe8152b0e8d762c0ae1278 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 18 Jul 2016 08:34:35 +0200 Subject: Doc: Fix snippet to use initializer list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can expect C++11 now, and using an initializer list is much shorter. Change-Id: I6424d24ce7660b342a629e836b94d62c8868a44d Reviewed-by: Jędrzej Nowacki --- src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp index 576aea1cf5..ca1ea21b02 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp @@ -147,10 +147,7 @@ QVariant data = QVariant::fromValue(object); //! [9] -QList intList; -intList.push_back(7); -intList.push_back(11); -intList.push_back(42); +QList intList = {7, 11, 42}; QVariant variant = QVariant::fromValue(intList); if (variant.canConvert()) { -- cgit v1.2.3 From b75fe73700bae85af4de3e4159a16276b844557b Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 15 Jul 2016 11:41:08 +0300 Subject: QStandardItem: enable NRVO for gcc Change-Id: I5a5ad039e1df8f040b77ff783a4f0e1213a0f286 Reviewed-by: Marc Mutz --- src/gui/itemmodels/qstandarditemmodel.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp index 7b8d8ae2b7..5c04510af1 100644 --- a/src/gui/itemmodels/qstandarditemmodel.cpp +++ b/src/gui/itemmodels/qstandarditemmodel.cpp @@ -1805,11 +1805,12 @@ QStandardItem *QStandardItem::takeChild(int row, int column) QList QStandardItem::takeRow(int row) { Q_D(QStandardItem); + QList items; if ((row < 0) || (row >= rowCount())) - return QList(); + return items; if (d->model) d->model->d_func()->rowsAboutToBeRemoved(this, row, row); - QList items; + int index = d->childIndex(row, 0); // Will return -1 if there are no columns if (index != -1) { int col_count = d->columnCount(); @@ -1838,11 +1839,11 @@ QList QStandardItem::takeRow(int row) QList QStandardItem::takeColumn(int column) { Q_D(QStandardItem); + QList items; if ((column < 0) || (column >= columnCount())) - return QList(); + return items; if (d->model) d->model->d_func()->columnsAboutToBeRemoved(this, column, column); - QList items; const int rowCount = d->rowCount(); items.reserve(rowCount); -- cgit v1.2.3 From 267c01390544ba12f81783c8b0e37ed38db231d6 Mon Sep 17 00:00:00 2001 From: Michael Sheldon Date: Thu, 26 May 2016 16:20:33 +0100 Subject: Preserve the scale of fonts when caching the font engine Associates the scalableBitmapFactor with the freetype QFontEngine so that it is preserved when caching the engine Task-number: QTBUG-53652 Change-Id: I010f9d235ccf30679b112e0c05e01bc247a3693f Reviewed-by: jian liang Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontengine_ft.cpp | 36 ++++++++++++++++++------------------ src/gui/text/qfontengine_ft_p.h | 4 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index e89522f5af..26ed81a091 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -259,7 +259,6 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id, newFreetype->ref.store(1); newFreetype->xsize = 0; newFreetype->ysize = 0; - newFreetype->scalableBitmapScaleFactor = 1; newFreetype->matrix.xx = 0x10000; newFreetype->matrix.yy = 0x10000; newFreetype->matrix.xy = 0; @@ -335,10 +334,11 @@ void QFreetypeFace::release(const QFontEngine::FaceId &face_id) } -void QFreetypeFace::computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing) +void QFreetypeFace::computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing, QFixed *scalableBitmapScaleFactor) { *ysize = qRound(fontDef.pixelSize * 64); *xsize = *ysize * fontDef.stretch / 100; + *scalableBitmapScaleFactor = 1; *outline_drawing = false; if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) { @@ -376,7 +376,7 @@ void QFreetypeFace::computeSize(const QFontDef &fontDef, int *xsize, int *ysize, // to make sure we can select the desired bitmap strike index if (FT_Select_Size(face, best) == 0) { if (isScalableBitmap()) - scalableBitmapScaleFactor = QFixed::fromReal((qreal)fontDef.pixelSize / face->available_sizes[best].height); + *scalableBitmapScaleFactor = QFixed::fromReal((qreal)fontDef.pixelSize / face->available_sizes[best].height); *xsize = face->available_sizes[best].x_ppem; *ysize = face->available_sizes[best].y_ppem; } else { @@ -729,7 +729,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, symbol = bool(fontDef.family.contains(QLatin1String("symbol"), Qt::CaseInsensitive)); } - freetype->computeSize(fontDef, &xsize, &ysize, &defaultGlyphSet.outline_drawing); + freetype->computeSize(fontDef, &xsize, &ysize, &defaultGlyphSet.outline_drawing, &scalableBitmapScaleFactor); FT_Face face = lockFace(); @@ -1294,24 +1294,24 @@ int QFontEngineFT::synthesized() const QFixed QFontEngineFT::ascent() const { QFixed v = QFixed::fromFixed(metrics.ascender); - if (freetype->scalableBitmapScaleFactor != 1) - v *= freetype->scalableBitmapScaleFactor; + if (scalableBitmapScaleFactor != 1) + v *= scalableBitmapScaleFactor; return v; } QFixed QFontEngineFT::descent() const { QFixed v = QFixed::fromFixed(-metrics.descender); - if (freetype->scalableBitmapScaleFactor != 1) - v *= freetype->scalableBitmapScaleFactor; + if (scalableBitmapScaleFactor != 1) + v *= scalableBitmapScaleFactor; return v; } QFixed QFontEngineFT::leading() const { QFixed v = QFixed::fromFixed(metrics.height - metrics.ascender + metrics.descender); - if (freetype->scalableBitmapScaleFactor != 1) - v *= freetype->scalableBitmapScaleFactor; + if (scalableBitmapScaleFactor != 1) + v *= scalableBitmapScaleFactor; return v; } @@ -1326,7 +1326,7 @@ QFixed QFontEngineFT::xHeight() const return answer; } } else { - return QFixed(freetype->face->size->metrics.y_ppem) * freetype->scalableBitmapScaleFactor; + return QFixed(freetype->face->size->metrics.y_ppem) * scalableBitmapScaleFactor; } return QFontEngine::xHeight(); } @@ -1352,8 +1352,8 @@ QFixed QFontEngineFT::averageCharWidth() const qreal QFontEngineFT::maxCharWidth() const { QFixed max_advance = QFixed::fromFixed(metrics.max_advance); - if (freetype->scalableBitmapScaleFactor != 1) - max_advance *= freetype->scalableBitmapScaleFactor; + if (scalableBitmapScaleFactor != 1) + max_advance *= scalableBitmapScaleFactor; return max_advance.toReal(); } @@ -1639,7 +1639,7 @@ bool QFontEngineFT::shouldUseDesignMetrics(QFontEngine::ShaperFlags flags) const QFixed QFontEngineFT::scaledBitmapMetrics(QFixed m) const { - return m * freetype->scalableBitmapScaleFactor; + return m * scalableBitmapScaleFactor; } glyph_metrics_t QFontEngineFT::scaledBitmapMetrics(const glyph_metrics_t &m) const @@ -1677,8 +1677,8 @@ void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlag delete g; } - if (freetype->scalableBitmapScaleFactor != 1) - glyphs->advances[i] *= freetype->scalableBitmapScaleFactor; + if (scalableBitmapScaleFactor != 1) + glyphs->advances[i] *= scalableBitmapScaleFactor; } if (face) unlockFace(); @@ -1981,9 +1981,9 @@ QImage QFontEngineFT::bitmapForGlyph(glyph_t g, QFixed subPixelPosition, const Q else if (defaultFormat == GlyphFormat::Format_Mono) img = QImage(glyph->data, glyph->width, glyph->height, QImage::Format_Mono).copy(); - if (!img.isNull() && (!t.isIdentity() || freetype->scalableBitmapScaleFactor != 1)) { + if (!img.isNull() && (!t.isIdentity() || scalableBitmapScaleFactor != 1)) { QTransform trans(t); - const qreal scaleFactor = freetype->scalableBitmapScaleFactor.toReal(); + const qreal scaleFactor = scalableBitmapScaleFactor.toReal(); trans.scale(scaleFactor, scaleFactor); img = img.transformed(trans, Qt::SmoothTransformation); } diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 3f4bf84753..3cdf0cda47 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -75,7 +75,7 @@ class QFontconfigDatabase; class QFreetypeFace { public: - void computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing); + void computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing, QFixed *scalableBitmapScaleFactor); QFontEngine::Properties properties() const; bool getSfntTable(uint tag, uchar *buffer, uint *length) const; @@ -96,7 +96,6 @@ public: FT_Face face; int xsize; // 26.6 int ysize; // 26.6 - QFixed scalableBitmapScaleFactor; FT_Matrix matrix; FT_CharMap unicode_map; FT_CharMap symbol_map; @@ -340,6 +339,7 @@ private: FT_Size_Metrics metrics; mutable bool kerning_pairs_loaded; + QFixed scalableBitmapScaleFactor; }; inline uint qHash(const QFontEngineFT::GlyphAndSubPixelPosition &g) -- cgit v1.2.3 From 62cbb434579a56871f0917bc306d592055381c00 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 19 Jul 2016 08:48:40 +0200 Subject: Fix typo in doc snippets of qOverload and related Task-number: QTBUG-54808 Change-Id: Ic565710e4d3a95abf98d4696ae7c0001a9171697 Reviewed-by: Marc Mutz --- src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp index a022187c21..54b5c95a34 100644 --- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp @@ -583,13 +583,13 @@ template<> class QTypeInfo : public QTypeInfoMerger {}; void overloadedFunction(); void overloadedFunction(int, QString); }; - ... qOverload<>(&Foo:overloadedFunction) - ... qOverload(&Foo:overloadedFunction) + ... qOverload<>(&Foo::overloadedFunction) + ... qOverload(&Foo::overloadedFunction) //! [52] //! [53] - ... QOverload<>::of(&Foo:overloadedFunction) - ... QOverload::of(&Foo:overloadedFunction) + ... QOverload<>::of(&Foo::overloadedFunction) + ... QOverload::of(&Foo::overloadedFunction) //! [53] //! [54] @@ -597,8 +597,8 @@ template<> class QTypeInfo : public QTypeInfoMerger {}; void overloadedFunction(int, QString); void overloadedFunction(int, QString) const; }; - ... qConstOverload<>(&Foo:overloadedFunction) - ... qNonConstOverload(&Foo:overloadedFunction) + ... qConstOverload<>(&Foo::overloadedFunction) + ... qNonConstOverload(&Foo::overloadedFunction) //! [54] //! [qlikely] -- cgit v1.2.3